From fe30ea583d6510a7f017aab46c2cfa62425e4d85 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 19 Jul 2022 19:52:34 +0300 Subject: [PATCH 001/225] feeds: use forked bitthief/nss-packages Signed-off-by: bitthief --- feeds.conf.default | 1 + 1 file changed, 1 insertion(+) diff --git a/feeds.conf.default b/feeds.conf.default index fc679335e0e47f..e0bad42753507c 100644 --- a/feeds.conf.default +++ b/feeds.conf.default @@ -2,6 +2,7 @@ src-git packages https://git.openwrt.org/feed/packages.git src-git luci https://git.openwrt.org/project/luci.git src-git routing https://git.openwrt.org/feed/routing.git src-git telephony https://git.openwrt.org/feed/telephony.git +src-git nss_packages https://github.com/bitthief/nss-packages.git #src-git video https://github.com/openwrt/video.git #src-git targets https://github.com/openwrt/targets.git #src-git oldpackages http://git.openwrt.org/packages.git From 06c92866be5475958c29a768e7ecfa08a7ac637a Mon Sep 17 00:00:00 2001 From: bitthief Date: Sun, 10 Jul 2022 08:05:39 +0300 Subject: [PATCH 002/225] kernel: add ASN1 encoder module to keys-trusted The ASN1 encoder module is required on kernel 5.15, fixes build issues. Signed-off-by: bitthief --- package/kernel/linux/modules/other.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package/kernel/linux/modules/other.mk b/package/kernel/linux/modules/other.mk index face5794727736..5b9fcd9bc46cc3 100644 --- a/package/kernel/linux/modules/other.mk +++ b/package/kernel/linux/modules/other.mk @@ -1266,7 +1266,8 @@ $(eval $(call KernelPackage,keys-encrypted)) define KernelPackage/keys-trusted SUBMENU:=$(OTHER_MENU) TITLE:=TPM trusted keys on kernel keyring - DEPENDS:=@KERNEL_KEYS +kmod-crypto-hash +kmod-crypto-hmac +kmod-crypto-sha1 +kmod-tpm + DEPENDS:=@KERNEL_KEYS +(LINUX_5_15):kmod-asn1-encoder +kmod-crypto-hash \ + +kmod-crypto-hmac +kmod-crypto-sha1 +kmod-tpm KCONFIG:=CONFIG_TRUSTED_KEYS FILES:= $(LINUX_DIR)/security/keys/trusted-keys/trusted.ko AUTOLOAD:=$(call AutoLoad,01,trusted-keys,1) From 437275f9e67c55be9e395ae3b0cb4bb8ce37e14f Mon Sep 17 00:00:00 2001 From: bitthief Date: Sun, 21 Aug 2022 10:10:28 +0300 Subject: [PATCH 003/225] mac80211: fix parameter reading of tweak for tx bursting when using VHT Reference: https: //github.com/openwrt/openwrt/pull/10395 Signed-off-by: bitthief --- package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh index 1bf4db6e5f0554..96dbf4b11caef1 100644 --- a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh +++ b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh @@ -138,8 +138,9 @@ mac80211_hostapd_setup_base() { [ -n "$acs_exclude_dfs" ] && [ "$acs_exclude_dfs" -gt 0 ] && append base_cfg "acs_exclude_dfs=1" "$N" - json_get_vars noscan ht_coex min_tx_power:0 tx_burst + json_get_vars noscan ht_coex min_tx_power:0 json_get_values ht_capab_list ht_capab + json_get_vars tx_burst json_get_values channel_list channels [ "$auto_channel" = 0 ] && [ -z "$channel_list" ] && \ From f576509f12ecd49ced1e04888eee4520ecec08e8 Mon Sep 17 00:00:00 2001 From: bitthief Date: Fri, 5 Aug 2022 15:39:09 +0300 Subject: [PATCH 004/225] dnsmasq: honor IPv6 address MAC assign Signed-off-by: bitthief --- ...igning-IPv6-address-based-on-MAC-add.patch | 166 ++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 package/network/services/dnsmasq/patches/300-DHCPv6-Honor-assigning-IPv6-address-based-on-MAC-add.patch diff --git a/package/network/services/dnsmasq/patches/300-DHCPv6-Honor-assigning-IPv6-address-based-on-MAC-add.patch b/package/network/services/dnsmasq/patches/300-DHCPv6-Honor-assigning-IPv6-address-based-on-MAC-add.patch new file mode 100644 index 00000000000000..4dd7e22b34a7c4 --- /dev/null +++ b/package/network/services/dnsmasq/patches/300-DHCPv6-Honor-assigning-IPv6-address-based-on-MAC-add.patch @@ -0,0 +1,166 @@ +From 93ac8f9d469ff08d41170eb6934842b3626d5fdd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= +Date: Wed, 23 Dec 2015 22:10:44 +0100 +Subject: [PATCH] DHCPv6: Honor assigning IPv6 address based on MAC address + +Currently IPv6 addresses are assigned to tuple (IAID, DUID). When system +changes IAID/DUID then old assigned IPv6 address cannot be reused, even +when in config file was DHCPv6 assignment based on MAC address (and not on +DUID). + +IAID/DUID is changed when rebooting from one operating system to another; +or after reinstalling system. In reality it is normal that DUID of some +machine is changed, so people rather assign also IPv6 addresses based on +MAC address. + +So assigning IPv6 based on MAC address in dnsmasq is currently semi-broken. + +This patch tries to fix it and honors IPv6 config rules with MAC address, +to always assign particular IPv6 address to specific MAC address (when +configured). And ignores the fact if IAID/DUID was changed. + +Normally IPv6 address should be assigned by IAID/DUID (which also state +DHCPv6 RFCs), but dnsmasq has already some support for assigning IPv6 +address based on MAC address, when users configured in config file. + +So this patch just tries to fix above problem for user configuration with +MAC addresses. It does not change assignment based on DUID. +--- + src/rfc3315.c | 55 +++++++++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 47 insertions(+), 8 deletions(-) + +--- a/src/rfc3315.c ++++ b/src/rfc3315.c +@@ -48,7 +48,7 @@ static int build_ia(struct state *state, + static void end_ia(int t1cntr, unsigned int min_time, int do_fuzz); + static void mark_context_used(struct state *state, struct in6_addr *addr); + static void mark_config_used(struct dhcp_context *context, struct in6_addr *addr); +-static int check_address(struct state *state, struct in6_addr *addr); ++static int check_address(struct state *state, struct dhcp_config *config, struct in6_addr *addr); + static int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr, struct state *state, time_t now); + static struct addrlist *config_implies(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr); + static void add_address(struct state *state, struct dhcp_context *context, unsigned int lease_time, void *ia_option, +@@ -688,8 +688,13 @@ static int dhcp6_no_relay(struct state * + } + else if (!(c = address6_available(state->context, &req_addr, solicit_tags, plain_range))) + continue; /* not an address we're allowed */ +- else if (!check_address(state, &req_addr)) ++ else if (!check_address(state, config, &req_addr)) + continue; /* address leased elsewhere */ ++ else if (state->mac_len && config && ++ config_has_mac(config, state->mac, state->mac_len, state->mac_type) && ++ match_netid(c->filter, solicit_tags, plain_range) && ++ !config_implies(config, c, &req_addr)) ++ continue; /* another static address is configured */ + + /* add address to output packet */ + add_address(state, c, lease_time, ia_option, &min_time, &req_addr, now); +@@ -701,7 +706,10 @@ static int dhcp6_no_relay(struct state * + + /* Suggest configured address(es) */ + for (c = state->context; c; c = c->current) +- if (!(c->flags & CONTEXT_CONF_USED) && ++ if ((!(c->flags & CONTEXT_CONF_USED) || ++ (state->mac_len && config && ++ config_has_mac(config, state->mac, state->mac_len, state->mac_type) ++ )) && + match_netid(c->filter, solicit_tags, plain_range) && + config_valid(config, c, &addr, state, now)) + { +@@ -725,6 +733,11 @@ static int dhcp6_no_relay(struct state * + req_addr = ltmp->addr6; + if ((c = address6_available(state->context, &req_addr, solicit_tags, plain_range))) + { ++ if (state->mac_len && config && ++ config_has_mac(config, state->mac, state->mac_len, state->mac_type) && ++ match_netid(c->filter, solicit_tags, plain_range) && ++ !config_implies(config, c, &req_addr)) ++ continue; /* skip this lease because another static address is configured */ + add_address(state, c, c->lease_time, NULL, &min_time, &req_addr, now); + mark_context_used(state, &req_addr); + get_context_tag(state, c); +@@ -859,7 +872,7 @@ static int dhcp6_no_relay(struct state * + put_opt6_string(_("address unavailable")); + end_opt6(o1); + } +- else if (!check_address(state, &req_addr)) ++ else if (!check_address(state, config, &req_addr)) + { + /* Address leased to another DUID/IAID */ + o1 = new_opt6(OPTION6_STATUS_CODE); +@@ -989,6 +1002,16 @@ static int dhcp6_no_relay(struct state * + { + unsigned int lease_time; + ++ /* check if another static address is preferred */ ++ if (state->mac_len && config && ++ config_has_mac(config, state->mac, state->mac_len, state->mac_type) && ++ !config_implies(config, this_context, &req_addr)) ++ { ++ preferred_time = valid_time = 0; ++ message = _("deprecated"); ++ } ++ else ++ { + get_context_tag(state, this_context); + + if (config_implies(config, this_context, &req_addr) && have_config(config, CONFIG_TIME)) +@@ -1014,6 +1037,7 @@ static int dhcp6_no_relay(struct state * + + if (preferred_time == 0) + message = _("deprecated"); ++ } + + address_assigned = 1; + } +@@ -1070,11 +1094,22 @@ static int dhcp6_no_relay(struct state * + ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24)) + { + struct in6_addr req_addr; ++ struct dhcp_context *c; ++ int config_addr_ok = 1; + + /* alignment */ + memcpy(&req_addr, opt6_ptr(ia_option, 0), IN6ADDRSZ); ++ ++ c = address6_valid(state->context, &req_addr, tagif, 1); ++ ++ if (c && state->mac_len && config && ++ config_has_mac(config, state->mac, state->mac_len, state->mac_type) && ++ !config_implies(config, c, &req_addr)) ++ { ++ config_addr_ok = 0; ++ } + +- if (!address6_valid(state->context, &req_addr, tagif, 1)) ++ if (!c || !config_addr_ok) + { + o1 = new_opt6(OPTION6_STATUS_CODE); + put_opt6_short(DHCP6NOTONLINK); +@@ -1692,11 +1727,15 @@ static void mark_config_used(struct dhcp + context->flags |= CONTEXT_CONF_USED; + } + +-/* make sure address not leased to another CLID/IAID */ +-static int check_address(struct state *state, struct in6_addr *addr) ++/* check that ipv6 address belongs to config with same mac address as in state or ipv6 address is not leased to another CLID/IAID */ ++static int check_address(struct state *state, struct dhcp_config *config, struct in6_addr *addr) + { + struct dhcp_lease *lease; + ++ if (state->mac_len && config && ++ config_has_mac(config, state->mac, state->mac_len, state->mac_type)) ++ return 1; ++ + if (!(lease = lease6_find_by_addr(addr, 128, 0))) + return 1; + +@@ -1773,7 +1812,7 @@ static int config_valid(struct dhcp_conf + { + setaddr6part(addr, addrpart+i); + +- if (check_address(state, addr)) ++ if (check_address(state, config, addr)) + return 1; + } + } From 443f8ef61cce2af0a9d7468b475005ad0a50db6b Mon Sep 17 00:00:00 2001 From: bitthief Date: Sun, 21 Aug 2022 10:21:32 +0300 Subject: [PATCH 005/225] dnsmasq: fix resolv.conf for round-robin DNS configuration Reference: https: //github.com/openwrt/openwrt/pull/10279 Signed-off-by: bitthief --- package/network/services/dnsmasq/files/dnsmasq.init | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/package/network/services/dnsmasq/files/dnsmasq.init b/package/network/services/dnsmasq/files/dnsmasq.init index 0c769602366c29..a1fb0aada76471 100755 --- a/package/network/services/dnsmasq/files/dnsmasq.init +++ b/package/network/services/dnsmasq/files/dnsmasq.init @@ -8,6 +8,8 @@ PROG=/usr/sbin/dnsmasq ADD_LOCAL_DOMAIN=1 ADD_LOCAL_HOSTNAME=1 +ADD_LOCAL_IPV4_NAMESERVER=1 +ADD_LOCAL_IPV6_NAMESERVER=0 ADD_WAN_FQDN=0 ADD_LOCAL_FQDN="" @@ -1036,6 +1038,8 @@ dnsmasq_start() config_get_bool ADD_LOCAL_DOMAIN "$cfg" add_local_domain 1 config_get_bool ADD_LOCAL_HOSTNAME "$cfg" add_local_hostname 1 + config_get_bool ADD_LOCAL_IPV4_NAMESERVER "$cfg" add_local_ipv4_nameserver 1 + config_get_bool ADD_LOCAL_IPV6_NAMESERVER "$cfg" add_local_ipv6_nameserver 0 config_get ADD_LOCAL_FQDN "$cfg" add_local_fqdn "" config_get ADD_WAN_FQDN "$cfg" add_wan_fqdn 0 @@ -1192,8 +1196,12 @@ dnsmasq_start() [ $ADD_LOCAL_DOMAIN -eq 1 ] && [ -n "$DOMAIN" ] && { echo "search $DOMAIN" >> /tmp/resolv.conf } - DNS_SERVERS="$DNS_SERVERS 127.0.0.1" - [ -e /proc/sys/net/ipv6 ] && DNS_SERVERS="$DNS_SERVERS ::1" + [ "$ADD_LOCAL_IPV4_NAMESERVER" -eq 1 ] && { + DNS_SERVERS="$DNS_SERVERS 127.0.0.1" + } + [ -e /proc/sys/net/ipv6 ] && [ "$ADD_LOCAL_IPV6_NAMESERVER" -eq 1 ] && { + DNS_SERVERS="$DNS_SERVERS ::1" + } for DNS_SERVER in $DNS_SERVERS ; do echo "nameserver $DNS_SERVER" >> /tmp/resolv.conf done From 774273bdff846aa7af24a7fe96d53b367338acde Mon Sep 17 00:00:00 2001 From: bitthief Date: Wed, 16 Nov 2022 21:15:08 +0200 Subject: [PATCH 006/225] dropbear: disable three weak kex/mac algorithms ssh-rsa (2048-bit), hmac-sha1, and diffie-hellman-group14-sha1 are weak algorithms. In the case of sha-rsa (2048-bit), a future deprecation notice has been issued.[1] It has no place in a potentially internet-facing daemon like dropbear. Upstream has acknowledged this and offered this solution to disable these three until this is made to be the default in the next release of dropbear next year.[2] This PR disables these three at build time until then. 1. https://www.openssh.com/txt/release-8.2 2. https://github.com/mkj/dropbear/issues/138 Build system: x86_64 Build-tested: bcm2711/RPi4B Run-tested: bcm2711/RPi4B Signed-off-by: John Audia Signed-off-by: bitthief --- package/network/services/dropbear/Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package/network/services/dropbear/Makefile b/package/network/services/dropbear/Makefile index e98e995ba7b9a3..ba463c86a2ec9a 100644 --- a/package/network/services/dropbear/Makefile +++ b/package/network/services/dropbear/Makefile @@ -116,6 +116,9 @@ DB_OPT_COMMON = \ DROPBEAR_CLI_NETCAT|0 \ DROPBEAR_DSS|0 \ DO_MOTD|0 \ + DROPBEAR_RSA_SHA1|0 \ + DROPBEAR_DH_GROUP14_SHA1|0 \ + DROPBEAR_SHA1_HMAC|0 \ ############################################################################## From 88300a910403e0e958debd06eb22431d8b376b1b Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 01:32:53 +0300 Subject: [PATCH 007/225] qualcommax: ipq807x: refactor packet steering init Replace a standalone init.d script with a platform implementation as supported by netifd. This avoids a race between netifd and target specific setups. Signed-off-by: bitthief --- .../usr/libexec/platform/packet-steering.sh | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100755 target/linux/qualcommax/ipq807x/base-files/usr/libexec/platform/packet-steering.sh diff --git a/target/linux/qualcommax/ipq807x/base-files/usr/libexec/platform/packet-steering.sh b/target/linux/qualcommax/ipq807x/base-files/usr/libexec/platform/packet-steering.sh new file mode 100755 index 00000000000000..77e49c1cfadeb3 --- /dev/null +++ b/target/linux/qualcommax/ipq807x/base-files/usr/libexec/platform/packet-steering.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +packet_steering="$(uci -q get network.@globals[0].packet_steering)" +flow_offloading="$(uci -q get firewall.@defaults[0].flow_offloading)" +flow_offloading_hw="$(uci -q get firewall.@defaults[0].flow_offloading_hw)" + +[ "$packet_steering" = 1 ] && { + if [ ${flow_offloading_hw:-0} -gt 0 ]; then + # HW offloading + # Not implemented + : + elif [ ${flow_offloading:-0} -gt 0 ]; then + # SW offloading + : + else + # Default + # LAN + for q in $(ls /sys/class/net/lan*/queues/rx-*/rps_cpus); do echo f > $q; done + for q in $(ls /sys/class/net/lan*/queues/tx-*/xps_cpus); do echo f > $q; done + for q in $(ls /sys/class/net/lan*/queues/rx-*/rps_flow_cnt); do echo 4096 > $q; done + # WAN + for q in $(ls /sys/class/net/wan/queues/rx-*/rps_cpus); do echo f > $q; done + for q in $(ls /sys/class/net/wan/queues/tx-*/xps_cpus); do echo f > $q; done + for q in $(ls /sys/class/net/wan/queues/rx-*/rps_flow_cnt); do echo 4096 > $q; done + + echo 32768 > /proc/sys/net/core/rps_sock_flow_entries + fi +} + +# Enable threaded network backlog processing +echo 1 > /proc/sys/net/core/backlog_threaded From 757e9f80a84a305dcfd5e94c5e012433d3025f73 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 01:35:07 +0300 Subject: [PATCH 008/225] qualcommax: ipq807x: add smp_affinity init script Signed-off-by: bitthief --- .../base-files/etc/init.d/smp_affinity | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100755 target/linux/qualcommax/ipq807x/base-files/etc/init.d/smp_affinity diff --git a/target/linux/qualcommax/ipq807x/base-files/etc/init.d/smp_affinity b/target/linux/qualcommax/ipq807x/base-files/etc/init.d/smp_affinity new file mode 100755 index 00000000000000..09348eba33a991 --- /dev/null +++ b/target/linux/qualcommax/ipq807x/base-files/etc/init.d/smp_affinity @@ -0,0 +1,43 @@ +#!/bin/sh /etc/rc.common + +START=99 + +enable_affinity_ipq807x(){ + set_affinity() { + irq=$(awk "/$1/{ print substr(\$1, 1, length(\$1)-1); exit }" /proc/interrupts) + [ -n "$irq" ] && echo $2 > /proc/irq/$irq/smp_affinity + } + + # assign 4 rx interrupts to each core + set_affinity 'reo2host-destination-ring1' 1 + set_affinity 'reo2host-destination-ring2' 2 + set_affinity 'reo2host-destination-ring3' 4 + set_affinity 'reo2host-destination-ring4' 8 + + # assign 3 tcl completions to last 3 CPUs + set_affinity 'wbm2host-tx-completions-ring1' 2 + set_affinity 'wbm2host-tx-completions-ring2' 4 + set_affinity 'wbm2host-tx-completions-ring3' 8 +} + +boot() { + case $(board_name) in + buffalo,wxr-5950ax12|\ + compex,wpq873|\ + dynalink,dl-wrx36|\ + edgecore,eap102|\ + edimax,cax1800|\ + netgear,rax120v2|\ + netgear,wax218|\ + netgear,wax620|\ + netgear,wax630|\ + prpl,haze|\ + qnap,301w|\ + redmi,ax6|\ + xiaomi,ax3600|\ + xiaomi,ax9000|\ + zyxel,nbg7815) + enable_affinity_ipq807x + ;; + esac +} From b7f352537d319cd96afbd132ffd63488ed063072 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 01:51:06 +0300 Subject: [PATCH 009/225] generic, qualcommax: config: crypto, ktls, netfilter, misc. Signed-off-by: bitthief --- target/linux/generic/config-6.1 | 2 + .../linux/qualcommax/ipq807x/config-default | 96 +++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/target/linux/generic/config-6.1 b/target/linux/generic/config-6.1 index d11c946dbca028..cd474b483c8c65 100644 --- a/target/linux/generic/config-6.1 +++ b/target/linux/generic/config-6.1 @@ -858,6 +858,7 @@ CONFIG_BT_HCIUART_H4=y # CONFIG_BT_MSFTEXT is not set # CONFIG_BT_MTKSDIO is not set # CONFIG_BT_MTKUART is not set +# CONFIG_BT_QCOMSMD is not set # CONFIG_BT_RFCOMM is not set CONFIG_BT_RFCOMM_TTY=y # CONFIG_BT_SELFTEST is not set @@ -5779,6 +5780,7 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_Q54SJ108A2 is not set # CONFIG_SENSORS_RM3100_I2C is not set # CONFIG_SENSORS_RM3100_SPI is not set +# CONFIG_SENSORS_Q54SJ108A2 is not set # CONFIG_SENSORS_SBRMI is not set # CONFIG_SENSORS_SBTSI is not set # CONFIG_SENSORS_SCH5627 is not set diff --git a/target/linux/qualcommax/ipq807x/config-default b/target/linux/qualcommax/ipq807x/config-default index 18483d05b449a2..68a750e6edb4ac 100644 --- a/target/linux/qualcommax/ipq807x/config-default +++ b/target/linux/qualcommax/ipq807x/config-default @@ -1,9 +1,92 @@ CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y +CONFIG_ARM_QCOM_CPUFREQ_HW=y +CONFIG_ASN1=y +CONFIG_ASN1_ENCODER=y +CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_ASYMMETRIC_KEY_TYPE=y +# CONFIG_ASYMMETRIC_TPM_KEY_SUBTYPE is not set +CONFIG_AT803X_PHY=y +CONFIG_BPFILTER=y +CONFIG_BPFILTER_UMH=m +CONFIG_CLZ_TAB=y +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set +CONFIG_CRYPTO_AES_ARM64=y +CONFIG_CRYPTO_AES_ARM64_BS=y +CONFIG_CRYPTO_AES_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y +CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=y +CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=y +CONFIG_CRYPTO_BLAKE2B=y +CONFIG_CRYPTO_BLAKE2S=y +CONFIG_CRYPTO_CFB=y +CONFIG_CRYPTO_CHACHA20=y +CONFIG_CRYPTO_CHACHA20POLY1305=y +CONFIG_CRYPTO_CHACHA20_NEON=y +CONFIG_CRYPTO_CMAC=y +CONFIG_CRYPTO_CRCT10DIF=y +CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=y +CONFIG_CRYPTO_CRYPTD=y +CONFIG_CRYPTO_CURVE25519=y +CONFIG_CRYPTO_DH=y +CONFIG_CRYPTO_DH_RFC7919_GROUPS=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_ECC=y +CONFIG_CRYPTO_ECDH=y +CONFIG_CRYPTO_ECDSA=y +CONFIG_CRYPTO_ECRDSA=y +CONFIG_CRYPTO_GF128MUL=y +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_KEYWRAP=y +CONFIG_CRYPTO_LIB_CHACHA_GENERIC=y +CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=y +CONFIG_CRYPTO_LIB_POLY1305_GENERIC=y +CONFIG_CRYPTO_LIB_SM4=y +CONFIG_CRYPTO_LRW=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_NULL2=y +CONFIG_CRYPTO_NHPOLY1305_NEON=y +CONFIG_CRYPTO_OFB=y +CONFIG_CRYPTO_POLY1305=y +CONFIG_CRYPTO_POLY1305_NEON=y +CONFIG_CRYPTO_POLYVAL_ARM64_CE=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_RSA=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +CONFIG_CRYPTO_SHA256_ARM64=y +CONFIG_CRYPTO_SHA3=y +CONFIG_CRYPTO_SHA3_ARM64=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_SHA512_ARM64=y +CONFIG_CRYPTO_SHA512_ARM64_CE=y +CONFIG_CRYPTO_SIMD=y +CONFIG_CRYPTO_SM2=y +CONFIG_CRYPTO_SM3=y +CONFIG_CRYPTO_SM3_ARM64_CE=y +CONFIG_CRYPTO_SM3_NEON=y +CONFIG_CRYPTO_SM4_ARM64_CE=y +CONFIG_CRYPTO_SM4_ARM64_CE_BLK=y +CONFIG_CRYPTO_SM4_ARM64_NEON_BLK=y +CONFIG_CRYPTO_STREEBOG=y +CONFIG_CRYPTO_XXHASH=y CONFIG_DT_IDLE_GENPD=y +CONFIG_IP6_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_MASQUERADE=y CONFIG_IPQ_GCC_8074=y # CONFIG_MFD_HI6421_SPMI is not set CONFIG_MFD_SPMI_PMIC=y +CONFIG_MPILIB=y # CONFIG_NVMEM_SPMI_SDAM is not set +CONFIG_OID_REGISTRY=y CONFIG_PINCTRL_IPQ8074=y CONFIG_PINCTRL_QCOM_SPMI_PMIC=y # CONFIG_PM8916_WATCHDOG is not set @@ -13,9 +96,14 @@ CONFIG_PM_GENERIC_DOMAINS_OF=y CONFIG_QCOM_APM=y # CONFIG_QCOM_COINCELL is not set CONFIG_QCOM_GDSC=y +# CONFIG_QCOM_IPA is not set +CONFIG_QCOM_QFPROM=y +# CONFIG_QCOM_QMI_HELPERS is not set CONFIG_QCOM_SPMI_ADC5=y # CONFIG_QCOM_SPMI_RRADC is not set CONFIG_QCOM_VADC_COMMON=y +CONFIG_QCOM_WCNSS_CTRL=y +CONFIG_QCOM_WCNSS_PIL=y CONFIG_REGMAP_SPMI=y CONFIG_REGULATOR_CPR3=y # CONFIG_REGULATOR_CPR3_NPU is not set @@ -23,8 +111,16 @@ CONFIG_REGULATOR_CPR4_APSS=y # CONFIG_REGULATOR_QCOM_LABIBB is not set CONFIG_REGULATOR_QCOM_SPMI=y # CONFIG_REGULATOR_QCOM_USB_VBUS is not set +CONFIG_RESET_QCOM_AOSS=y +CONFIG_RESET_QCOM_PDC=y CONFIG_RTC_DRV_PM8XXX=y +# CONFIG_SCHED_CLUSTER is not set +CONFIG_SCHED_CORE=y CONFIG_SPMI=y # CONFIG_SPMI_HISI3670 is not set CONFIG_SPMI_MSM_PMIC_ARB=y # CONFIG_SPMI_PMIC_CLKDIV is not set +CONFIG_TLS=y +CONFIG_TLS_DEVICE=y +# CONFIG_TLS_TOE is not set +CONFIG_XOR_BLOCKS=y From 185a93f136001636645463146699143c8f261622 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 01:52:43 +0300 Subject: [PATCH 010/225] qualcommax: config: enable preemptive/RT kernel build Signed-off-by: bitthief --- target/linux/qualcommax/config-6.1 | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/target/linux/qualcommax/config-6.1 b/target/linux/qualcommax/config-6.1 index 7a983b961b393e..00d92ad71a8b92 100644 --- a/target/linux/qualcommax/config-6.1 +++ b/target/linux/qualcommax/config-6.1 @@ -184,6 +184,11 @@ CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT_MAP=y CONFIG_HWSPINLOCK=y CONFIG_HWSPINLOCK_QCOM=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MSM=y +CONFIG_HZ=1000 +# CONFIG_HZ_100 is not set +CONFIG_HZ_1000=y CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y @@ -348,7 +353,12 @@ CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y CONFIG_POWER_RESET=y # CONFIG_POWER_RESET_MSM is not set CONFIG_POWER_SUPPLY=y -CONFIG_PREEMPT_NONE_BUILD=y +CONFIG_PREEMPT=y +CONFIG_PREEMPT_COUNT=y +# CONFIG_PREEMPT_DYNAMIC is not set +# CONFIG_PREEMPT_NONE_BUILD is not set +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_RCU=y CONFIG_PRINTK_TIME=y CONFIG_PTP_1588_CLOCK_OPTIONAL=y # CONFIG_QCM_DISPCC_2290 is not set @@ -363,7 +373,7 @@ CONFIG_QCOM_BAM_DMA=y # CONFIG_QCOM_CLK_APCS_MSM8916 is not set # CONFIG_QCOM_CLK_APCS_SDX55 is not set # CONFIG_QCOM_COMMAND_DB is not set -# CONFIG_QCOM_CPR is not set +CONFIG_QCOM_CPR=y # CONFIG_QCOM_EBI2 is not set # CONFIG_QCOM_FASTRPC is not set # CONFIG_QCOM_GENI_SE is not set @@ -408,6 +418,7 @@ CONFIG_QUEUED_SPINLOCKS=y CONFIG_RANDSTRUCT_NONE=y CONFIG_RAS=y CONFIG_RATIONAL=y +# CONFIG_RCU_BOOST is not set CONFIG_REGMAP=y CONFIG_REGMAP_MMIO=y CONFIG_REGULATOR=y From 248cd3a623ee3e14da204de0752e61bf9dd8b066 Mon Sep 17 00:00:00 2001 From: bitthief Date: Wed, 20 Jul 2022 01:41:31 +0300 Subject: [PATCH 011/225] package: fullconenat Reference: https: //github.com/coolsnowwolf/lede https: //github.com/Chion82/netfilter-full-cone-nat Signed-off-by: bitthief --- package/network/config/firewall/Makefile | 6 +- .../config/firewall/files/firewall.config | 2 + .../config/firewall/patches/fullconenat.patch | 63 ++++++++++++++++ package/network/utils/fullconenat/Makefile | 71 +++++++++++++++++++ .../fullconenat/patches/000-printk.patch | 19 +++++ .../network/utils/fullconenat/src/Makefile | 12 ++++ 6 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 package/network/config/firewall/patches/fullconenat.patch create mode 100644 package/network/utils/fullconenat/Makefile create mode 100644 package/network/utils/fullconenat/patches/000-printk.patch create mode 100644 package/network/utils/fullconenat/src/Makefile diff --git a/package/network/config/firewall/Makefile b/package/network/config/firewall/Makefile index 0e00f386897a7c..73d9dc95068133 100644 --- a/package/network/config/firewall/Makefile +++ b/package/network/config/firewall/Makefile @@ -30,7 +30,9 @@ define Package/firewall SECTION:=net CATEGORY:=Base system TITLE:=OpenWrt C Firewall - DEPENDS:=+libubox +libubus +libuci +libip4tc +IPV6:libip6tc +libiptext +IPV6:libiptext6 +libxtables +kmod-ipt-core +kmod-ipt-conntrack +IPV6:kmod-nf-conntrack6 +kmod-ipt-nat + DEPENDS:=+libubox +libubus +libuci +libip4tc +IPV6:libip6tc +libiptext +IPV6:libiptext6 \ + +libxtables +kmod-ipt-core +kmod-ipt-conntrack +IPV6:kmod-nf-conntrack6 +kmod-ipt-nat \ + +iptables-mod-fullconenat PROVIDES:=uci-firewall CONFLICTS:=firewall4 endef @@ -61,4 +63,4 @@ define Package/firewall/install $(INSTALL_CONF) $(PKG_BUILD_DIR)/helpers.conf $(1)/usr/share/fw3 endef -$(eval $(call BuildPackage,firewall)) +$(eval $(call BuildPackage,firewall)) \ No newline at end of file diff --git a/package/network/config/firewall/files/firewall.config b/package/network/config/firewall/files/firewall.config index b90ac7af0a382c..231ee7116d6f80 100644 --- a/package/network/config/firewall/files/firewall.config +++ b/package/network/config/firewall/files/firewall.config @@ -3,6 +3,8 @@ config defaults option input REJECT option output ACCEPT option forward REJECT + option flow_offloading 1 + option fullcone 1 # Uncomment this line to disable ipv6 rules # option disable_ipv6 1 diff --git a/package/network/config/firewall/patches/fullconenat.patch b/package/network/config/firewall/patches/fullconenat.patch new file mode 100644 index 00000000000000..d69e7129ec7ebd --- /dev/null +++ b/package/network/config/firewall/patches/fullconenat.patch @@ -0,0 +1,63 @@ +index 85a3750..9fac9b1 100644 +--- a/defaults.c ++++ b/defaults.c +@@ -46,7 +46,9 @@ const struct fw3_option fw3_flag_opts[] = { + FW3_OPT("synflood_protect", bool, defaults, syn_flood), + FW3_OPT("synflood_rate", limit, defaults, syn_flood_rate), + FW3_OPT("synflood_burst", int, defaults, syn_flood_rate.burst), +- ++ ++ FW3_OPT("fullcone", bool, defaults, fullcone), ++ + FW3_OPT("tcp_syncookies", bool, defaults, tcp_syncookies), + FW3_OPT("tcp_ecn", int, defaults, tcp_ecn), + FW3_OPT("tcp_window_scaling", bool, defaults, tcp_window_scaling), +diff --git a/options.h b/options.h +index 6edd174..c02eb97 100644 +--- a/options.h ++++ b/options.h +@@ -267,6 +267,7 @@ struct fw3_defaults + bool drop_invalid; + + bool syn_flood; ++ bool fullcone; + struct fw3_limit syn_flood_rate; + + bool tcp_syncookies; +diff --git a/zones.c b/zones.c +index 2aa7473..57eead0 100644 +--- a/zones.c ++++ b/zones.c +@@ -627,6 +627,7 @@ print_zone_rule(struct fw3_ipt_handle *h + struct fw3_address *msrc; + struct fw3_address *mdest; + struct fw3_ipt_rule *r; ++ struct fw3_defaults *defs = &state->defaults; + + if (!fw3_is_family(zone, handle->family)) + return; +@@ -712,8 +713,22 @@ print_zone_rule(struct fw3_ipt_handle *h + { + r = fw3_ipt_rule_new(handle); + fw3_ipt_rule_src_dest(r, msrc, mdest); +- fw3_ipt_rule_target(r, "MASQUERADE"); +- fw3_ipt_rule_append(r, "zone_%s_postrouting", zone->name); ++ /*FIXME: Workaround for FULLCONE-NAT*/ ++ if(defs->fullcone) ++ { ++ warn("%s will enable FULLCONE-NAT", zone->name); ++ fw3_ipt_rule_target(r, "FULLCONENAT"); ++ fw3_ipt_rule_append(r, "zone_%s_postrouting", zone->name); ++ r = fw3_ipt_rule_new(handle); ++ fw3_ipt_rule_src_dest(r, msrc, mdest); ++ fw3_ipt_rule_target(r, "FULLCONENAT"); ++ fw3_ipt_rule_append(r, "zone_%s_prerouting", zone->name); ++ } ++ else ++ { ++ fw3_ipt_rule_target(r, "MASQUERADE"); ++ fw3_ipt_rule_append(r, "zone_%s_postrouting", zone->name); ++ } + } + } + } diff --git a/package/network/utils/fullconenat/Makefile b/package/network/utils/fullconenat/Makefile new file mode 100644 index 00000000000000..d0771f7a84215a --- /dev/null +++ b/package/network/utils/fullconenat/Makefile @@ -0,0 +1,71 @@ +# +# Copyright (C) 2018 Chion Tang +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=fullconenat +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/llccd/netfilter-full-cone-nat.git +PKG_SOURCE_DATE:=2023-01-01 +PKG_SOURCE_VERSION:=74c5e6f3c7faaf33ece451697537c81781781c20 +PKG_MIRROR_HASH:=3c254f1edba28eafdccac9cf95eb550fd2b05eeaaec8a02c73e1dcd2f98f9d93 + +PKG_LICENSE:=GPL-2.0 +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Chion Tang + +include $(INCLUDE_DIR)/package.mk + +define Package/iptables-mod-fullconenat + SUBMENU:=Firewall + SECTION:=net + CATEGORY:=Network + TITLE:=FULLCONENAT iptables extension + DEPENDS:=+iptables +kmod-ipt-fullconenat +endef + +define Package/ip6tables-mod-fullconenat + SUBMENU:=Firewall + SECTION:=net + CATEGORY:=Network + TITLE:=FULLCONENAT ip6tables extension + DEPENDS:=ip6tables +kmod-nf-nat6 +kmod-ipt-fullconenat +ip6tables-mod-nat +endef + +define KernelPackage/ipt-fullconenat + SUBMENU:=Netfilter Extensions + TITLE:=FULLCONENAT netfilter module + DEPENDS:=+kmod-nf-ipt +kmod-nf-nat + KCONFIG:= \ + CONFIG_NF_CONNTRACK_EVENTS=y \ + CONFIG_NF_CONNTRACK_CHAIN_EVENTS=n + FILES:=$(PKG_BUILD_DIR)/xt_FULLCONENAT.ko +endef + +include $(INCLUDE_DIR)/kernel-defaults.mk + +define Build/Compile + +$(KERNEL_MAKE) M="$(PKG_BUILD_DIR)" modules + $(call Build/Compile/Default) +endef + +define Package/iptables-mod-fullconenat/install + $(INSTALL_DIR) $(1)/usr/lib/iptables + $(INSTALL_BIN) $(PKG_BUILD_DIR)/libipt_FULLCONENAT.so $(1)/usr/lib/iptables +endef + +define Package/ip6tables-mod-fullconenat/install + $(INSTALL_DIR) $(1)/usr/lib/iptables + $(INSTALL_BIN) $(PKG_BUILD_DIR)/libip6t_FULLCONENAT.so $(1)/usr/lib/iptables +endef + +$(eval $(call BuildPackage,iptables-mod-fullconenat)) +$(eval $(call BuildPackage,ip6tables-mod-fullconenat)) +$(eval $(call KernelPackage,ipt-fullconenat)) diff --git a/package/network/utils/fullconenat/patches/000-printk.patch b/package/network/utils/fullconenat/patches/000-printk.patch new file mode 100644 index 00000000000000..251d10f5ddc204 --- /dev/null +++ b/package/network/utils/fullconenat/patches/000-printk.patch @@ -0,0 +1,19 @@ +diff --git a/xt_FULLCONENAT.c b/xt_FULLCONENAT.c +index 30e7686..492f638 100644 +--- a/xt_FULLCONENAT.c ++++ b/xt_FULLCONENAT.c +@@ -1345,9 +1345,13 @@ static struct xt_target tg_reg[] __read_mostly = { + static int __init fullconenat_tg_init(void) + { + int ret; ++ ++ printk(KERN_INFO "xt_FULLCONENAT: RFC3489 Full Cone NAT module\n" ++ "xt_FULLCONENAT: Copyright (C) 2018 Chion Tang \n"); ++ + wq = create_singlethread_workqueue("xt_FULLCONENAT"); + if (wq == NULL) { +- printk("xt_FULLCONENAT: warning: failed to create workqueue\n"); ++ printk(KERN_WARNING "xt_FULLCONENAT: warning: failed to create workqueue\n"); + } + + #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) diff --git a/package/network/utils/fullconenat/src/Makefile b/package/network/utils/fullconenat/src/Makefile new file mode 100644 index 00000000000000..a48a513daf60ab --- /dev/null +++ b/package/network/utils/fullconenat/src/Makefile @@ -0,0 +1,12 @@ +all: libipt_FULLCONENAT.so libip6t_FULLCONENAT.so + +libipt_FULLCONENAT.so: libipt_FULLCONENAT.o + $(CC) -shared -lxtables -o $@ $^; +libipt_FULLCONENAT.o: libipt_FULLCONENAT.c + $(CC) ${CFLAGS} -fPIC -c -o $@ $<; +libip6t_FULLCONENAT.so: libip6t_FULLCONENAT.o + $(CC) -shared -lxtables -o $@ $^; +libip6t_FULLCONENAT.o: libip6t_FULLCONENAT.c + $(CC) ${CFLAGS} -fPIC -c -o $@ $<; + +obj-m += xt_FULLCONENAT.o From 890fc97eb0927756be622f787359cc4be845972d Mon Sep 17 00:00:00 2001 From: bitthief Date: Thu, 1 Dec 2022 05:36:10 +0200 Subject: [PATCH 012/225] kernel: sysctl: update nf_ct settings for fullcone nat Reference: https: //github.com/coolsnowwolf/lede/commit/58692d5c98169249eae7b8cb27b45ce6ecac1d92 Signed-off-by: bitthief --- package/kernel/linux/files/sysctl-nf-conntrack.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package/kernel/linux/files/sysctl-nf-conntrack.conf b/package/kernel/linux/files/sysctl-nf-conntrack.conf index c6a0ef362b6a9f..b8821b162ac4b8 100644 --- a/package/kernel/linux/files/sysctl-nf-conntrack.conf +++ b/package/kernel/linux/files/sysctl-nf-conntrack.conf @@ -6,3 +6,6 @@ net.netfilter.nf_conntrack_checksum=0 net.netfilter.nf_conntrack_tcp_timeout_established=7440 net.netfilter.nf_conntrack_udp_timeout=60 net.netfilter.nf_conntrack_udp_timeout_stream=180 +net.netfilter.nf_conntrack_helper=1 +net.netfilter.nf_conntrack_buckets=16384 +net.netfilter.nf_conntrack_expect_max=16384 \ No newline at end of file From 3bbab2ccf223fd10b9759c5b5f51cef94c817719 Mon Sep 17 00:00:00 2001 From: bitthief Date: Wed, 20 Jul 2022 01:43:38 +0300 Subject: [PATCH 013/225] package: nft-fullcone Add firewall4 and nftables support for fullcone NAT. Reference: https: //github.com/fullcone-nat-nftables/nft-fullcone https: //github.com/fullcone-nat-nftables/openwrt-firewall4-with-fullcone Signed-off-by: bitthief --- package/libs/libnftnl/Makefile | 1 + ...ftnl-Add-fullcone-expression-support.patch | 253 ++++++++++++++++++ package/network/config/firewall4/Makefile | 4 +- .../001-firewall4-Add-fullcone-support.patch | 215 +++++++++++++++ .../network/utils/fullconenat-nft/Makefile | 50 ++++ ...bles-Add-fullcone-expression-support.patch | 208 ++++++++++++++ 6 files changed, 729 insertions(+), 2 deletions(-) create mode 100644 package/libs/libnftnl/patches/001-libnftnl-Add-fullcone-expression-support.patch create mode 100644 package/network/config/firewall4/patches/001-firewall4-Add-fullcone-support.patch create mode 100644 package/network/utils/fullconenat-nft/Makefile create mode 100644 package/network/utils/nftables/patches/0001-nftables-Add-fullcone-expression-support.patch diff --git a/package/libs/libnftnl/Makefile b/package/libs/libnftnl/Makefile index b512d4d58fe616..1e4fa66e2a6f9c 100644 --- a/package/libs/libnftnl/Makefile +++ b/package/libs/libnftnl/Makefile @@ -23,6 +23,7 @@ PKG_LICENSE_FILES:=COPYING PKG_INSTALL:=1 PKG_BUILD_PARALLEL:=1 PKG_BUILD_FLAGS:=lto +PKG_FIXUP:=autoreconf include $(INCLUDE_DIR)/package.mk diff --git a/package/libs/libnftnl/patches/001-libnftnl-Add-fullcone-expression-support.patch b/package/libs/libnftnl/patches/001-libnftnl-Add-fullcone-expression-support.patch new file mode 100644 index 00000000000000..f68882849a25a4 --- /dev/null +++ b/package/libs/libnftnl/patches/001-libnftnl-Add-fullcone-expression-support.patch @@ -0,0 +1,253 @@ +From 6c39f04febd7cfdbd474233379416babcd0fc341 Mon Sep 17 00:00:00 2001 +From: Syrone Wong +Date: Fri, 8 Apr 2022 23:52:11 +0800 +Subject: [PATCH] libnftnl: add fullcone expression support + +Signed-off-by: Syrone Wong +--- + include/libnftnl/expr.h | 6 + + include/linux/netfilter/nf_tables.h | 16 +++ + src/Makefile.am | 1 + + src/expr/fullcone.c | 167 ++++++++++++++++++++++++++++ + src/expr_ops.c | 2 + + 5 files changed, 192 insertions(+) + create mode 100644 src/expr/fullcone.c + +--- a/include/libnftnl/expr.h ++++ b/include/libnftnl/expr.h +@@ -245,6 +245,12 @@ enum { + }; + + enum { ++ NFTNL_EXPR_FULLCONE_FLAGS = NFTNL_EXPR_BASE, ++ NFTNL_EXPR_FULLCONE_REG_PROTO_MIN, ++ NFTNL_EXPR_FULLCONE_REG_PROTO_MAX, ++}; ++ ++enum { + NFTNL_EXPR_REDIR_REG_PROTO_MIN = NFTNL_EXPR_BASE, + NFTNL_EXPR_REDIR_REG_PROTO_MAX, + NFTNL_EXPR_REDIR_FLAGS, +--- a/include/linux/netfilter/nf_tables.h ++++ b/include/linux/netfilter/nf_tables.h +@@ -1464,6 +1464,22 @@ enum nft_masq_attributes { + #define NFTA_MASQ_MAX (__NFTA_MASQ_MAX - 1) + + /** ++ * enum nft_fullcone_attributes - nf_tables fullcone expression attributes ++ * ++ * @NFTA_FULLCONE_FLAGS: NAT flags (see NF_NAT_RANGE_* in linux/netfilter/nf_nat.h) (NLA_U32) ++ * @NFTA_FULLCONE_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers) ++ * @NFTA_FULLCONE_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers) ++ */ ++enum nft_fullcone_attributes { ++ NFTA_FULLCONE_UNSPEC, ++ NFTA_FULLCONE_FLAGS, ++ NFTA_FULLCONE_REG_PROTO_MIN, ++ NFTA_FULLCONE_REG_PROTO_MAX, ++ __NFTA_FULLCONE_MAX ++}; ++#define NFTA_FULLCONE_MAX (__NFTA_FULLCONE_MAX - 1) ++ ++/** + * enum nft_redir_attributes - nf_tables redirect expression netlink attributes + * + * @NFTA_REDIR_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers) +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -55,6 +55,7 @@ libnftnl_la_SOURCES = utils.c \ + expr/target.c \ + expr/tunnel.c \ + expr/masq.c \ ++ expr/fullcone.c \ + expr/redir.c \ + expr/hash.c \ + expr/socket.c \ +--- /dev/null ++++ b/src/expr/fullcone.c +@@ -0,0 +1,167 @@ ++/* ++ * (C) 2022 wongsyrone ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published ++ * by the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "internal.h" ++#include ++#include ++#include ++ ++struct nftnl_expr_fullcone { ++ uint32_t flags; ++ enum nft_registers sreg_proto_min; ++ enum nft_registers sreg_proto_max; ++}; ++ ++static int ++nftnl_expr_fullcone_set(struct nftnl_expr *e, uint16_t type, ++ const void *data, uint32_t data_len) ++{ ++ struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e); ++ ++ switch (type) { ++ case NFTNL_EXPR_FULLCONE_FLAGS: ++ memcpy(&fullcone->flags, data, sizeof(fullcone->flags)); ++ break; ++ case NFTNL_EXPR_FULLCONE_REG_PROTO_MIN: ++ memcpy(&fullcone->sreg_proto_min, data, sizeof(fullcone->sreg_proto_min)); ++ break; ++ case NFTNL_EXPR_FULLCONE_REG_PROTO_MAX: ++ memcpy(&fullcone->sreg_proto_max, data, sizeof(fullcone->sreg_proto_max)); ++ break; ++ default: ++ return -1; ++ } ++ return 0; ++} ++ ++static const void * ++nftnl_expr_fullcone_get(const struct nftnl_expr *e, uint16_t type, ++ uint32_t *data_len) ++{ ++ struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e); ++ ++ switch (type) { ++ case NFTNL_EXPR_FULLCONE_FLAGS: ++ *data_len = sizeof(fullcone->flags); ++ return &fullcone->flags; ++ case NFTNL_EXPR_FULLCONE_REG_PROTO_MIN: ++ *data_len = sizeof(fullcone->sreg_proto_min); ++ return &fullcone->sreg_proto_min; ++ case NFTNL_EXPR_FULLCONE_REG_PROTO_MAX: ++ *data_len = sizeof(fullcone->sreg_proto_max); ++ return &fullcone->sreg_proto_max; ++ } ++ return NULL; ++} ++ ++static int nftnl_expr_fullcone_cb(const struct nlattr *attr, void *data) ++{ ++ const struct nlattr **tb = data; ++ int type = mnl_attr_get_type(attr); ++ ++ if (mnl_attr_type_valid(attr, NFTA_FULLCONE_MAX) < 0) ++ return MNL_CB_OK; ++ ++ switch (type) { ++ case NFTA_FULLCONE_REG_PROTO_MIN: ++ case NFTA_FULLCONE_REG_PROTO_MAX: ++ case NFTA_FULLCONE_FLAGS: ++ if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) ++ abi_breakage(); ++ break; ++ } ++ ++ tb[type] = attr; ++ return MNL_CB_OK; ++} ++ ++static void ++nftnl_expr_fullcone_build(struct nlmsghdr *nlh, const struct nftnl_expr *e) ++{ ++ struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e); ++ ++ if (e->flags & (1 << NFTNL_EXPR_FULLCONE_FLAGS)) ++ mnl_attr_put_u32(nlh, NFTA_FULLCONE_FLAGS, htobe32(fullcone->flags)); ++ if (e->flags & (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MIN)) ++ mnl_attr_put_u32(nlh, NFTA_FULLCONE_REG_PROTO_MIN, ++ htobe32(fullcone->sreg_proto_min)); ++ if (e->flags & (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MAX)) ++ mnl_attr_put_u32(nlh, NFTA_FULLCONE_REG_PROTO_MAX, ++ htobe32(fullcone->sreg_proto_max)); ++} ++ ++static int ++nftnl_expr_fullcone_parse(struct nftnl_expr *e, struct nlattr *attr) ++{ ++ struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e); ++ struct nlattr *tb[NFTA_FULLCONE_MAX+1] = {}; ++ ++ if (mnl_attr_parse_nested(attr, nftnl_expr_fullcone_cb, tb) < 0) ++ return -1; ++ ++ if (tb[NFTA_FULLCONE_FLAGS]) { ++ fullcone->flags = be32toh(mnl_attr_get_u32(tb[NFTA_FULLCONE_FLAGS])); ++ e->flags |= (1 << NFTNL_EXPR_FULLCONE_FLAGS); ++ } ++ if (tb[NFTA_FULLCONE_REG_PROTO_MIN]) { ++ fullcone->sreg_proto_min = ++ be32toh(mnl_attr_get_u32(tb[NFTA_FULLCONE_REG_PROTO_MIN])); ++ e->flags |= (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MIN); ++ } ++ if (tb[NFTA_FULLCONE_REG_PROTO_MAX]) { ++ fullcone->sreg_proto_max = ++ be32toh(mnl_attr_get_u32(tb[NFTA_FULLCONE_REG_PROTO_MAX])); ++ e->flags |= (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MAX); ++ } ++ ++ return 0; ++} ++ ++static int nftnl_expr_fullcone_snprintf(char *buf, size_t remain, ++ uint32_t flags, const struct nftnl_expr *e) ++{ ++ struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e); ++ int offset = 0, ret = 0; ++ ++ if (e->flags & (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MIN)) { ++ ret = snprintf(buf + offset, remain, "proto_min reg %u ", ++ fullcone->sreg_proto_min); ++ SNPRINTF_BUFFER_SIZE(ret, remain, offset); ++ } ++ if (e->flags & (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MAX)) { ++ ret = snprintf(buf + offset, remain, "proto_max reg %u ", ++ fullcone->sreg_proto_max); ++ SNPRINTF_BUFFER_SIZE(ret, remain, offset); ++ } ++ if (e->flags & (1 << NFTNL_EXPR_FULLCONE_FLAGS)) { ++ ret = snprintf(buf + offset, remain, "flags 0x%x ", fullcone->flags); ++ SNPRINTF_BUFFER_SIZE(ret, remain, offset); ++ } ++ ++ return offset; ++} ++ ++struct expr_ops expr_ops_fullcone = { ++ .name = "fullcone", ++ .alloc_len = sizeof(struct nftnl_expr_fullcone), ++ .max_attr = NFTA_FULLCONE_MAX, ++ .set = nftnl_expr_fullcone_set, ++ .get = nftnl_expr_fullcone_get, ++ .parse = nftnl_expr_fullcone_parse, ++ .build = nftnl_expr_fullcone_build, ++ .output = nftnl_expr_fullcone_snprintf, ++}; +--- a/src/expr_ops.c ++++ b/src/expr_ops.c +@@ -20,6 +20,7 @@ extern struct expr_ops expr_ops_limit; + extern struct expr_ops expr_ops_log; + extern struct expr_ops expr_ops_lookup; + extern struct expr_ops expr_ops_masq; ++extern struct expr_ops expr_ops_fullcone; + extern struct expr_ops expr_ops_match; + extern struct expr_ops expr_ops_meta; + extern struct expr_ops expr_ops_ng; +@@ -65,6 +66,7 @@ static struct expr_ops *expr_ops[] = { + &expr_ops_log, + &expr_ops_lookup, + &expr_ops_masq, ++ &expr_ops_fullcone, + &expr_ops_match, + &expr_ops_meta, + &expr_ops_ng, diff --git a/package/network/config/firewall4/Makefile b/package/network/config/firewall4/Makefile index 6a54e28f0c2a71..c35e1181c3104e 100644 --- a/package/network/config/firewall4/Makefile +++ b/package/network/config/firewall4/Makefile @@ -23,7 +23,7 @@ define Package/firewall4 TITLE:=OpenWrt 4th gen firewall DEPENDS:= \ +kmod-nft-core +kmod-nft-fib +kmod-nft-offload \ - +kmod-nft-nat \ + +kmod-nft-nat +kmod-nft-fullcone \ +nftables-json \ +ucode +ucode-mod-fs +ucode-mod-ubus +ucode-mod-uci EXTRA_DEPENDS:=ucode (>= 2022-03-22) @@ -47,4 +47,4 @@ endef define Build/Compile endef -$(eval $(call BuildPackage,firewall4)) +$(eval $(call BuildPackage,firewall4)) \ No newline at end of file diff --git a/package/network/config/firewall4/patches/001-firewall4-Add-fullcone-support.patch b/package/network/config/firewall4/patches/001-firewall4-Add-fullcone-support.patch new file mode 100644 index 00000000000000..3ed2caef00390f --- /dev/null +++ b/package/network/config/firewall4/patches/001-firewall4-Add-fullcone-support.patch @@ -0,0 +1,215 @@ +From aa3b56e289fba7425e649a608c333622ffd9c367 Mon Sep 17 00:00:00 2001 +From: Syrone Wong +Date: Sat, 9 Apr 2022 13:24:19 +0800 +Subject: [PATCH] firewall4: add fullcone support + +fullcone is drop-in replacement of masq for non-udp traffic + +add runtime fullcone rule check, disable it globally if fullcone expr is +invalid + +defaults.fullcone and defaults.fullcone6 are switches for IPv4 and IPv6 +respectively, most IPv6 traffic do NOT need this FullCone NAT functionality. + +Renew: ZiMing Mo +--- + root/etc/config/firewall | 2 ++ + root/usr/share/firewall4/templates/ruleset.uc | 16 ++++++++++++++-- + .../firewall4/templates/zone-fullcone.uc | 4 ++++ + root/usr/share/ucode/fw4.uc | 69 ++++++++++++++++++- + 4 files changed, 89 insertions(+), 4 deletions(-) + create mode 100644 root/usr/share/firewall4/templates/zone-fullcone.uc + +--- a/root/etc/config/firewall ++++ b/root/etc/config/firewall +@@ -5,6 +5,9 @@ config defaults + option forward REJECT + # Uncomment this line to disable ipv6 rules + # option disable_ipv6 1 ++ option flow_offloading 1 ++ option fullcone 1 ++ option fullcone6 0 + + config zone + option name lan +--- a/root/usr/share/firewall4/templates/ruleset.uc ++++ b/root/usr/share/firewall4/templates/ruleset.uc +@@ -316,6 +316,12 @@ table inet fw4 { + {% for (let redirect in fw4.redirects(`dstnat_${zone.name}`)): %} + {%+ include("redirect.uc", { fw4, redirect }) %} + {% endfor %} ++{% if (zone.masq && fw4.default_option("fullcone")): %} ++ {%+ include("zone-fullcone.uc", { fw4, zone, family: 4, direction: "dstnat" }) %} ++{% endif %} ++{% if (zone.masq6 && fw4.default_option("fullcone6")): %} ++ {%+ include("zone-fullcone.uc", { fw4, zone, family: 6, direction: "dstnat" }) %} ++{% endif %} + {% fw4.includes('chain-append', `dstnat_${zone.name}`) %} + } + +@@ -326,20 +326,26 @@ table inet fw4 { + {% for (let redirect in fw4.redirects(`srcnat_${zone.name}`)): %} + {%+ include("redirect.uc", { fw4, redirect }) %} + {% endfor %} +-{% if (zone.masq): %} ++{% if (zone.masq && !fw4.default_option("fullcone")): %} + {% for (let saddrs in zone.masq4_src_subnets): %} + {% for (let daddrs in zone.masq4_dest_subnets): %} + {%+ include("zone-masq.uc", { fw4, zone, family: 4, saddrs, daddrs }) %} + {% endfor %} + {% endfor %} + {% endif %} +-{% if (zone.masq6): %} ++{% if (zone.masq6 && !fw4.default_option("fullcone6")): %} + {% for (let saddrs in zone.masq6_src_subnets): %} + {% for (let daddrs in zone.masq6_dest_subnets): %} + {%+ include("zone-masq.uc", { fw4, zone, family: 6, saddrs, daddrs }) %} + {% endfor %} + {% endfor %} + {% endif %} ++{% if (zone.masq && fw4.default_option("fullcone")): %} ++ {%+ include("zone-fullcone.uc", { fw4, zone, family: 4, direction: "srcnat" }) %} ++{% endif %} ++{% if (zone.masq6 && fw4.default_option("fullcone6")): %} ++ {%+ include("zone-fullcone.uc", { fw4, zone, family: 6, direction: "srcnat" }) %} ++{% endif %} + {% fw4.includes('chain-append', `srcnat_${zone.name}`) %} + } + +--- /dev/null ++++ b/root/usr/share/firewall4/templates/zone-fullcone.uc +@@ -0,0 +1,4 @@ ++{# /usr/share/firewall4/templates/zone-fullcone.uc #} ++ meta nfproto {{ fw4.nfproto(family) }} fullcone comment "!fw4: Handle {{ ++ zone.name ++}} {{ fw4.nfproto(family, true) }} fullcone NAT {{ direction }} traffic" +--- a/root/usr/share/ucode/fw4.uc ++++ b/root/usr/share/ucode/fw4.uc +@@ -1,3 +1,5 @@ ++// /usr/share/ucode/fw4.uc ++ + const fs = require("fs"); + const uci = require("uci"); + const ubus = require("ubus"); +@@ -428,6 +430,25 @@ function nft_try_hw_offload(devices) { + return (rc == 0); + } + ++function nft_try_fullcone() { ++ let nft_test = ++ 'add table inet fw4-fullcone-test; ' + ++ 'add chain inet fw4-fullcone-test dstnat { ' + ++ 'type nat hook prerouting priority -100; policy accept; ' + ++ 'fullcone; ' + ++ '}; ' + ++ 'add chain inet fw4-fullcone-test srcnat { ' + ++ 'type nat hook postrouting priority -100; policy accept; ' + ++ 'fullcone; ' + ++ '}; '; ++ let cmd = sprintf("/usr/sbin/nft -c '%s' 2>/dev/null", replace(nft_test, "'", "'\\''")); ++ let ok = system(cmd) == 0; ++ if (!ok) { ++ warn("nft_try_fullcone: cmd "+ cmd + "\n"); ++ } ++ return ok; ++} ++ + + return { + read_kernel_version: function() { +@@ -778,6 +799,18 @@ return { + warn(`[!] ${msg}\n`); + }, + ++ myinfo: function(fmt, ...args) { ++ if (getenv("QUIET")) ++ return; ++ ++ let msg = sprintf(fmt, ...args); ++ ++ if (getenv("TTY")) ++ warn(`\033[32m${msg}\033[m\n`); ++ else ++ warn(`[I] ${msg}\n`); ++ }, ++ + get: function(sid, opt) { + return this.cursor.get("firewall", sid, opt); + }, +@@ -959,6 +992,21 @@ return { + } + }, + ++ myinfo_section: function(s, msg) { ++ if (s[".name"]) { ++ if (s.name) ++ this.myinfo("Section %s (%s) %s", this.section_id(s[".name"]), s.name, msg); ++ else ++ this.myinfo("Section %s %s", this.section_id(s[".name"]), msg); ++ } ++ else { ++ if (s.name) ++ this.myinfo("ubus %s (%s) %s", s.type || "rule", s.name, msg); ++ else ++ this.myinfo("ubus %s %s", s.type || "rule", msg); ++ } ++ }, ++ + parse_policy: function(val) { + return this.parse_enum(val, [ + "accept", +@@ -1398,6 +1446,7 @@ return { + "dnat", + "snat", + "masquerade", ++ "fullcone", + "accept", + "reject", + "drop" +@@ -1865,6 +1914,8 @@ return { + } + + let defs = this.parse_options(data, { ++ fullcone: [ "bool", "0" ], ++ fullcone6: [ "bool", "0" ], + input: [ "policy", "drop" ], + output: [ "policy", "drop" ], + forward: [ "policy", "drop" ], +@@ -1899,6 +1950,11 @@ return { + + delete defs.syn_flood; + ++ if (!nft_try_fullcone()) { ++ delete defs.fullcone; ++ warn("nft_try_fullcone failed, disable fullcone globally\n"); ++ } ++ + this.state.defaults = defs; + }, + +@@ -2124,10 +2180,23 @@ return { + zone.related_subnets = related_subnets; + zone.related_physdevs = related_physdevs; + +- if (zone.masq || zone.masq6) ++ if (zone.masq) { + zone.dflags.snat = true; ++ if (this.state.defaults.fullcone) { ++ zone.dflags.dnat = true; ++ this.myinfo_section(data, "IPv4 fullcone enabled for zone '" + zone.name + "'"); ++ } ++ } ++ ++ if (zone.masq6) { ++ zone.dflags.snat = true; ++ if (this.state.defaults.fullcone6) { ++ zone.dflags.dnat = true; ++ this.myinfo_section(data, "IPv6 fullcone enabled for zone '" + zone.name + "'"); ++ } ++ } + +- if ((zone.auto_helper && !(zone.masq || zone.masq6)) || length(zone.helper)) { ++ if ((zone.auto_helper && !(zone.masq || zone.masq6 || this.state.defaults.fullcone || this.state.defaults.fullcone6)) || length(zone.helper)) { + zone.dflags.helper = true; + + for (let helper in (length(zone.helper) ? zone.helper : this.state.helpers)) { diff --git a/package/network/utils/fullconenat-nft/Makefile b/package/network/utils/fullconenat-nft/Makefile new file mode 100644 index 00000000000000..76f36038d26a18 --- /dev/null +++ b/package/network/utils/fullconenat-nft/Makefile @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) 2018 Chion Tang +# Original xt_FULLCONENAT and related iptables extension author +# Copyright (c) 2019-2022 GitHub/llccd Twitter/@gNodeB +# Added IPv6 support for xt_FULLCONENAT and ip6tables extension +# Ported to recent kernel versions +# Copyright (c) 2022 Syrone Wong +# Massively rewrite the whole module, split the original code into library and nftables 'fullcone' expression module + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=fullconenat-nft +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/fullcone-nat-nftables/nft-fullcone.git +PKG_SOURCE_DATE:=2023-01-10 +PKG_SOURCE_VERSION:=95ad79bc6d15c64b2770fe8b7092a64d5c2a293c +PKG_MIRROR_HASH:=56440d912625a26f1a6412c5399fccf89432d1cd35d2e6c9cc4d3a445e98b223 + +PKG_LICENSE:=GPL-2.0-only +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Syrone Wong + +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/nft-fullcone + SUBMENU:=Netfilter Extensions + DEPENDS:=+kmod-nft-nat + TITLE:=nftables fullcone expression support + FILES:= $(PKG_BUILD_DIR)/src/nft_fullcone.ko + KCONFIG:= \ + CONFIG_NF_CONNTRACK_EVENTS=y \ + CONFIG_NF_CONNTRACK_CHAIN_EVENTS=n + AUTOLOAD:=$(call AutoProbe,nft_fullcone) +endef + +define KernelPackage/nft-fullcone/Description + Kernel module adds the fullcone expression that you can use + to perform NAT in the RFC3489-compatible full cone SNAT flavour. + Currently only UDP traffic is supported for full-cone NAT. + For other protos FULLCONENAT is equivalent to MASQUERADE. +endef + +define Build/Compile + +$(KERNEL_MAKE) M="$(PKG_BUILD_DIR)/src" modules +endef + +$(eval $(call KernelPackage,nft-fullcone)) diff --git a/package/network/utils/nftables/patches/0001-nftables-Add-fullcone-expression-support.patch b/package/network/utils/nftables/patches/0001-nftables-Add-fullcone-expression-support.patch new file mode 100644 index 00000000000000..4d9eb8a0d674c9 --- /dev/null +++ b/package/network/utils/nftables/patches/0001-nftables-Add-fullcone-expression-support.patch @@ -0,0 +1,208 @@ +From 58c89e8768711a959fdc6e953df3ea2254ff93c1 Mon Sep 17 00:00:00 2001 +From: Syrone Wong +Date: Sat, 9 Apr 2022 00:38:51 +0800 +Subject: [PATCH] nftables: add fullcone expression support + +Signed-off-by: Syrone Wong +--- + include/linux/netfilter/nf_tables.h | 16 ++++++++++ + include/statement.h | 1 + + src/netlink_delinearize.c | 48 +++++++++++++++++++++++++++++ + src/netlink_linearize.c | 7 +++++ + src/parser_bison.y | 28 +++++++++++++++-- + src/scanner.l | 1 + + src/statement.c | 1 + + 7 files changed, 100 insertions(+), 2 deletions(-) + +--- a/include/linux/netfilter/nf_tables.h ++++ b/include/linux/netfilter/nf_tables.h +@@ -1485,6 +1485,22 @@ enum nft_masq_attributes { + #define NFTA_MASQ_MAX (__NFTA_MASQ_MAX - 1) + + /** ++ * enum nft_fullcone_attributes - nf_tables fullcone expression attributes ++ * ++ * @NFTA_FULLCONE_FLAGS: NAT flags (see NF_NAT_RANGE_* in linux/netfilter/nf_nat.h) (NLA_U32) ++ * @NFTA_FULLCONE_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers) ++ * @NFTA_FULLCONE_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers) ++ */ ++enum nft_fullcone_attributes { ++ NFTA_FULLCONE_UNSPEC, ++ NFTA_FULLCONE_FLAGS, ++ NFTA_FULLCONE_REG_PROTO_MIN, ++ NFTA_FULLCONE_REG_PROTO_MAX, ++ __NFTA_FULLCONE_MAX ++}; ++#define NFTA_FULLCONE_MAX (__NFTA_FULLCONE_MAX - 1) ++ ++/** + * enum nft_redir_attributes - nf_tables redirect expression netlink attributes + * + * @NFTA_REDIR_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers) +--- a/include/statement.h ++++ b/include/statement.h +@@ -129,6 +129,7 @@ enum nft_nat_etypes { + __NFT_NAT_SNAT = NFT_NAT_SNAT, + __NFT_NAT_DNAT = NFT_NAT_DNAT, + NFT_NAT_MASQ, ++ NFT_NAT_FULLCONE, + NFT_NAT_REDIR, + }; + +--- a/src/netlink_delinearize.c ++++ b/src/netlink_delinearize.c +@@ -1473,6 +1473,53 @@ out_err: + stmt_free(stmt); + } + ++static void netlink_parse_fullcone(struct netlink_parse_ctx *ctx, ++ const struct location *loc, ++ const struct nftnl_expr *nle) ++{ ++ enum nft_registers reg1, reg2; ++ struct expr *proto; ++ struct stmt *stmt; ++ uint32_t flags = 0; ++ ++ if (nftnl_expr_is_set(nle, NFTNL_EXPR_FULLCONE_FLAGS)) ++ flags = nftnl_expr_get_u32(nle, NFTNL_EXPR_FULLCONE_FLAGS); ++ ++ stmt = nat_stmt_alloc(loc, NFT_NAT_FULLCONE); ++ stmt->nat.flags = flags; ++ ++ reg1 = netlink_parse_register(nle, NFTNL_EXPR_FULLCONE_REG_PROTO_MIN); ++ if (reg1) { ++ proto = netlink_get_register(ctx, loc, reg1); ++ if (proto == NULL) { ++ netlink_error(ctx, loc, ++ "fullcone statement has no proto expression"); ++ goto out_err; ++ } ++ expr_set_type(proto, &inet_service_type, BYTEORDER_BIG_ENDIAN); ++ stmt->nat.proto = proto; ++ } ++ ++ reg2 = netlink_parse_register(nle, NFTNL_EXPR_FULLCONE_REG_PROTO_MAX); ++ if (reg2 && reg2 != reg1) { ++ proto = netlink_get_register(ctx, loc, reg2); ++ if (proto == NULL) { ++ netlink_error(ctx, loc, ++ "fullcone statement has no proto expression"); ++ goto out_err; ++ } ++ expr_set_type(proto, &inet_service_type, BYTEORDER_BIG_ENDIAN); ++ if (stmt->nat.proto != NULL) ++ proto = range_expr_alloc(loc, stmt->nat.proto, proto); ++ stmt->nat.proto = proto; ++ } ++ ++ ctx->stmt = stmt; ++ return; ++out_err: ++ stmt_free(stmt); ++} ++ + static void netlink_parse_redir(struct netlink_parse_ctx *ctx, + const struct location *loc, + const struct nftnl_expr *nle) +@@ -1901,6 +1948,7 @@ static const struct expr_handler netlink + { .name = "tproxy", .parse = netlink_parse_tproxy }, + { .name = "notrack", .parse = netlink_parse_notrack }, + { .name = "masq", .parse = netlink_parse_masq }, ++ { .name = "fullcone", .parse = netlink_parse_fullcone }, + { .name = "redir", .parse = netlink_parse_redir }, + { .name = "dup", .parse = netlink_parse_dup }, + { .name = "queue", .parse = netlink_parse_queue }, +--- a/src/netlink_linearize.c ++++ b/src/netlink_linearize.c +@@ -1221,6 +1221,13 @@ static void netlink_gen_nat_stmt(struct + nftnl_reg_pmin = NFTNL_EXPR_MASQ_REG_PROTO_MIN; + nftnl_reg_pmax = NFTNL_EXPR_MASQ_REG_PROTO_MAX; + break; ++ case NFT_NAT_FULLCONE: ++ nle = alloc_nft_expr("fullcone"); ++ ++ nftnl_flag_attr = NFTNL_EXPR_FULLCONE_FLAGS; ++ nftnl_reg_pmin = NFTNL_EXPR_FULLCONE_REG_PROTO_MIN; ++ nftnl_reg_pmax = NFTNL_EXPR_FULLCONE_REG_PROTO_MAX; ++ break; + case NFT_NAT_REDIR: + nle = alloc_nft_expr("redir"); + +--- a/src/parser_bison.y ++++ b/src/parser_bison.y +@@ -621,6 +621,7 @@ int nft_lex(void *, void *, void *); + %token SNAT "snat" + %token DNAT "dnat" + %token MASQUERADE "masquerade" ++%token FULLCONE "fullcone" + %token REDIRECT "redirect" + %token RANDOM "random" + %token FULLY_RANDOM "fully-random" +@@ -755,8 +756,8 @@ int nft_lex(void *, void *, void *); + %type limit_burst_pkts limit_burst_bytes limit_mode limit_bytes time_unit quota_mode + %type reject_stmt reject_stmt_alloc + %destructor { stmt_free($$); } reject_stmt reject_stmt_alloc +-%type nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc redir_stmt redir_stmt_alloc +-%destructor { stmt_free($$); } nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc redir_stmt redir_stmt_alloc ++%type nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc fullcone_stmt fullcone_stmt_alloc redir_stmt redir_stmt_alloc ++%destructor { stmt_free($$); } nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc fullcone_stmt fullcone_stmt_alloc redir_stmt redir_stmt_alloc + %type nf_nat_flags nf_nat_flag offset_opt + %type tproxy_stmt + %destructor { stmt_free($$); } tproxy_stmt +@@ -3064,6 +3065,7 @@ stmt : verdict_stmt + | queue_stmt + | ct_stmt + | masq_stmt close_scope_nat ++ | fullcone_stmt close_scope_nat + | redir_stmt close_scope_nat + | dup_stmt close_scope_dup + | fwd_stmt close_scope_fwd +@@ -3976,6 +3978,28 @@ masq_stmt_args : TO COLON stmt_expr + { + $0->nat.proto = $3; + } ++ | TO COLON stmt_expr nf_nat_flags ++ { ++ $0->nat.proto = $3; ++ $0->nat.flags = $4; ++ } ++ | nf_nat_flags ++ { ++ $0->nat.flags = $1; ++ } ++ ; ++ ++fullcone_stmt : fullcone_stmt_alloc fullcone_stmt_args ++ | fullcone_stmt_alloc ++ ; ++ ++fullcone_stmt_alloc : FULLCONE { $$ = nat_stmt_alloc(&@$, NFT_NAT_FULLCONE); } ++ ; ++ ++fullcone_stmt_args : TO COLON stmt_expr ++ { ++ $0->nat.proto = $3; ++ } + | TO COLON stmt_expr nf_nat_flags + { + $0->nat.proto = $3; +--- a/src/scanner.l ++++ b/src/scanner.l +@@ -460,6 +460,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr + "snat" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return SNAT; } + "dnat" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return DNAT; } + "masquerade" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return MASQUERADE; } ++"fullcone" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return FULLCONE; } + "redirect" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return REDIRECT; } + "random" { return RANDOM; } + { +--- a/src/statement.c ++++ b/src/statement.c +@@ -681,6 +681,7 @@ const char *nat_etype2str(enum nft_nat_e + [NFT_NAT_SNAT] = "snat", + [NFT_NAT_DNAT] = "dnat", + [NFT_NAT_MASQ] = "masquerade", ++ [NFT_NAT_FULLCONE] = "fullcone", + [NFT_NAT_REDIR] = "redirect", + }; From 5f334cb79b2bf376e71218a76f51cd9e1c101341 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 24 Jan 2023 13:33:05 +0200 Subject: [PATCH 014/225] firmware: add NSS firmware package Qualcomm NSS offloading requires FW binaries in order to operate, so lets package them from the publicly distributable QUIC repository. So far only IPQ8074 is offered, but repo also hosts IPQ5018 and IPQ6018 NSS FW. Signed-off-by: Robert Marko (cherry picked from commit a17fc42332835e6837f06ddb6ef81fc80997bf58) Signed-off-by: bitthief --- package/firmware/nss-firmware/Makefile | 59 ++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 package/firmware/nss-firmware/Makefile diff --git a/package/firmware/nss-firmware/Makefile b/package/firmware/nss-firmware/Makefile new file mode 100644 index 00000000000000..215f2d574d2579 --- /dev/null +++ b/package/firmware/nss-firmware/Makefile @@ -0,0 +1,59 @@ +# +# Copyright (C) 2022 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=nss-firmware +PKG_SOURCE_DATE:=2022-07-12 +PKG_SOURCE_VERSION:=ade6bff594377c9d9c79b45e39bf104303d919bc +PKG_MIRROR_HASH:=af0521893064b7bc52baab263e12c7db5462461ddac30d02647ed76d999b59fb +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/quic/qca-sdk-nss-fw.git + +PKG_LICENSE_FILES:=LICENSE.md + +PKG_MAINTAINER:=Robert Marko + +include $(INCLUDE_DIR)/package.mk + +RSTRIP:=: +STRIP:=: + +VERSION_PATH=$(PKG_BUILD_DIR)/QCA_Networking_2022.SPF_12.0.0/ED1 + +define Package/nss-firmware-default + SECTION:=firmware + CATEGORY:=Firmware + URL:=$(PKG_SOURCE_URL) + DEPENDS:=@TARGET_qualcommax +endef + +define Package/nss-firmware-ipq8074 +$(Package/nss-firmware-default) + TITLE:=IPQ8074 NSS firmware + NSS_ARCHIVE:=$(VERSION_PATH)/IPQ8074.ATH.12.0.0/BIN-NSS.FW.12.1-022-HK.R.tar.bz2 +endef + +define Build/Compile + +endef + +define Package/nss-firmware-ipq8074/install + mkdir -p $(PKG_BUILD_DIR)/IPQ8074 + $(TAR) -C $(PKG_BUILD_DIR)/IPQ8074 -xf $(NSS_ARCHIVE) --strip-components=1 + $(INSTALL_DIR) $(1)/lib/firmware/ + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/IPQ8074/retail_router0.bin \ + $(1)/lib/firmware/qca-nss0-retail.bin + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/IPQ8074/retail_router1.bin \ + $(1)/lib/firmware/qca-nss1-retail.bin +endef + +$(eval $(call BuildPackage,nss-firmware-ipq8074)) From 9f476a7650f296c8fbb7ba448fd8db1d99a05b89 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 24 Jan 2023 13:36:00 +0200 Subject: [PATCH 015/225] package: kernel: add qca-nss-crypto Add the base Qualcomm driver for EIP197 HW in modern QCA WiSoC-s. Signed-off-by: Robert Marko (cherry picked from commit 90b029043cc0ef6d878f9ae66c802b4a46729ed5) Signed-off-by: bitthief --- package/kernel/qca-nss-crypto/Makefile | 70 ++++++++++++++ ...1-nss-crypto-fix-SHA1-header-include.patch | 27 ++++++ ...replace-ioremap_nocache-with-ioremap.patch | 94 +++++++++++++++++++ ...rypto-fix-SHA-header-include-in-5.15.patch | 44 +++++++++ 4 files changed, 235 insertions(+) create mode 100644 package/kernel/qca-nss-crypto/Makefile create mode 100644 package/kernel/qca-nss-crypto/patches/0001-nss-crypto-fix-SHA1-header-include.patch create mode 100644 package/kernel/qca-nss-crypto/patches/0002-nss-crypto-replace-ioremap_nocache-with-ioremap.patch create mode 100644 package/kernel/qca-nss-crypto/patches/0003-nss-crypto-fix-SHA-header-include-in-5.15.patch diff --git a/package/kernel/qca-nss-crypto/Makefile b/package/kernel/qca-nss-crypto/Makefile new file mode 100644 index 00000000000000..5662757944442a --- /dev/null +++ b/package/kernel/qca-nss-crypto/Makefile @@ -0,0 +1,70 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=qca-nss-crypto +PKG_RELEASE:=1 + +PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-crypto.git +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2022-03-20 +PKG_SOURCE_VERSION:=2271a3a66f7e8284d42a9e787ddec6f24a1d2e15 +PKG_MIRROR_HASH:=cd8049f6ab05f5dda6b5d563cf28aad3c3e3160d48214a6773e769e813ba11aa + +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +# v1.0 is for Akronite +# v2.0 is for Hawkeye/Cypress/Maple +ifneq (, $(findstring $(CONFIG_TARGET_SUBTARGET), "ipq807x")) +NSS_CRYPTO_DIR:=v2.0 +else +NSS_CRYPTO_DIR:=v1.0 +endif + +define KernelPackage/qca-nss-crypto + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Cryptographic API modules + DEPENDS:=@TARGET_qualcommax +kmod-qca-nss-drv + TITLE:=Kernel driver for NSS crypto driver + FILES:=$(PKG_BUILD_DIR)/$(NSS_CRYPTO_DIR)/src/qca-nss-crypto.ko \ + $(PKG_BUILD_DIR)/$(NSS_CRYPTO_DIR)/tool/qca-nss-crypto-tool.ko + AUTOLOAD:=$(call AutoProbe,qca-nss-crypto) +endef + +define KernelPackage/qca-nss-crypto/Description +This package contains a NSS crypto driver for QCA chipset +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/qca-nss-crypto + $(CP) $(PKG_BUILD_DIR)/$(NSS_CRYPTO_DIR)/include/* $(1)/usr/include/qca-nss-crypto +endef + +EXTRA_CFLAGS+= \ + -DCONFIG_NSS_DEBUG_LEVEL=4 \ + -I$(STAGING_DIR)/usr/include/qca-nss-crypto \ + -I$(STAGING_DIR)/usr/include/qca-nss-drv \ + -I$(PKG_BUILD_DIR)/$(NSS_CRYPTO_DIR)/include \ + -I$(PKG_BUILD_DIR)/$(NSS_CRYPTO_DIR)/src + +ifeq ($(CONFIG_TARGET_BOARD), "qualcommax") + SOC:=$(CONFIG_TARGET_SUBTARGET) +endif + +define Build/Compile + +$(MAKE) -C "$(LINUX_DIR)" \ + CC="$(TARGET_CC)" \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + ARCH="$(LINUX_KARCH)" \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ + NSS_CRYPTO_DIR=$(NSS_CRYPTO_DIR) \ + SoC=$(SOC) \ + $(KERNEL_MAKE_FLAGS) \ + $(PKG_JOBS) \ + modules +endef + +$(eval $(call KernelPackage,qca-nss-crypto)) diff --git a/package/kernel/qca-nss-crypto/patches/0001-nss-crypto-fix-SHA1-header-include.patch b/package/kernel/qca-nss-crypto/patches/0001-nss-crypto-fix-SHA1-header-include.patch new file mode 100644 index 00000000000000..c9849a2e8d739b --- /dev/null +++ b/package/kernel/qca-nss-crypto/patches/0001-nss-crypto-fix-SHA1-header-include.patch @@ -0,0 +1,27 @@ +From 0c6c593783f2d64a429ad38523661a915aa462fc Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Sun, 13 Mar 2022 13:44:47 +0100 +Subject: [PATCH 1/3] nss-crypto: fix SHA1 header include + +SHA1 header has been merged to the generic SHA one, +and with that the cryptohash.h was dropped. + +So, fix include in kernels 5.8 and newer. + +Signed-off-by: Robert Marko +--- + v2.0/src/nss_crypto_hlos.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/v2.0/src/nss_crypto_hlos.h ++++ b/v2.0/src/nss_crypto_hlos.h +@@ -55,7 +55,9 @@ + #include + #include + #include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0) + #include ++#endif + #include + #include + #include diff --git a/package/kernel/qca-nss-crypto/patches/0002-nss-crypto-replace-ioremap_nocache-with-ioremap.patch b/package/kernel/qca-nss-crypto/patches/0002-nss-crypto-replace-ioremap_nocache-with-ioremap.patch new file mode 100644 index 00000000000000..19454c457b3018 --- /dev/null +++ b/package/kernel/qca-nss-crypto/patches/0002-nss-crypto-replace-ioremap_nocache-with-ioremap.patch @@ -0,0 +1,94 @@ +From 8baa8e747247403c6f814ea5dc3e463c70e0415f Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Tue, 8 Jun 2021 22:14:34 +0200 +Subject: [PATCH 2/3] nss-crypto: replace ioremap_nocache() with ioremap + +ioremap_nocache() was dropped in kernel 5.5 as regular +ioremap() was exactly the same. + +So, simply replace all of the ioremap_nocache() calls +with ioremap(). + +Signed-off-by: Robert Marko +--- + v1.0/src/nss_crypto_dtsi.c | 4 ++-- + v1.0/src/nss_crypto_platform.c | 4 ++-- + v2.0/src/hal/ipq50xx/nss_crypto_ce5.c | 4 ++-- + v2.0/src/hal/ipq60xx/nss_crypto_eip197.c | 2 +- + v2.0/src/hal/ipq807x/nss_crypto_eip197.c | 2 +- + 5 files changed, 8 insertions(+), 8 deletions(-) + +--- a/v1.0/src/nss_crypto_dtsi.c ++++ b/v1.0/src/nss_crypto_dtsi.c +@@ -311,11 +311,11 @@ static int nss_crypto_probe(struct platf + e_ctrl->dev = &pdev->dev; + + e_ctrl->cmd_base = crypto_res.start; +- e_ctrl->crypto_base = ioremap_nocache(e_ctrl->cmd_base, resource_size(&crypto_res)); ++ e_ctrl->crypto_base = ioremap(e_ctrl->cmd_base, resource_size(&crypto_res)); + nss_crypto_assert(e_ctrl->crypto_base); + + e_ctrl->bam_pbase = bam_res.start; +- e_ctrl->bam_base = ioremap_nocache(e_ctrl->bam_pbase, resource_size(&bam_res)); ++ e_ctrl->bam_base = ioremap(e_ctrl->bam_pbase, resource_size(&bam_res)); + nss_crypto_assert(e_ctrl->bam_base); + + e_ctrl->bam_ee = bam_ee; +--- a/v1.0/src/nss_crypto_platform.c ++++ b/v1.0/src/nss_crypto_platform.c +@@ -134,11 +134,11 @@ static int nss_crypto_probe(struct platf + e_ctrl->bam_ee = res->bam_ee; + + e_ctrl->cmd_base = res->crypto_pbase; +- e_ctrl->crypto_base = ioremap_nocache(res->crypto_pbase, res->crypto_pbase_sz); ++ e_ctrl->crypto_base = ioremap(res->crypto_pbase, res->crypto_pbase_sz); + nss_crypto_assert(e_ctrl->crypto_base); + + e_ctrl->bam_pbase = res->bam_pbase; +- e_ctrl->bam_base = ioremap_nocache(res->bam_pbase, res->bam_pbase_sz); ++ e_ctrl->bam_base = ioremap(res->bam_pbase, res->bam_pbase_sz); + nss_crypto_assert(e_ctrl->bam_base); + + /* +--- a/v2.0/src/hal/ipq50xx/nss_crypto_ce5.c ++++ b/v2.0/src/hal/ipq50xx/nss_crypto_ce5.c +@@ -288,7 +288,7 @@ int nss_crypto_ce5_engine_init(struct pl + * remap the I/O addresses for crypto + */ + eng->crypto_paddr = crypto_res->start; +- eng->crypto_vaddr = ioremap_nocache(crypto_res->start, resource_size(crypto_res)); ++ eng->crypto_vaddr = ioremap(crypto_res->start, resource_size(crypto_res)); + if (!eng->crypto_vaddr) { + nss_crypto_warn("%px: unable to remap crypto_addr(0x%px)\n", node, (void *)eng->crypto_paddr); + nss_crypto_engine_free(eng); +@@ -299,7 +299,7 @@ int nss_crypto_ce5_engine_init(struct pl + * remap the I/O addresses for bam + */ + eng->dma_paddr = bam_res->start; +- eng->dma_vaddr = ioremap_nocache(bam_res->start, resource_size(bam_res)); ++ eng->dma_vaddr = ioremap(bam_res->start, resource_size(bam_res)); + if (!eng->dma_vaddr) { + iounmap(eng->crypto_vaddr); + nss_crypto_warn("%px: unable to remap dma_addr(0x%px)\n", node, (void *)eng->dma_paddr); +--- a/v2.0/src/hal/ipq60xx/nss_crypto_eip197.c ++++ b/v2.0/src/hal/ipq60xx/nss_crypto_eip197.c +@@ -490,7 +490,7 @@ int nss_crypto_eip197_engine_init(struct + * remap the I/O addresses + */ + paddr = res->start + offset; +- vaddr = ioremap_nocache(paddr, resource_size(res)); ++ vaddr = ioremap(paddr, resource_size(res)); + if (!vaddr) { + nss_crypto_warn("%px: unable to remap crypto_addr(0x%px)\n", node, (void *)paddr); + return -EIO; +--- a/v2.0/src/hal/ipq807x/nss_crypto_eip197.c ++++ b/v2.0/src/hal/ipq807x/nss_crypto_eip197.c +@@ -490,7 +490,7 @@ int nss_crypto_eip197_engine_init(struct + * remap the I/O addresses + */ + paddr = res->start + offset; +- vaddr = ioremap_nocache(paddr, resource_size(res)); ++ vaddr = ioremap(paddr, resource_size(res)); + if (!vaddr) { + nss_crypto_warn("%px: unable to remap crypto_addr(0x%px)\n", node, (void *)paddr); + return -EIO; diff --git a/package/kernel/qca-nss-crypto/patches/0003-nss-crypto-fix-SHA-header-include-in-5.15.patch b/package/kernel/qca-nss-crypto/patches/0003-nss-crypto-fix-SHA-header-include-in-5.15.patch new file mode 100644 index 00000000000000..61df791fdd7e9d --- /dev/null +++ b/package/kernel/qca-nss-crypto/patches/0003-nss-crypto-fix-SHA-header-include-in-5.15.patch @@ -0,0 +1,44 @@ +From 96da3ca01ac172e5d858209b3d3d9aefad04423c Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Sun, 13 Mar 2022 13:47:24 +0100 +Subject: [PATCH 3/3] nss-crypto: fix SHA header include in 5.15 + +SHA header was split into SHA-1 and SHA-2 headers in kernel 5.11, so +fix the include for newer kernels. + +Signed-off-by: Robert Marko +--- + v2.0/src/nss_crypto_ctrl.c | 6 ++++++ + v2.0/src/nss_crypto_hlos.h | 4 ++++ + 2 files changed, 10 insertions(+) + +--- a/v2.0/src/nss_crypto_ctrl.c ++++ b/v2.0/src/nss_crypto_ctrl.c +@@ -38,7 +38,13 @@ + #include + #include + #include ++#include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) + #include ++#else ++#include ++#include ++#endif + #include + #include + #include +--- a/v2.0/src/nss_crypto_hlos.h ++++ b/v2.0/src/nss_crypto_hlos.h +@@ -58,7 +58,11 @@ + #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0) + #include + #endif ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) + #include ++#else ++#include ++#endif + #include + #include + #include From 05154c9f51aa11e00e5c2c4a377aaf861f2e3048 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 24 Jan 2023 13:38:45 +0200 Subject: [PATCH 016/225] package: kernel: add qca-nss-cfi Add basic version of NSS-CFI registering the EIP197 offloaded algos to the kernel. It still needs to be converted to skcipher for the most interesting algos to work, but hashes work now so lets start with those. Signed-off-by: Robert Marko (cherry picked from commit d3ad6cdc1bcd0c8137f6b353e824ccc37a2cf62c) nss-cfi: convert to skcipher Still crashing though. Signed-off-by: Robert Marko (cherry picked from commit 38216af79a3bfbeaa9022d4e9ee02ba0e61c86ea) Signed-off-by: bitthief --- package/kernel/qca-nss-cfi/Makefile | 87 ++ ...yptoapi-v2.0-fix-SHA1-header-include.patch | 62 + ...ptoapi-v2.0-make-ablkcipher-optional.patch | 116 ++ ...emove-setting-crypto_ahash_type-for-.patch | 137 ++ ...ead-add-downstream-crypto_tfm_alg_fl.patch | 28 + ...-cryptoapi-v2.0-remove-dropped-flags.patch | 97 ++ ...6-cryptoapi-v2.0-convert-to-skcipher.patch | 1199 +++++++++++++++++ 7 files changed, 1726 insertions(+) create mode 100644 package/kernel/qca-nss-cfi/Makefile create mode 100644 package/kernel/qca-nss-cfi/patches/0001-cryptoapi-v2.0-fix-SHA1-header-include.patch create mode 100644 package/kernel/qca-nss-cfi/patches/0002-cryptoapi-v2.0-make-ablkcipher-optional.patch create mode 100644 package/kernel/qca-nss-cfi/patches/0003-cryptoapi-v2.0-remove-setting-crypto_ahash_type-for-.patch create mode 100644 package/kernel/qca-nss-cfi/patches/0004-cryptoapi-v2.0-aead-add-downstream-crypto_tfm_alg_fl.patch create mode 100644 package/kernel/qca-nss-cfi/patches/0005-cryptoapi-v2.0-remove-dropped-flags.patch create mode 100644 package/kernel/qca-nss-cfi/patches/0006-cryptoapi-v2.0-convert-to-skcipher.patch diff --git a/package/kernel/qca-nss-cfi/Makefile b/package/kernel/qca-nss-cfi/Makefile new file mode 100644 index 00000000000000..4841aaa74beff8 --- /dev/null +++ b/package/kernel/qca-nss-cfi/Makefile @@ -0,0 +1,87 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=qca-nss-cfi +PKG_RELEASE:=1 + +PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-cfi.git +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2021-12-14 +PKG_SOURCE_VERSION:=a0239b330846770793aefc3debf4be7edad6ffcd +PKG_MIRROR_HASH:=036bb67b5d497393199958775ea1733a445731d5c5e29c3a8b1e98d49b3721d4 + +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +ifneq (, $(findstring $(CONFIG_TARGET_SUBTARGET), "ipq807x")) +#4.4/5.4 + ipq807x/ipq60xx/ipq50xx + CFI_OCF_DIR:=ocf/v2.0 + CFI_CRYPTOAPI_DIR:=cryptoapi/v2.0 +else +#4.4 Kernel + ipq806x + CFI_CRYPTOAPI_DIR:=cryptoapi/v1.1 + CFI_OCF_DIR:=ocf/v1.0 + CFI_IPSEC_DIR:=ipsec/v1.0 +endif + +define KernelPackage/qca-nss-cfi-cryptoapi + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Cryptographic API modules + DEPENDS:=@TARGET_qualcommax +kmod-qca-nss-crypto +kmod-crypto-authenc + TITLE:=Kernel driver for NSS cfi + FILES:=$(PKG_BUILD_DIR)/$(CFI_CRYPTOAPI_DIR)/qca-nss-cfi-cryptoapi.ko + AUTOLOAD:=$(call AutoLoad,59,qca-nss-cfi-cryptoapi) +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/qca-nss-cfi + $(CP) $(PKG_BUILD_DIR)/$(CFI_CRYPTOAPI_DIR)/../exports/* $(1)/usr/include/qca-nss-cfi + $(CP) $(PKG_BUILD_DIR)/include/* $(1)/usr/include/qca-nss-cfi +endef + +define KernelPackage/qca-nss-cfi/Description +This package contains a NSS cfi driver for QCA chipset +endef + +EXTRA_CFLAGS+= \ + -DCONFIG_NSS_DEBUG_LEVEL=4 \ + -I$(LINUX_DIR)/crypto/ocf \ + -I$(STAGING_DIR)/usr/include/qca-nss-crypto \ + -I$(STAGING_DIR)/usr/include/crypto \ + -I$(STAGING_DIR)/usr/include/qca-nss-drv + +ifneq (, $(findstring $(CONFIG_TARGET_SUBTARGET), "ipq807x")) +EXTRA_CFLAGS+= -I$(STAGING_DIR)/usr/include/qca-nss-clients +endif + +# Build individual packages if selected +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-cfi-cryptoapi),) +MAKE_OPTS+= \ + cryptoapi=y \ + NSS_CRYPTOAPI_ABLK=n \ + NSS_CRYPTOAPI_SKCIPHER=y +endif + +ifeq ($(CONFIG_TARGET_BOARD), "qualcommax") + SOC:=$(CONFIG_TARGET_SUBTARGET) +endif + +define Build/Compile + +$(MAKE) -C "$(LINUX_DIR)" $(strip $(MAKE_OPTS)) \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + ARCH="$(LINUX_KARCH)" \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ + CC="$(TARGET_CC)" \ + CFI_CRYPTOAPI_DIR=$(CFI_CRYPTOAPI_DIR) \ + CFI_OCF_DIR=$(CFI_OCF_DIR) \ + CFI_IPSEC_DIR=$(CFI_IPSEC_DIR) \ + SoC=$(SOC) \ + $(KERNEL_MAKE_FLAGS) \ + $(PKG_JOBS) \ + modules +endef + +$(eval $(call KernelPackage,qca-nss-cfi-cryptoapi)) diff --git a/package/kernel/qca-nss-cfi/patches/0001-cryptoapi-v2.0-fix-SHA1-header-include.patch b/package/kernel/qca-nss-cfi/patches/0001-cryptoapi-v2.0-fix-SHA1-header-include.patch new file mode 100644 index 00000000000000..12df90fdcf7321 --- /dev/null +++ b/package/kernel/qca-nss-cfi/patches/0001-cryptoapi-v2.0-fix-SHA1-header-include.patch @@ -0,0 +1,62 @@ +From 1569ac3b6bbcae9c3f4898e0d34aec8f88297ee6 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Sun, 22 Jan 2023 21:45:23 +0100 +Subject: [PATCH 1/5] cryptoapi: v2.0: fix SHA1 header include + +SHA1 header has been merged to the generic SHA one, +and with that the cryptohash.h was dropped. + +So, fix include in kernels 5.8 and newer. + +Signed-off-by: Robert Marko +--- + cryptoapi/v2.0/nss_cryptoapi.c | 5 +++++ + cryptoapi/v2.0/nss_cryptoapi_aead.c | 5 +++++ + cryptoapi/v2.0/nss_cryptoapi_ahash.c | 5 +++++ + 3 files changed, 15 insertions(+) + +--- a/cryptoapi/v2.0/nss_cryptoapi.c ++++ b/cryptoapi/v2.0/nss_cryptoapi.c +@@ -39,7 +39,12 @@ + + #include + #include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) + #include ++#else ++#include ++#include ++#endif + #include + #include + #include +--- a/cryptoapi/v2.0/nss_cryptoapi_aead.c ++++ b/cryptoapi/v2.0/nss_cryptoapi_aead.c +@@ -39,7 +39,12 @@ + + #include + #include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) + #include ++#else ++#include ++#include ++#endif + #include + #include + #include +--- a/cryptoapi/v2.0/nss_cryptoapi_ahash.c ++++ b/cryptoapi/v2.0/nss_cryptoapi_ahash.c +@@ -38,7 +38,12 @@ + + #include + #include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) + #include ++#else ++#include ++#include ++#endif + #include + #include + #include diff --git a/package/kernel/qca-nss-cfi/patches/0002-cryptoapi-v2.0-make-ablkcipher-optional.patch b/package/kernel/qca-nss-cfi/patches/0002-cryptoapi-v2.0-make-ablkcipher-optional.patch new file mode 100644 index 00000000000000..e9702eb33a7705 --- /dev/null +++ b/package/kernel/qca-nss-cfi/patches/0002-cryptoapi-v2.0-make-ablkcipher-optional.patch @@ -0,0 +1,116 @@ +From 26cca5006bddb0da57398452616e07ee7b11edb1 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Sun, 22 Jan 2023 22:01:34 +0100 +Subject: [PATCH 2/5] cryptoapi: v2.0: make ablkcipher optional + +albkcipher has been removed from the kernel in v5.5, so until it has been +converted to skcipher, lets make it optional to at least have hashes +working. + +Signed-off-by: Robert Marko +--- + cryptoapi/v2.0/Makefile | 3 +++ + cryptoapi/v2.0/nss_cryptoapi.c | 10 ++++++++++ + cryptoapi/v2.0/nss_cryptoapi_private.h | 2 ++ + 3 files changed, 15 insertions(+) + +--- a/cryptoapi/v2.0/Makefile ++++ b/cryptoapi/v2.0/Makefile +@@ -5,7 +5,10 @@ NSS_CRYPTOAPI_MOD_NAME=qca-nss-cfi-crypt + obj-m += $(NSS_CRYPTOAPI_MOD_NAME).o + $(NSS_CRYPTOAPI_MOD_NAME)-objs = nss_cryptoapi.o + $(NSS_CRYPTOAPI_MOD_NAME)-objs += nss_cryptoapi_aead.o ++ifneq "$(NSS_CRYPTOAPI_ABLK)" "n" + $(NSS_CRYPTOAPI_MOD_NAME)-objs += nss_cryptoapi_ablk.o ++ccflags-y += -DNSS_CRYPTOAPI_ABLK ++endif + $(NSS_CRYPTOAPI_MOD_NAME)-objs += nss_cryptoapi_ahash.o + + obj ?= . +--- a/cryptoapi/v2.0/nss_cryptoapi.c ++++ b/cryptoapi/v2.0/nss_cryptoapi.c +@@ -1367,6 +1367,7 @@ struct aead_alg cryptoapi_aead_algs[] = + /* + * ABLK cipher algorithms + */ ++#if defined(NSS_CRYPTOAPI_ABLK) + static struct crypto_alg cryptoapi_ablkcipher_algs[] = { + { + .cra_name = "cbc(aes)", +@@ -1466,6 +1467,7 @@ static struct crypto_alg cryptoapi_ablkc + }, + } + }; ++#endif + + /* + * AHASH algorithms +@@ -2189,7 +2191,9 @@ void nss_cryptoapi_add_ctx2debugfs(struc + */ + void nss_cryptoapi_attach_user(void *app_data, struct nss_crypto_user *user) + { ++#if defined(NSS_CRYPTOAPI_ABLK) + struct crypto_alg *ablk = cryptoapi_ablkcipher_algs; ++#endif + struct aead_alg *aead = cryptoapi_aead_algs; + struct ahash_alg *ahash = cryptoapi_ahash_algs; + struct nss_cryptoapi *sc = app_data; +@@ -2212,6 +2216,7 @@ void nss_cryptoapi_attach_user(void *app + g_cryptoapi.user = user; + } + ++#if defined(NSS_CRYPTOAPI_ABLK) + for (i = 0; enable_ablk && (i < ARRAY_SIZE(cryptoapi_ablkcipher_algs)); i++, ablk++) { + info = nss_cryptoapi_cra_name_lookup(ablk->cra_name); + if(!info || !nss_crypto_algo_is_supp(info->algo)) +@@ -2222,6 +2227,7 @@ void nss_cryptoapi_attach_user(void *app + ablk->cra_flags = 0; + } + } ++#endif + + for (i = 0; enable_aead && (i < ARRAY_SIZE(cryptoapi_aead_algs)); i++, aead++) { + info = nss_cryptoapi_cra_name_lookup(aead->base.cra_name); +@@ -2257,7 +2263,9 @@ void nss_cryptoapi_attach_user(void *app + */ + void nss_cryptoapi_detach_user(void *app_data, struct nss_crypto_user *user) + { ++#if defined(NSS_CRYPTOAPI_ABLK) + struct crypto_alg *ablk = cryptoapi_ablkcipher_algs; ++#endif + struct aead_alg *aead = cryptoapi_aead_algs; + struct ahash_alg *ahash = cryptoapi_ahash_algs; + struct nss_cryptoapi *sc = app_data; +@@ -2270,6 +2278,7 @@ void nss_cryptoapi_detach_user(void *app + */ + atomic_set(&g_cryptoapi.registered, 0); + ++#if defined(NSS_CRYPTOAPI_ABLK) + for (i = 0; enable_ablk && (i < ARRAY_SIZE(cryptoapi_ablkcipher_algs)); i++, ablk++) { + if (!ablk->cra_flags) + continue; +@@ -2277,6 +2286,7 @@ void nss_cryptoapi_detach_user(void *app + crypto_unregister_alg(ablk); + nss_cfi_info("%px: ABLK unregister succeeded, algo: %s\n", sc, ablk->cra_name); + } ++#endif + + for (i = 0; enable_aead && (i < ARRAY_SIZE(cryptoapi_aead_algs)); i++, aead++) { + if (!aead->base.cra_flags) +--- a/cryptoapi/v2.0/nss_cryptoapi_private.h ++++ b/cryptoapi/v2.0/nss_cryptoapi_private.h +@@ -250,12 +250,14 @@ extern void nss_cryptoapi_aead_tx_proc(s + /* + * ABLKCIPHER + */ ++#if defined(NSS_CRYPTOAPI_ABLK) + extern int nss_cryptoapi_ablkcipher_init(struct crypto_tfm *tfm); + extern void nss_cryptoapi_ablkcipher_exit(struct crypto_tfm *tfm); + extern int nss_cryptoapi_ablk_setkey(struct crypto_ablkcipher *cipher, const u8 *key, unsigned int len); + extern int nss_cryptoapi_ablk_encrypt(struct ablkcipher_request *req); + extern int nss_cryptoapi_ablk_decrypt(struct ablkcipher_request *req); + extern void nss_cryptoapi_copy_iv(struct nss_cryptoapi_ctx *ctx, struct scatterlist *sg, uint8_t *iv, uint8_t iv_len); ++#endif + + /* + * AHASH diff --git a/package/kernel/qca-nss-cfi/patches/0003-cryptoapi-v2.0-remove-setting-crypto_ahash_type-for-.patch b/package/kernel/qca-nss-cfi/patches/0003-cryptoapi-v2.0-remove-setting-crypto_ahash_type-for-.patch new file mode 100644 index 00000000000000..ad11b8b35741f0 --- /dev/null +++ b/package/kernel/qca-nss-cfi/patches/0003-cryptoapi-v2.0-remove-setting-crypto_ahash_type-for-.patch @@ -0,0 +1,137 @@ +From 797b5166783cda0886038ffb22f5386b9363a961 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Sun, 22 Jan 2023 22:08:27 +0100 +Subject: [PATCH 3/5] cryptoapi: v2.0: remove setting crypto_ahash_type for + newer kernels + +Upstream has stopped exporting crypto_ahash_type and removed setting it +on ahash algos since v4.19 as its easily identifiable by the struct type +and its being set in the core directly, so lets do the same. + +Signed-off-by: Robert Marko +--- + cryptoapi/v2.0/nss_cryptoapi.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +--- a/cryptoapi/v2.0/nss_cryptoapi.c ++++ b/cryptoapi/v2.0/nss_cryptoapi.c +@@ -1495,7 +1495,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = MD5_HMAC_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, +@@ -1521,7 +1523,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = SHA1_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, +@@ -1547,7 +1551,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = SHA224_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, +@@ -1573,7 +1579,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = SHA256_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, +@@ -1599,7 +1607,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = SHA384_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, +@@ -1625,7 +1635,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = SHA512_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, +@@ -1655,7 +1667,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = MD5_HMAC_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, +@@ -1681,7 +1695,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = SHA1_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, +@@ -1707,7 +1723,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = SHA224_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, +@@ -1733,7 +1751,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = SHA256_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, +@@ -1759,7 +1779,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = SHA384_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, +@@ -1785,7 +1807,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = SHA512_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, diff --git a/package/kernel/qca-nss-cfi/patches/0004-cryptoapi-v2.0-aead-add-downstream-crypto_tfm_alg_fl.patch b/package/kernel/qca-nss-cfi/patches/0004-cryptoapi-v2.0-aead-add-downstream-crypto_tfm_alg_fl.patch new file mode 100644 index 00000000000000..a872321fb3fc98 --- /dev/null +++ b/package/kernel/qca-nss-cfi/patches/0004-cryptoapi-v2.0-aead-add-downstream-crypto_tfm_alg_fl.patch @@ -0,0 +1,28 @@ +From 8db77add1a794bdee8eef0a351e40bf1cdf6dfa9 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Sun, 22 Jan 2023 22:09:51 +0100 +Subject: [PATCH 4/5] cryptoapi: v2.0: aead: add downstream + crypto_tfm_alg_flags + +crypto_tfm_alg_flags newer made it upstream, but as a temporary stopgap +until a better solution is figured out lets add it. + +Signed-off-by: Robert Marko +--- + cryptoapi/v2.0/nss_cryptoapi_aead.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/cryptoapi/v2.0/nss_cryptoapi_aead.c ++++ b/cryptoapi/v2.0/nss_cryptoapi_aead.c +@@ -61,6 +61,11 @@ + #include + #include "nss_cryptoapi_private.h" + ++static inline u32 crypto_tfm_alg_flags(struct crypto_tfm *tfm) ++{ ++ return tfm->__crt_alg->cra_flags & ~CRYPTO_ALG_TYPE_MASK; ++} ++ + /* + * nss_cryptoapi_aead_ctx2session() + * Cryptoapi function to get the session ID for an AEAD diff --git a/package/kernel/qca-nss-cfi/patches/0005-cryptoapi-v2.0-remove-dropped-flags.patch b/package/kernel/qca-nss-cfi/patches/0005-cryptoapi-v2.0-remove-dropped-flags.patch new file mode 100644 index 00000000000000..645633abc53e3c --- /dev/null +++ b/package/kernel/qca-nss-cfi/patches/0005-cryptoapi-v2.0-remove-dropped-flags.patch @@ -0,0 +1,97 @@ +From 62bbb188e1a72d28916e1eca31f4cb9fbbf51cd1 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Sun, 22 Jan 2023 22:11:06 +0100 +Subject: [PATCH 5/5] cryptoapi: v2.0: remove dropped flags + +Upstream has dropped these flags as there was no use for them, so lets do +the same. + +Signed-off-by: Robert Marko +--- + cryptoapi/v2.0/nss_cryptoapi_aead.c | 6 ------ + cryptoapi/v2.0/nss_cryptoapi_ahash.c | 4 ---- + 2 files changed, 10 deletions(-) + +--- a/cryptoapi/v2.0/nss_cryptoapi_aead.c ++++ b/cryptoapi/v2.0/nss_cryptoapi_aead.c +@@ -207,7 +207,6 @@ int nss_cryptoapi_aead_setkey_noauth(str + ctx->info = nss_cryptoapi_cra_name2info(crypto_tfm_alg_name(tfm), keylen, 0); + if (!ctx->info) { + nss_cfi_err("%px: Unable to find algorithm with keylen\n", ctx); +- crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -ENOENT; + } + +@@ -239,7 +238,6 @@ int nss_cryptoapi_aead_setkey_noauth(str + status = nss_crypto_session_alloc(ctx->user, &data, &ctx->sid); + if (status < 0) { + nss_cfi_err("%px: Unable to allocate crypto session(%d)\n", ctx, status); +- crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_FLAGS); + return status; + } + +@@ -271,14 +269,12 @@ int nss_cryptoapi_aead_setkey(struct cry + */ + if (crypto_authenc_extractkeys(&keys, key, keylen) != 0) { + nss_cfi_err("%px: Unable to extract keys\n", ctx); +- crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EIO; + } + + ctx->info = nss_cryptoapi_cra_name2info(crypto_tfm_alg_name(tfm), keys.enckeylen, crypto_aead_maxauthsize(aead)); + if (!ctx->info) { + nss_cfi_err("%px: Unable to find algorithm with keylen\n", ctx); +- crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -ENOENT; + } + +@@ -299,7 +295,6 @@ int nss_cryptoapi_aead_setkey(struct cry + */ + if (keys.authkeylen > ctx->info->auth_blocksize) { + nss_cfi_err("%px: Auth keylen(%d) exceeds supported\n", ctx, keys.authkeylen); +- crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + +@@ -342,7 +337,6 @@ int nss_cryptoapi_aead_setkey(struct cry + status = nss_crypto_session_alloc(ctx->user, &data, &ctx->sid); + if (status < 0) { + nss_cfi_err("%px: Unable to allocate crypto session(%d)\n", ctx, status); +- crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_FLAGS); + return status; + } + +--- a/cryptoapi/v2.0/nss_cryptoapi_ahash.c ++++ b/cryptoapi/v2.0/nss_cryptoapi_ahash.c +@@ -192,7 +192,6 @@ int nss_cryptoapi_ahash_setkey(struct cr + + ctx->info = nss_cryptoapi_cra_name2info(crypto_tfm_alg_name(tfm), 0, crypto_ahash_digestsize(ahash)); + if (!ctx->info) { +- crypto_ahash_set_flags(ahash, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + +@@ -215,7 +214,6 @@ int nss_cryptoapi_ahash_setkey(struct cr + status = nss_crypto_session_alloc(ctx->user, &data, &ctx->sid); + if (status < 0) { + nss_cfi_warn("%px: Unable to allocate crypto session(%d)\n", ctx, status); +- crypto_ahash_set_flags(ahash, CRYPTO_TFM_RES_BAD_FLAGS); + return status; + } + +@@ -299,7 +297,6 @@ int nss_cryptoapi_ahash_init(struct ahas + */ + ctx->info = nss_cryptoapi_cra_name2info(crypto_tfm_alg_name(tfm), 0, 0); + if (!ctx->info) { +- crypto_ahash_set_flags(ahash, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + +@@ -314,7 +311,6 @@ int nss_cryptoapi_ahash_init(struct ahas + status = nss_crypto_session_alloc(ctx->user, &data, &ctx->sid); + if (status < 0) { + nss_cfi_err("%px: Unable to allocate crypto session(%d)\n", ctx, status); +- crypto_ahash_set_flags(ahash, CRYPTO_TFM_RES_BAD_FLAGS); + return status; + } + diff --git a/package/kernel/qca-nss-cfi/patches/0006-cryptoapi-v2.0-convert-to-skcipher.patch b/package/kernel/qca-nss-cfi/patches/0006-cryptoapi-v2.0-convert-to-skcipher.patch new file mode 100644 index 00000000000000..f85e3d892c9be2 --- /dev/null +++ b/package/kernel/qca-nss-cfi/patches/0006-cryptoapi-v2.0-convert-to-skcipher.patch @@ -0,0 +1,1199 @@ +From 1b30927548c2498c76b815b87f604f9a1de40a48 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Sun, 22 Jan 2023 23:31:09 +0100 +Subject: [PATCH] cryptoapi: v2.0: convert to skcipher + +Finally convert the driver from ablkcipher that was dropped in v5.5 to +skcipher. + +Signed-off-by: Robert Marko +--- + cryptoapi/v2.0/Makefile | 6 +- + cryptoapi/v2.0/nss_cryptoapi.c | 200 ++++++++---------- + cryptoapi/v2.0/nss_cryptoapi_private.h | 14 +- + ...ptoapi_ablk.c => nss_cryptoapi_skcipher.c} | 116 +++++----- + 4 files changed, 145 insertions(+), 191 deletions(-) + rename cryptoapi/v2.0/{nss_cryptoapi_ablk.c => nss_cryptoapi_skcipher.c} (74%) + +--- a/cryptoapi/v2.0/Makefile ++++ b/cryptoapi/v2.0/Makefile +@@ -5,9 +5,9 @@ NSS_CRYPTOAPI_MOD_NAME=qca-nss-cfi-crypt + obj-m += $(NSS_CRYPTOAPI_MOD_NAME).o + $(NSS_CRYPTOAPI_MOD_NAME)-objs = nss_cryptoapi.o + $(NSS_CRYPTOAPI_MOD_NAME)-objs += nss_cryptoapi_aead.o +-ifneq "$(NSS_CRYPTOAPI_ABLK)" "n" +-$(NSS_CRYPTOAPI_MOD_NAME)-objs += nss_cryptoapi_ablk.o +-ccflags-y += -DNSS_CRYPTOAPI_ABLK ++ifneq "$(NSS_CRYPTOAPI_SKCIPHER)" "n" ++$(NSS_CRYPTOAPI_MOD_NAME)-objs += nss_cryptoapi_skcipher.o ++ccflags-y += -DNSS_CRYPTOAPI_SKCIPHER + endif + $(NSS_CRYPTOAPI_MOD_NAME)-objs += nss_cryptoapi_ahash.o + +--- a/cryptoapi/v2.0/nss_cryptoapi.c ++++ b/cryptoapi/v2.0/nss_cryptoapi.c +@@ -1367,104 +1367,78 @@ struct aead_alg cryptoapi_aead_algs[] = + /* + * ABLK cipher algorithms + */ +-#if defined(NSS_CRYPTOAPI_ABLK) +-static struct crypto_alg cryptoapi_ablkcipher_algs[] = { ++#if defined(NSS_CRYPTOAPI_SKCIPHER) ++static struct skcipher_alg cryptoapi_skcipher_algs[] = { + { +- .cra_name = "cbc(aes)", +- .cra_driver_name = "nss-cbc-aes", +- .cra_priority = 10000, +- .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, +- .cra_blocksize = AES_BLOCK_SIZE, +- .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), +- .cra_alignmask = 0, +- .cra_type = &crypto_ablkcipher_type, +- .cra_module = THIS_MODULE, +- .cra_init = nss_cryptoapi_ablkcipher_init, +- .cra_exit = nss_cryptoapi_ablkcipher_exit, +- .cra_u = { +- .ablkcipher = { +- .ivsize = AES_BLOCK_SIZE, +- .min_keysize = AES_MIN_KEY_SIZE, +- .max_keysize = AES_MAX_KEY_SIZE, +- .setkey = nss_cryptoapi_ablk_setkey, +- .encrypt = nss_cryptoapi_ablk_encrypt, +- .decrypt = nss_cryptoapi_ablk_decrypt, +- }, +- }, +- }, +- { +- .cra_name = "rfc3686(ctr(aes))", +- .cra_driver_name = "nss-rfc3686-ctr-aes", +- .cra_priority = 30000, +- .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, +- .cra_blocksize = AES_BLOCK_SIZE, +- .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), +- .cra_alignmask = 0, +- .cra_type = &crypto_ablkcipher_type, +- .cra_module = THIS_MODULE, +- .cra_init = nss_cryptoapi_ablkcipher_init, +- .cra_exit = nss_cryptoapi_ablkcipher_exit, +- .cra_u = { +- .ablkcipher = { +- .ivsize = CTR_RFC3686_IV_SIZE, +-/* +- * geniv deprecated from kernel version 5.0 and above +- */ +-#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) +- .geniv = "seqiv", +-#endif +- .min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, +- .max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, +- .setkey = nss_cryptoapi_ablk_setkey, +- .encrypt = nss_cryptoapi_ablk_encrypt, +- .decrypt = nss_cryptoapi_ablk_decrypt, +- }, +- }, +- }, +- { +- .cra_name = "ecb(aes)", +- .cra_driver_name = "nss-ecb-aes", +- .cra_priority = 10000, +- .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, +- .cra_blocksize = AES_BLOCK_SIZE, +- .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), +- .cra_alignmask = 0, +- .cra_type = &crypto_ablkcipher_type, +- .cra_module = THIS_MODULE, +- .cra_init = nss_cryptoapi_ablkcipher_init, +- .cra_exit = nss_cryptoapi_ablkcipher_exit, +- .cra_u = { +- .ablkcipher = { +- .min_keysize = AES_MIN_KEY_SIZE, +- .max_keysize = AES_MAX_KEY_SIZE, +- .setkey = nss_cryptoapi_ablk_setkey, +- .encrypt = nss_cryptoapi_ablk_encrypt, +- .decrypt = nss_cryptoapi_ablk_decrypt, +- }, +- }, +- }, +- { +- .cra_name = "cbc(des3_ede)", +- .cra_driver_name = "nss-cbc-des-ede", +- .cra_priority = 10000, +- .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, +- .cra_blocksize = DES3_EDE_BLOCK_SIZE, +- .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), +- .cra_alignmask = 0, +- .cra_type = &crypto_ablkcipher_type, +- .cra_module = THIS_MODULE, +- .cra_init = nss_cryptoapi_ablkcipher_init, +- .cra_exit = nss_cryptoapi_ablkcipher_exit, +- .cra_u = { +- .ablkcipher = { +- .ivsize = DES3_EDE_BLOCK_SIZE, +- .min_keysize = DES3_EDE_KEY_SIZE, +- .max_keysize = DES3_EDE_KEY_SIZE, +- .setkey = nss_cryptoapi_ablk_setkey, +- .encrypt = nss_cryptoapi_ablk_encrypt, +- .decrypt = nss_cryptoapi_ablk_decrypt, +- }, +- }, ++ .base.cra_name = "cbc(aes)", ++ .base.cra_driver_name = "nss-cbc-aes", ++ .base.cra_priority = 10000, ++ .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_blocksize = AES_BLOCK_SIZE, ++ .base.cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), ++ .base.cra_alignmask = 0, ++ .base.cra_module = THIS_MODULE, ++ .init = nss_cryptoapi_skcipher_init, ++ .exit = nss_cryptoapi_skcipher_exit, ++ .ivsize = AES_BLOCK_SIZE, ++ .min_keysize = AES_MIN_KEY_SIZE, ++ .max_keysize = AES_MAX_KEY_SIZE, ++ .setkey = nss_cryptoapi_skcipher_setkey, ++ .encrypt = nss_cryptoapi_skcipher_encrypt, ++ .decrypt = nss_cryptoapi_skcipher_decrypt, ++ }, ++ { ++ .base.cra_name = "rfc3686(ctr(aes))", ++ .base.cra_driver_name = "nss-rfc3686-ctr-aes", ++ .base.cra_priority = 30000, ++ .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_blocksize = AES_BLOCK_SIZE, ++ .base.cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), ++ .base.cra_alignmask = 0, ++ .base.cra_module = THIS_MODULE, ++ .init = nss_cryptoapi_skcipher_init, ++ .exit = nss_cryptoapi_skcipher_exit, ++ .ivsize = CTR_RFC3686_IV_SIZE, ++ .min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, ++ .max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, ++ .setkey = nss_cryptoapi_skcipher_setkey, ++ .encrypt = nss_cryptoapi_skcipher_encrypt, ++ .decrypt = nss_cryptoapi_skcipher_decrypt, ++ }, ++ { ++ .base.cra_name = "ecb(aes)", ++ .base.cra_driver_name = "nss-ecb-aes", ++ .base.cra_priority = 10000, ++ .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_blocksize = AES_BLOCK_SIZE, ++ .base.cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), ++ .base.cra_alignmask = 0, ++ .base.cra_module = THIS_MODULE, ++ .init = nss_cryptoapi_skcipher_init, ++ .exit = nss_cryptoapi_skcipher_exit, ++ .min_keysize = AES_MIN_KEY_SIZE, ++ .max_keysize = AES_MAX_KEY_SIZE, ++ .setkey = nss_cryptoapi_skcipher_setkey, ++ .encrypt = nss_cryptoapi_skcipher_encrypt, ++ .decrypt = nss_cryptoapi_skcipher_decrypt, ++ }, ++ { ++ .base.cra_name = "cbc(des3_ede)", ++ .base.cra_driver_name = "nss-cbc-des-ede", ++ .base.cra_priority = 10000, ++ .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_blocksize = DES3_EDE_BLOCK_SIZE, ++ .base.cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), ++ .base.cra_alignmask = 0, ++ .base.cra_module = THIS_MODULE, ++ .init = nss_cryptoapi_skcipher_init, ++ .exit = nss_cryptoapi_skcipher_exit, ++ .ivsize = DES3_EDE_BLOCK_SIZE, ++ .min_keysize = DES3_EDE_KEY_SIZE, ++ .max_keysize = DES3_EDE_KEY_SIZE, ++ .setkey = nss_cryptoapi_skcipher_setkey, ++ .encrypt = nss_cryptoapi_skcipher_encrypt, ++ .decrypt = nss_cryptoapi_skcipher_decrypt, + } + }; + #endif +@@ -2215,8 +2189,8 @@ void nss_cryptoapi_add_ctx2debugfs(struc + */ + void nss_cryptoapi_attach_user(void *app_data, struct nss_crypto_user *user) + { +-#if defined(NSS_CRYPTOAPI_ABLK) +- struct crypto_alg *ablk = cryptoapi_ablkcipher_algs; ++#if defined(NSS_CRYPTOAPI_SKCIPHER) ++ struct skcipher_alg *ablk = cryptoapi_skcipher_algs; + #endif + struct aead_alg *aead = cryptoapi_aead_algs; + struct ahash_alg *ahash = cryptoapi_ahash_algs; +@@ -2240,15 +2214,15 @@ void nss_cryptoapi_attach_user(void *app + g_cryptoapi.user = user; + } + +-#if defined(NSS_CRYPTOAPI_ABLK) +- for (i = 0; enable_ablk && (i < ARRAY_SIZE(cryptoapi_ablkcipher_algs)); i++, ablk++) { +- info = nss_cryptoapi_cra_name_lookup(ablk->cra_name); ++#if defined(NSS_CRYPTOAPI_SKCIPHER) ++ for (i = 0; enable_ablk && (i < ARRAY_SIZE(cryptoapi_skcipher_algs)); i++, ablk++) { ++ info = nss_cryptoapi_cra_name_lookup(ablk->base.cra_name); + if(!info || !nss_crypto_algo_is_supp(info->algo)) + continue; + +- if (crypto_register_alg(ablk)) { +- nss_cfi_err("%px: ABLK registration failed(%s)\n", sc, ablk->cra_name); +- ablk->cra_flags = 0; ++ if (crypto_register_skcipher(ablk)) { ++ nss_cfi_err("%px: skcipher registration failed(%s)\n", sc, ablk->base.cra_name); ++ ablk->base.cra_flags = 0; + } + } + #endif +@@ -2287,8 +2261,8 @@ void nss_cryptoapi_attach_user(void *app + */ + void nss_cryptoapi_detach_user(void *app_data, struct nss_crypto_user *user) + { +-#if defined(NSS_CRYPTOAPI_ABLK) +- struct crypto_alg *ablk = cryptoapi_ablkcipher_algs; ++#if defined(NSS_CRYPTOAPI_SKCIPHER) ++ struct skcipher_alg *ablk = cryptoapi_skcipher_algs; + #endif + struct aead_alg *aead = cryptoapi_aead_algs; + struct ahash_alg *ahash = cryptoapi_ahash_algs; +@@ -2302,13 +2276,13 @@ void nss_cryptoapi_detach_user(void *app + */ + atomic_set(&g_cryptoapi.registered, 0); + +-#if defined(NSS_CRYPTOAPI_ABLK) +- for (i = 0; enable_ablk && (i < ARRAY_SIZE(cryptoapi_ablkcipher_algs)); i++, ablk++) { +- if (!ablk->cra_flags) ++#if defined(NSS_CRYPTOAPI_SKCIPHER) ++ for (i = 0; enable_ablk && (i < ARRAY_SIZE(cryptoapi_skcipher_algs)); i++, ablk++) { ++ if (!ablk->base.cra_flags) + continue; + +- crypto_unregister_alg(ablk); +- nss_cfi_info("%px: ABLK unregister succeeded, algo: %s\n", sc, ablk->cra_name); ++ crypto_unregister_skcipher(ablk); ++ nss_cfi_info("%px: skcipher unregister succeeded, algo: %s\n", sc, ablk->base.cra_name); + } + #endif + +--- a/cryptoapi/v2.0/nss_cryptoapi_private.h ++++ b/cryptoapi/v2.0/nss_cryptoapi_private.h +@@ -248,14 +248,14 @@ extern void nss_cryptoapi_aead_tx_proc(s + struct nss_cryptoapi_info *info, bool encrypt); + + /* +- * ABLKCIPHER ++ * SKCIPHER + */ +-#if defined(NSS_CRYPTOAPI_ABLK) +-extern int nss_cryptoapi_ablkcipher_init(struct crypto_tfm *tfm); +-extern void nss_cryptoapi_ablkcipher_exit(struct crypto_tfm *tfm); +-extern int nss_cryptoapi_ablk_setkey(struct crypto_ablkcipher *cipher, const u8 *key, unsigned int len); +-extern int nss_cryptoapi_ablk_encrypt(struct ablkcipher_request *req); +-extern int nss_cryptoapi_ablk_decrypt(struct ablkcipher_request *req); ++#if defined(NSS_CRYPTOAPI_SKCIPHER) ++extern int nss_cryptoapi_skcipher_init(struct crypto_skcipher *tfm); ++extern void nss_cryptoapi_skcipher_exit(struct crypto_skcipher *tfm); ++extern int nss_cryptoapi_skcipher_setkey(struct crypto_skcipher *cipher, const u8 *key, unsigned int len); ++extern int nss_cryptoapi_skcipher_encrypt(struct skcipher_request *req); ++extern int nss_cryptoapi_skcipher_decrypt(struct skcipher_request *req); + extern void nss_cryptoapi_copy_iv(struct nss_cryptoapi_ctx *ctx, struct scatterlist *sg, uint8_t *iv, uint8_t iv_len); + #endif + +--- a/cryptoapi/v2.0/nss_cryptoapi_ablk.c ++++ /dev/null +@@ -1,458 +0,0 @@ +-/* Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. +- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. +- * +- * Permission to use, copy, modify, and/or distribute this software for any +- * purpose with or without fee is hereby granted, provided that the above +- * copyright notice and this permission notice appear in all copies. +- * +- * +- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +- * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT +- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +- * PERFORMANCE OF THIS SOFTWARE. +- * +- * +- */ +- +-/** +- * nss_cryptoapi_ablk.c +- * Interface to communicate Native Linux crypto framework specific data +- * to Crypto core specific data +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include "nss_cryptoapi_private.h" +- +-extern struct nss_cryptoapi g_cryptoapi; +- +-/* +- * nss_cryptoapi_skcipher_ctx2session() +- * Cryptoapi function to get the session ID for an skcipher +- */ +-int nss_cryptoapi_skcipher_ctx2session(struct crypto_skcipher *sk, uint32_t *sid) +-{ +- struct crypto_tfm *tfm = crypto_skcipher_tfm(sk); +- struct crypto_ablkcipher **actx, *ablk; +- struct ablkcipher_tfm *ablk_tfm; +- struct nss_cryptoapi_ctx *ctx; +- +- if (strncmp("nss-", crypto_tfm_alg_driver_name(tfm), 4)) +- return -EINVAL; +- +- /* Get the ablkcipher from the skcipher */ +- actx = crypto_skcipher_ctx(sk); +- if (!actx || !(*actx)) +- return -EINVAL; +- +- /* +- * The ablkcipher now obtained is a wrapper around the actual +- * ablkcipher that is created when the skcipher is created. +- * Hence we derive the required ablkcipher through ablkcipher_tfm. +- */ +- ablk_tfm = crypto_ablkcipher_crt(*actx); +- if (!ablk_tfm) +- return -EINVAL; +- +- ablk = ablk_tfm->base; +- if (!ablk) +- return -EINVAL; +- +- /* Get the nss_cryptoapi context stored in the ablkcipher */ +- ctx = crypto_ablkcipher_ctx(ablk); +- +- BUG_ON(!ctx); +- NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); +- +- *sid = ctx->sid; +- return 0; +-} +-EXPORT_SYMBOL(nss_cryptoapi_skcipher_ctx2session); +- +-/* +- * nss_cryptoapi_ablkcipher_init() +- * Cryptoapi ablkcipher init function. +- */ +-int nss_cryptoapi_ablkcipher_init(struct crypto_tfm *tfm) +-{ +- struct nss_cryptoapi_ctx *ctx = crypto_tfm_ctx(tfm); +- +- BUG_ON(!ctx); +- NSS_CRYPTOAPI_SET_MAGIC(ctx); +- +- memset(ctx, 0, sizeof(struct nss_cryptoapi_ctx)); +- +- ctx->user = g_cryptoapi.user; +- ctx->stats.init++; +- ctx->sid = NSS_CRYPTO_SESSION_MAX; +- init_completion(&ctx->complete); +- +- return 0; +-} +- +-/* +- * nss_cryptoapi_ablkcipher_exit() +- * Cryptoapi ablkcipher exit function. +- */ +-void nss_cryptoapi_ablkcipher_exit(struct crypto_tfm *tfm) +-{ +- struct nss_cryptoapi_ctx *ctx = crypto_tfm_ctx(tfm); +- int ret; +- +- BUG_ON(!ctx); +- NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); +- +- ctx->stats.exit++; +- +- /* +- * When fallback_req is set, it means that fallback tfm was used +- * we didn't create any sessions. +- */ +- if (ctx->fallback_req) { +- ctx->stats.failed_fallback++; +- return; +- } +- +- if (!atomic_read(&ctx->active)) { +- ctx->stats.failed_exit++; +- return; +- } +- +- /* +- * Mark cryptoapi context as inactive +- */ +- atomic_set(&ctx->active, 0); +- +- if (!atomic_sub_and_test(1, &ctx->refcnt)) { +- /* +- * We need to wait for any outstanding packet using this ctx. +- * Once the last packet get processed, reference count will become +- * 0 this ctx. We will wait for the reference to go down to 0. +- */ +- ret = wait_for_completion_timeout(&ctx->complete, NSS_CRYPTOAPI_REQ_TIMEOUT_TICKS); +- WARN_ON(!ret); +- } +- +- if (ctx->sid != NSS_CRYPTO_SESSION_MAX) { +- nss_crypto_session_free(ctx->user, ctx->sid); +- debugfs_remove_recursive(ctx->dentry); +- ctx->sid = NSS_CRYPTO_SESSION_MAX; +- } +- +- NSS_CRYPTOAPI_CLEAR_MAGIC(ctx); +-} +- +-/* +- * nss_cryptoapi_ablk_setkey() +- * Cryptoapi setkey routine for aes. +- */ +-int nss_cryptoapi_ablk_setkey(struct crypto_ablkcipher *cipher, const u8 *key, unsigned int keylen) +-{ +- struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); +- struct nss_cryptoapi_ctx *ctx = crypto_tfm_ctx(tfm); +- struct nss_crypto_session_data data = {0}; +- int status; +- +- /* +- * Validate magic number - init should be called before setkey +- */ +- NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); +- +- ctx->info = nss_cryptoapi_cra_name2info(crypto_tfm_alg_name(tfm), keylen, 0); +- if (!ctx->info) { +- crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN); +- return -EINVAL; +- } +- +- ctx->iv_size = crypto_ablkcipher_ivsize(cipher); +- +- if (ctx->info->cipher_mode == NSS_CRYPTOAPI_CIPHER_MODE_CTR_RFC3686) { +- keylen = keylen - CTR_RFC3686_NONCE_SIZE; +- memcpy(ctx->ctx_iv, key + keylen, CTR_RFC3686_NONCE_SIZE); +- ctx->ctx_iv[3] = ntohl(0x1); +- ctx->iv_size += CTR_RFC3686_NONCE_SIZE + sizeof(uint32_t); +- } +- +- /* +- * Fill NSS crypto session data +- */ +- data.algo = ctx->info->algo; +- data.cipher_key = key; +- +- if (data.algo >= NSS_CRYPTO_CMN_ALGO_MAX) +- return -ERANGE; +- +- if (ctx->sid != NSS_CRYPTO_SESSION_MAX) { +- nss_crypto_session_free(ctx->user, ctx->sid); +- debugfs_remove_recursive(ctx->dentry); +- ctx->sid = NSS_CRYPTO_SESSION_MAX; +- } +- +- status = nss_crypto_session_alloc(ctx->user, &data, &ctx->sid); +- if (status < 0) { +- nss_cfi_err("%px: Unable to allocate crypto session(%d)\n", ctx, status); +- crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_FLAGS); +- return status; +- } +- +- nss_cryptoapi_add_ctx2debugfs(ctx); +- atomic_set(&ctx->active, 1); +- atomic_set(&ctx->refcnt, 1); +- return 0; +-} +- +-/* +- * nss_cryptoapi_ablkcipher_done() +- * Cipher operation completion callback function +- */ +-void nss_cryptoapi_ablkcipher_done(void *app_data, struct nss_crypto_hdr *ch, uint8_t status) +-{ +- struct ablkcipher_request *req = app_data; +- struct nss_cryptoapi_ctx *ctx = crypto_tfm_ctx(req->base.tfm); +- int error; +- +- BUG_ON(!ch); +- +- /* +- * Check cryptoapi context magic number. +- */ +- NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); +- +- /* +- * For skcipher decryption case, the last block of encrypted data is used as +- * an IV for the next data +- */ +- if (ch->op == NSS_CRYPTO_OP_DIR_ENC) { +- nss_cryptoapi_copy_iv(ctx, req->dst, req->info, ch->iv_len); +- } +- +- /* +- * Free crypto hdr +- */ +- nss_crypto_hdr_free(ctx->user, ch); +- +- nss_cfi_dbg("data dump after transformation\n"); +- nss_cfi_dbg_data(sg_virt(req->dst), req->nbytes, ' '); +- +- /* +- * Check if there is any error reported by hardware +- */ +- error = nss_cryptoapi_status2error(ctx, status); +- ctx->stats.completed++; +- +- /* +- * Decrement cryptoapi reference +- */ +- nss_cryptoapi_ref_dec(ctx); +- req->base.complete(&req->base, error); +-} +- +-/* +- * nss_cryptoapi_ablk_encrypt() +- * Crytoapi encrypt for AES and 3DES algorithms. +- */ +-int nss_cryptoapi_ablk_encrypt(struct ablkcipher_request *req) +-{ +- struct nss_cryptoapi_info info = {.op_dir = NSS_CRYPTO_OP_DIR_ENC}; +- struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(req); +- struct nss_cryptoapi_ctx *ctx = crypto_ablkcipher_ctx(cipher); +- struct crypto_tfm *tfm = req->base.tfm; +- struct scatterlist *cur; +- int tot_len = 0; +- int i; +- +- /* +- * Check cryptoapi context magic number. +- */ +- NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); +- +- /* +- * Check if cryptoapi context is active or not +- */ +- if (!atomic_read(&ctx->active)) +- return -EINVAL; +- +- if (sg_nents(req->src) != sg_nents(req->dst)) { +- ctx->stats.failed_req++; +- return -EINVAL; +- } +- +- /* +- * Block size not aligned. +- * AES-CTR requires only a one-byte block size alignment. +- */ +- if (!IS_ALIGNED(req->nbytes, crypto_tfm_alg_blocksize(tfm)) && ctx->info->blk_align) { +- ctx->stats.failed_align++; +- crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_BLOCK_LEN); +- return -EFAULT; +- } +- +- /* +- * Fill the request information structure +- */ +- info.iv = req->info; +- info.src.nsegs = sg_nents(req->src); +- info.dst.nsegs = sg_nents(req->dst); +- info.op_dir = NSS_CRYPTO_OP_DIR_ENC; +- info.cb = nss_cryptoapi_ablkcipher_done; +- info.iv_size = ctx->iv_size; +- info.src.first_sg = req->src; +- info.dst.first_sg = req->dst; +- info.dst.last_sg = sg_last(req->dst, info.dst.nsegs); +- +- /* out and in length will be same as ablk does only encrypt/decryt operation */ +- info.total_in_len = info.total_out_len = req->nbytes; +- info.in_place = (req->src == req->dst) ? true : false; +- +- /* +- * The exact length of data that needs to be ciphered for an ABLK +- * request is stored in req->nbytes. Hence we may have to reduce +- * the DMA length to what is specified in req->nbytes and later +- * restore the length of scatterlist back to its original value. +- */ +- for_each_sg(req->src, cur, info.src.nsegs, i) { +- if (!cur) +- break; +- +- tot_len += cur->length; +- if (!sg_next(cur)) +- break; +- } +- +- /* +- * We only support (2^16 - 1) length. +- */ +- if (tot_len > U16_MAX) { +- ctx->stats.failed_len++; +- return -EFBIG; +- } +- +- info.src.last_sg = cur; +- info.ahash_skip = tot_len - req->nbytes; +- +- if (!atomic_inc_not_zero(&ctx->refcnt)) +- return -ENOENT; +- +- return nss_cryptoapi_transform(ctx, &info, (void *)req, false); +-} +- +-/* +- * nss_cryptoapi_ablk_decrypt() +- * Crytoapi decrypt for AES and 3DES CBC algorithms. +- */ +-int nss_cryptoapi_ablk_decrypt(struct ablkcipher_request *req) +-{ +- struct nss_cryptoapi_info info = {.op_dir = NSS_CRYPTO_OP_DIR_DEC}; +- struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(req); +- struct nss_cryptoapi_ctx *ctx = crypto_ablkcipher_ctx(cipher); +- struct crypto_tfm *tfm = req->base.tfm; +- struct scatterlist *cur; +- int tot_len = 0; +- int i; +- +- /* +- * Check cryptoapi context magic number. +- */ +- NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); +- +- /* +- * Check if cryptoapi context is active or not +- */ +- if (!atomic_read(&ctx->active)) +- return -EINVAL; +- +- if (sg_nents(req->src) != sg_nents(req->dst)) { +- ctx->stats.failed_req++; +- return -EINVAL; +- } +- +- /* +- * Block size not aligned +- */ +- if (!IS_ALIGNED(req->nbytes, crypto_tfm_alg_blocksize(tfm)) && ctx->info->blk_align) { +- ctx->stats.failed_align++; +- crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_BLOCK_LEN); +- return -EFAULT; +- } +- +- /* +- * Fill the request information structure +- * Note: For CTR mode, IV size will be set to AES_BLOCK_SIZE. +- * This is because linux gives iv size as 8 while we need to alloc 16 bytes +- * in crypto hdr to accomodate +- * - 4 bytes of nonce +- * - 8 bytes of IV +- * - 4 bytes of initial counter +- */ +- info.iv = req->info; +- info.src.nsegs = sg_nents(req->src); +- info.dst.nsegs = sg_nents(req->dst); +- info.iv_size = ctx->iv_size; +- info.op_dir = NSS_CRYPTO_OP_DIR_DEC; +- info.cb = nss_cryptoapi_ablkcipher_done; +- info.src.first_sg = req->src; +- info.dst.first_sg = req->dst; +- info.dst.last_sg = sg_last(req->dst, info.dst.nsegs); +- +- /* out and in length will be same as ablk does only encrypt/decryt operation */ +- info.total_in_len = info.total_out_len = req->nbytes; +- info.in_place = (req->src == req->dst) ? true : false; +- +- /* +- * The exact length of data that needs to be ciphered for an ABLK +- * request is stored in req->nbytes. Hence we may have to reduce +- * the DMA length to what is specified in req->nbytes and later +- * restore the length of scatterlist back to its original value. +- */ +- for_each_sg(req->src, cur, info.src.nsegs, i) { +- tot_len += cur->length; +- if (!sg_next(cur)) +- break; +- } +- +- /* +- * We only support (2^16 - 1) length. +- */ +- if (tot_len > U16_MAX) { +- ctx->stats.failed_len++; +- return -EFBIG; +- } +- +- info.ahash_skip = tot_len - req->nbytes; +- info.src.last_sg = cur; +- +- if (!atomic_inc_not_zero(&ctx->refcnt)) +- return -ENOENT; +- +- return nss_cryptoapi_transform(ctx, &info, (void *)req, false); +-} +--- /dev/null ++++ b/cryptoapi/v2.0/nss_cryptoapi_skcipher.c +@@ -0,0 +1,438 @@ ++/* Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ++ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT ++ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ++ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ++ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ++ * PERFORMANCE OF THIS SOFTWARE. ++ * ++ * ++ */ ++ ++/** ++ * nss_cryptoapi_ablk.c ++ * Interface to communicate Native Linux crypto framework specific data ++ * to Crypto core specific data ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) ++#include ++#else ++#include ++#include ++#endif ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "nss_cryptoapi_private.h" ++ ++extern struct nss_cryptoapi g_cryptoapi; ++ ++/* ++ * nss_cryptoapi_skcipher_ctx2session() ++ * Cryptoapi function to get the session ID for an skcipher ++ */ ++int nss_cryptoapi_skcipher_ctx2session(struct crypto_skcipher *sk, uint32_t *sid) ++{ ++ struct crypto_tfm *tfm = crypto_skcipher_tfm(sk); ++ struct nss_cryptoapi_ctx *ctx; ++ ++ if (strncmp("nss-", crypto_tfm_alg_driver_name(tfm), 4)) ++ return -EINVAL; ++ ++ /* Get the nss_cryptoapi context stored in skcipher */ ++ ctx = crypto_skcipher_ctx(sk); ++ BUG_ON(!ctx); ++ NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); ++ ++ *sid = ctx->sid; ++ return 0; ++} ++EXPORT_SYMBOL(nss_cryptoapi_skcipher_ctx2session); ++ ++/* ++ * nss_cryptoapi_skcipher_init() ++ * Cryptoapi skcipher init function. ++ */ ++int nss_cryptoapi_skcipher_init(struct crypto_skcipher *tfm) ++{ ++ struct nss_cryptoapi_ctx *ctx = crypto_skcipher_ctx(tfm); ++ ++ BUG_ON(!ctx); ++ NSS_CRYPTOAPI_SET_MAGIC(ctx); ++ ++ memset(ctx, 0, sizeof(struct nss_cryptoapi_ctx)); ++ ++ ctx->user = g_cryptoapi.user; ++ ctx->stats.init++; ++ ctx->sid = NSS_CRYPTO_SESSION_MAX; ++ init_completion(&ctx->complete); ++ ++ return 0; ++} ++ ++/* ++ * nss_cryptoapi_skcipher_exit() ++ * Cryptoapi skcipher exit function. ++ */ ++void nss_cryptoapi_skcipher_exit(struct crypto_skcipher *tfm) ++{ ++ struct nss_cryptoapi_ctx *ctx = crypto_skcipher_ctx(tfm); ++ int ret; ++ ++ BUG_ON(!ctx); ++ NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); ++ ++ ctx->stats.exit++; ++ ++ /* ++ * When fallback_req is set, it means that fallback tfm was used ++ * we didn't create any sessions. ++ */ ++ if (ctx->fallback_req) { ++ ctx->stats.failed_fallback++; ++ return; ++ } ++ ++ if (!atomic_read(&ctx->active)) { ++ ctx->stats.failed_exit++; ++ return; ++ } ++ ++ /* ++ * Mark cryptoapi context as inactive ++ */ ++ atomic_set(&ctx->active, 0); ++ ++ if (!atomic_sub_and_test(1, &ctx->refcnt)) { ++ /* ++ * We need to wait for any outstanding packet using this ctx. ++ * Once the last packet get processed, reference count will become ++ * 0 this ctx. We will wait for the reference to go down to 0. ++ */ ++ ret = wait_for_completion_timeout(&ctx->complete, NSS_CRYPTOAPI_REQ_TIMEOUT_TICKS); ++ WARN_ON(!ret); ++ } ++ ++ if (ctx->sid != NSS_CRYPTO_SESSION_MAX) { ++ nss_crypto_session_free(ctx->user, ctx->sid); ++ debugfs_remove_recursive(ctx->dentry); ++ ctx->sid = NSS_CRYPTO_SESSION_MAX; ++ } ++ ++ NSS_CRYPTOAPI_CLEAR_MAGIC(ctx); ++} ++ ++/* ++ * nss_cryptoapi_skcipher_setkey() ++ * Cryptoapi setkey routine for aes. ++ */ ++int nss_cryptoapi_skcipher_setkey(struct crypto_skcipher *cipher, const u8 *key, unsigned int keylen) ++{ ++ struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); ++ struct nss_cryptoapi_ctx *ctx = crypto_skcipher_ctx(cipher); ++ struct nss_crypto_session_data data = {0}; ++ int status; ++ ++ /* ++ * Validate magic number - init should be called before setkey ++ */ ++ NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); ++ ++ ctx->info = nss_cryptoapi_cra_name2info(crypto_tfm_alg_name(tfm), keylen, 0); ++ if (!ctx->info) { ++ return -EINVAL; ++ } ++ ++ ctx->iv_size = crypto_skcipher_ivsize(cipher); ++ ++ if (ctx->info->cipher_mode == NSS_CRYPTOAPI_CIPHER_MODE_CTR_RFC3686) { ++ keylen = keylen - CTR_RFC3686_NONCE_SIZE; ++ memcpy(ctx->ctx_iv, key + keylen, CTR_RFC3686_NONCE_SIZE); ++ ctx->ctx_iv[3] = ntohl(0x1); ++ ctx->iv_size += CTR_RFC3686_NONCE_SIZE + sizeof(uint32_t); ++ } ++ ++ /* ++ * Fill NSS crypto session data ++ */ ++ data.algo = ctx->info->algo; ++ data.cipher_key = key; ++ ++ if (data.algo >= NSS_CRYPTO_CMN_ALGO_MAX) ++ return -ERANGE; ++ ++ if (ctx->sid != NSS_CRYPTO_SESSION_MAX) { ++ nss_crypto_session_free(ctx->user, ctx->sid); ++ debugfs_remove_recursive(ctx->dentry); ++ ctx->sid = NSS_CRYPTO_SESSION_MAX; ++ } ++ ++ status = nss_crypto_session_alloc(ctx->user, &data, &ctx->sid); ++ if (status < 0) { ++ nss_cfi_err("%px: Unable to allocate crypto session(%d)\n", ctx, status); ++ return status; ++ } ++ ++ nss_cryptoapi_add_ctx2debugfs(ctx); ++ atomic_set(&ctx->active, 1); ++ atomic_set(&ctx->refcnt, 1); ++ return 0; ++} ++ ++/* ++ * nss_cryptoapi_skcipher_done() ++ * Cipher operation completion callback function ++ */ ++void nss_cryptoapi_skcipher_done(void *app_data, struct nss_crypto_hdr *ch, uint8_t status) ++{ ++ struct skcipher_request *req = app_data; ++ struct nss_cryptoapi_ctx *ctx = skcipher_request_ctx(req); ++ int error; ++ ++ BUG_ON(!ch); ++ ++ /* ++ * Check cryptoapi context magic number. ++ */ ++ NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); ++ ++ /* ++ * For skcipher decryption case, the last block of encrypted data is used as ++ * an IV for the next data ++ */ ++ if (ch->op == NSS_CRYPTO_OP_DIR_ENC) { ++ nss_cryptoapi_copy_iv(ctx, req->dst, req->iv, ch->iv_len); ++ } ++ ++ /* ++ * Free crypto hdr ++ */ ++ nss_crypto_hdr_free(ctx->user, ch); ++ ++ nss_cfi_dbg("data dump after transformation\n"); ++ nss_cfi_dbg_data(sg_virt(req->dst), req->cryptlen, ' '); ++ ++ /* ++ * Check if there is any error reported by hardware ++ */ ++ error = nss_cryptoapi_status2error(ctx, status); ++ ctx->stats.completed++; ++ ++ /* ++ * Decrement cryptoapi reference ++ */ ++ nss_cryptoapi_ref_dec(ctx); ++ req->base.complete(&req->base, error); ++} ++ ++/* ++ * nss_cryptoapi_skcipher_encrypt() ++ * Crytoapi encrypt for AES and 3DES algorithms. ++ */ ++int nss_cryptoapi_skcipher_encrypt(struct skcipher_request *req) ++{ ++ struct nss_cryptoapi_info info = {.op_dir = NSS_CRYPTO_OP_DIR_ENC}; ++ struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req); ++ struct nss_cryptoapi_ctx *ctx = crypto_skcipher_ctx(cipher); ++ struct crypto_tfm *tfm = req->base.tfm; ++ struct scatterlist *cur; ++ int tot_len = 0; ++ int i; ++ ++ /* ++ * Check cryptoapi context magic number. ++ */ ++ NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); ++ ++ /* ++ * Check if cryptoapi context is active or not ++ */ ++ if (!atomic_read(&ctx->active)) ++ return -EINVAL; ++ ++ if (sg_nents(req->src) != sg_nents(req->dst)) { ++ ctx->stats.failed_req++; ++ return -EINVAL; ++ } ++ ++ /* ++ * Block size not aligned. ++ * AES-CTR requires only a one-byte block size alignment. ++ */ ++ if (!IS_ALIGNED(req->cryptlen, crypto_tfm_alg_blocksize(tfm)) && ctx->info->blk_align) { ++ ctx->stats.failed_align++; ++ return -EFAULT; ++ } ++ ++ /* ++ * Fill the request information structure ++ */ ++ info.iv = req->iv; ++ info.src.nsegs = sg_nents(req->src); ++ info.dst.nsegs = sg_nents(req->dst); ++ info.op_dir = NSS_CRYPTO_OP_DIR_ENC; ++ info.cb = nss_cryptoapi_skcipher_done; ++ info.iv_size = ctx->iv_size; ++ info.src.first_sg = req->src; ++ info.dst.first_sg = req->dst; ++ info.dst.last_sg = sg_last(req->dst, info.dst.nsegs); ++ ++ /* out and in length will be same as ablk does only encrypt/decryt operation */ ++ info.total_in_len = info.total_out_len = req->cryptlen; ++ info.in_place = (req->src == req->dst) ? true : false; ++ ++ /* ++ * The exact length of data that needs to be ciphered for an ABLK ++ * request is stored in req->cryptlen. Hence we may have to reduce ++ * the DMA length to what is specified in req->cryptlen and later ++ * restore the length of scatterlist back to its original value. ++ */ ++ for_each_sg(req->src, cur, info.src.nsegs, i) { ++ if (!cur) ++ break; ++ ++ tot_len += cur->length; ++ if (!sg_next(cur)) ++ break; ++ } ++ ++ /* ++ * We only support (2^16 - 1) length. ++ */ ++ if (tot_len > U16_MAX) { ++ ctx->stats.failed_len++; ++ return -EFBIG; ++ } ++ ++ info.src.last_sg = cur; ++ info.ahash_skip = tot_len - req->cryptlen; ++ ++ if (!atomic_inc_not_zero(&ctx->refcnt)) ++ return -ENOENT; ++ ++ return nss_cryptoapi_transform(ctx, &info, (void *)req, false); ++} ++ ++/* ++ * nss_cryptoapi_skcipher_decrypt() ++ * Crytoapi decrypt for AES and 3DES CBC algorithms. ++ */ ++int nss_cryptoapi_skcipher_decrypt(struct skcipher_request *req) ++{ ++ struct nss_cryptoapi_info info = {.op_dir = NSS_CRYPTO_OP_DIR_DEC}; ++ struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req); ++ struct nss_cryptoapi_ctx *ctx = crypto_skcipher_ctx(cipher); ++ struct crypto_tfm *tfm = req->base.tfm; ++ struct scatterlist *cur; ++ int tot_len = 0; ++ int i; ++ ++ /* ++ * Check cryptoapi context magic number. ++ */ ++ NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); ++ ++ /* ++ * Check if cryptoapi context is active or not ++ */ ++ if (!atomic_read(&ctx->active)) ++ return -EINVAL; ++ ++ if (sg_nents(req->src) != sg_nents(req->dst)) { ++ ctx->stats.failed_req++; ++ return -EINVAL; ++ } ++ ++ /* ++ * Block size not aligned ++ */ ++ if (!IS_ALIGNED(req->cryptlen, crypto_tfm_alg_blocksize(tfm)) && ctx->info->blk_align) { ++ ctx->stats.failed_align++; ++ return -EFAULT; ++ } ++ ++ /* ++ * Fill the request information structure ++ * Note: For CTR mode, IV size will be set to AES_BLOCK_SIZE. ++ * This is because linux gives iv size as 8 while we need to alloc 16 bytes ++ * in crypto hdr to accomodate ++ * - 4 bytes of nonce ++ * - 8 bytes of IV ++ * - 4 bytes of initial counter ++ */ ++ info.iv = req->iv; ++ info.src.nsegs = sg_nents(req->src); ++ info.dst.nsegs = sg_nents(req->dst); ++ info.iv_size = ctx->iv_size; ++ info.op_dir = NSS_CRYPTO_OP_DIR_DEC; ++ info.cb = nss_cryptoapi_skcipher_done; ++ info.src.first_sg = req->src; ++ info.dst.first_sg = req->dst; ++ info.dst.last_sg = sg_last(req->dst, info.dst.nsegs); ++ ++ /* out and in length will be same as ablk does only encrypt/decryt operation */ ++ info.total_in_len = info.total_out_len = req->cryptlen; ++ info.in_place = (req->src == req->dst) ? true : false; ++ ++ /* ++ * The exact length of data that needs to be ciphered for an ABLK ++ * request is stored in req->cryptlen. Hence we may have to reduce ++ * the DMA length to what is specified in req->cryptlen and later ++ * restore the length of scatterlist back to its original value. ++ */ ++ for_each_sg(req->src, cur, info.src.nsegs, i) { ++ tot_len += cur->length; ++ if (!sg_next(cur)) ++ break; ++ } ++ ++ /* ++ * We only support (2^16 - 1) length. ++ */ ++ if (tot_len > U16_MAX) { ++ ctx->stats.failed_len++; ++ return -EFBIG; ++ } ++ ++ info.ahash_skip = tot_len - req->cryptlen; ++ info.src.last_sg = cur; ++ ++ if (!atomic_inc_not_zero(&ctx->refcnt)) ++ return -ENOENT; ++ ++ return nss_cryptoapi_transform(ctx, &info, (void *)req, false); ++} From 77d75bba7b70a7522de5912d8d0b8ccc30dd1fb6 Mon Sep 17 00:00:00 2001 From: bitthief Date: Sat, 4 Feb 2023 01:30:08 +0200 Subject: [PATCH 017/225] package: kernel: nat46: patches for QCA NSS ECM Signed-off-by: bitthief --- package/kernel/nat46/Makefile | 16 +- .../nat46/patches/100-kernel-5.4-compat.patch | 34 + .../kernel/nat46/patches/101-skb-reset.patch | 30 + package/kernel/nat46/patches/102-mapt.patch | 199 ++++++ package/kernel/nat46/patches/103-tos.patch | 56 ++ package/kernel/nat46/patches/104-icmp.patch | 440 ++++++++++++ .../patches/105-longest-prefix-match.patch | 639 ++++++++++++++++++ .../nat46/patches/106-dummy_header.patch | 100 +++ package/kernel/nat46/patches/107-stats.patch | 134 ++++ .../kernel/nat46/patches/108-ce_port.patch | 134 ++++ ...agment_if_not_df_and_larger_than_mtu.patch | 30 + .../patches/110-icmp_error_not_handled.patch | 99 +++ .../111-fix_null_point_reference.patch | 40 ++ .../nat46/patches/112-fix_icmp_crash.patch | 40 ++ .../113-fix_delete_race_condition.patch | 52 ++ ...114-fix-get-release-instance-protect.patch | 51 ++ .../115-export-ip6_update_csm-api.patch | 33 + .../patches/116-rate-limit-the-print.patch | 34 + .../patches/117-fix-icmp-no-payload-bug.patch | 34 + ...7-fix-proc_create-to-file_operations.patch | 43 ++ .../nat46/patches/118-add-nat46_remove.patch | 80 +++ .../119-upgrade-alloc_nat46_instance.patch | 56 ++ ...ayload-length-wrong-in-fragment-case.patch | 144 ++++ .../17-add-support-ipv6-udp-checksum-0.patch | 32 + 24 files changed, 2546 insertions(+), 4 deletions(-) create mode 100644 package/kernel/nat46/patches/100-kernel-5.4-compat.patch create mode 100644 package/kernel/nat46/patches/101-skb-reset.patch create mode 100644 package/kernel/nat46/patches/102-mapt.patch create mode 100644 package/kernel/nat46/patches/103-tos.patch create mode 100644 package/kernel/nat46/patches/104-icmp.patch create mode 100644 package/kernel/nat46/patches/105-longest-prefix-match.patch create mode 100644 package/kernel/nat46/patches/106-dummy_header.patch create mode 100644 package/kernel/nat46/patches/107-stats.patch create mode 100644 package/kernel/nat46/patches/108-ce_port.patch create mode 100644 package/kernel/nat46/patches/109-fragment_if_not_df_and_larger_than_mtu.patch create mode 100644 package/kernel/nat46/patches/110-icmp_error_not_handled.patch create mode 100644 package/kernel/nat46/patches/111-fix_null_point_reference.patch create mode 100644 package/kernel/nat46/patches/112-fix_icmp_crash.patch create mode 100644 package/kernel/nat46/patches/113-fix_delete_race_condition.patch create mode 100644 package/kernel/nat46/patches/114-fix-get-release-instance-protect.patch create mode 100644 package/kernel/nat46/patches/115-export-ip6_update_csm-api.patch create mode 100644 package/kernel/nat46/patches/116-rate-limit-the-print.patch create mode 100644 package/kernel/nat46/patches/117-fix-icmp-no-payload-bug.patch create mode 100644 package/kernel/nat46/patches/117-fix-proc_create-to-file_operations.patch create mode 100644 package/kernel/nat46/patches/118-add-nat46_remove.patch create mode 100644 package/kernel/nat46/patches/119-upgrade-alloc_nat46_instance.patch create mode 100644 package/kernel/nat46/patches/16-fix-l3_payload-length-wrong-in-fragment-case.patch create mode 100644 package/kernel/nat46/patches/17-add-support-ipv6-udp-checksum-0.patch diff --git a/package/kernel/nat46/Makefile b/package/kernel/nat46/Makefile index 5e5efbe101a713..55488550ef03c1 100644 --- a/package/kernel/nat46/Makefile +++ b/package/kernel/nat46/Makefile @@ -3,15 +3,17 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=nat46 -PKG_MIRROR_HASH:=aeff95aa278ec1e197b59700284c0210f32b92c1fb757e5c3088bd00b3b403d4 +PKG_MIRROR_HASH:=0627c7122ff7432aadb443e92e11a9ad7710add0ff512eebe17d7e3c041e0d2a PKG_SOURCE_URL:=https://github.com/ayourtch/nat46.git -PKG_SOURCE_DATE:=2022-09-19 +PKG_SOURCE_DATE:=2020-06-26 PKG_SOURCE_PROTO:=git -PKG_SOURCE_VERSION:=4c5beee236841724219598fabb1edc93d4f08ce5 +PKG_SOURCE_VERSION:=1182f30785e4274913f01a8c3d7e1b5437ae3819 PKG_MAINTAINER:=Hans Dedecker PKG_LICENSE:=GPL-2.0 +PKG_BUILD_PARALLEL:=1 + include $(INCLUDE_DIR)/package.mk define KernelPackage/nat46 @@ -25,11 +27,17 @@ endef include $(INCLUDE_DIR)/kernel-defaults.mk +define Build/InstallDev + mkdir -p -m 0777 $(STAGING_DIR)/usr/include/nat46 + $(CP) $(PKG_BUILD_DIR)/nat46/modules/*.h $(STAGING_DIR)/usr/include/nat46/ +endef + define Build/Compile - $(KERNEL_MAKE) M="$(PKG_BUILD_DIR)/nat46/modules" \ + +$(KERNEL_MAKE) M="$(PKG_BUILD_DIR)/nat46/modules" \ MODFLAGS="-DMODULE -mlong-calls" \ EXTRA_CFLAGS="-DNAT46_VERSION=\\\"$(PKG_SOURCE_VERSION)\\\"" \ modules + cp $(PKG_BUILD_DIR)/nat46/modules/Module.symvers $(PKG_BUILD_DIR)/Module.symvers endef $(eval $(call KernelPackage,nat46)) diff --git a/package/kernel/nat46/patches/100-kernel-5.4-compat.patch b/package/kernel/nat46/patches/100-kernel-5.4-compat.patch new file mode 100644 index 00000000000000..6a638e96b5ad67 --- /dev/null +++ b/package/kernel/nat46/patches/100-kernel-5.4-compat.patch @@ -0,0 +1,34 @@ +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -17,6 +17,7 @@ + */ + + #include ++#include + + #include "nat46-glue.h" + #include "nat46-core.h" +@@ -1601,7 +1602,11 @@ void nat46_ipv6_input(struct sk_buff *ol + /* Remove any debris in the socket control block */ + memset(IPCB(new_skb), 0, sizeof(struct inet_skb_parm)); + /* Remove netfilter references to IPv6 packet, new netfilter references will be created based on IPv4 packet */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) + nf_reset(new_skb); ++#else ++ nf_reset_ct(new_skb); ++#endif + + /* modify packet: actual IPv6->IPv4 transformation */ + truncSize = v6packet_l3size - sizeof(struct iphdr); /* chop first 20 bytes */ +@@ -1806,7 +1811,11 @@ void nat46_ipv4_input(struct sk_buff *ol + /* Remove any debris in the socket control block */ + memset(IPCB(new_skb), 0, sizeof(struct inet_skb_parm)); + /* Remove netfilter references to IPv4 packet, new netfilter references will be created based on IPv6 packet */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) + nf_reset(new_skb); ++#else ++ nf_reset_ct(new_skb); ++#endif + + /* expand header (add 20 extra bytes at the beginning of sk_buff) */ + pskb_expand_head(new_skb, IPV6V4HDRDELTA + (add_frag_header?8:0), 0, GFP_ATOMIC); diff --git a/package/kernel/nat46/patches/101-skb-reset.patch b/package/kernel/nat46/patches/101-skb-reset.patch new file mode 100644 index 00000000000000..928b048bb19da5 --- /dev/null +++ b/package/kernel/nat46/patches/101-skb-reset.patch @@ -0,0 +1,30 @@ +Author: Pavithra R +Date: Sun Sep 20 13:33:42 2020 +0530 + +nat46: Add skb_ext_reset to reset skb extensions + +This patch adds support to reset the skb extensions before +resetting the netfilter. Without the change, conntrack +is in invalid state and traffic gets dropped. + +Change-Id: I24ee6fe8a9a9dec09d61d8e716fff587f65e4e4f +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -1605,6 +1605,7 @@ void nat46_ipv6_input(struct sk_buff *ol + #if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) + nf_reset(new_skb); + #else ++ skb_ext_reset(new_skb); + nf_reset_ct(new_skb); + #endif + +@@ -1814,6 +1815,7 @@ void nat46_ipv4_input(struct sk_buff *ol + #if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) + nf_reset(new_skb); + #else ++ skb_ext_reset(new_skb); + nf_reset_ct(new_skb); + #endif + diff --git a/package/kernel/nat46/patches/102-mapt.patch b/package/kernel/nat46/patches/102-mapt.patch new file mode 100644 index 00000000000000..979ea56da0c86d --- /dev/null +++ b/package/kernel/nat46/patches/102-mapt.patch @@ -0,0 +1,199 @@ +Author: Pavithra R +Date: Sat Aug 1 13:27:20 2020 +0530 + +nat46: Export APIs for acceleration engine support in nat46 for kernel 5.4 + +This patch is propagated from kernel 4.4 commit +861e64a607fd22d5af089cf56539f42a2e31d581 + +The patch defines and exports APIs in nat46 to be used for accelaration. + +Change-Id: I7934b15544953f870d3595b8b359433b4fff7c30 +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -1491,6 +1491,10 @@ int pairs_xlate_v6_to_v4_outer(nat46_ins + return ( (xlate_src >= 0) && (xlate_dst >= 0) ); + } + ++int xlate_6_to_4(struct net_device *dev, struct ipv6hdr *ip6h, uint16_t proto, __u32 *pv4saddr, __u32 *pv4daddr) { ++ return pairs_xlate_v6_to_v4_outer(netdev_nat46_instance(dev), ip6h, proto, pv4saddr, pv4daddr); ++} ++EXPORT_SYMBOL(xlate_6_to_4); + + void nat46_ipv6_input(struct sk_buff *old_skb) { + struct ipv6hdr *ip6h = ipv6_hdr(old_skb); +@@ -1628,6 +1632,10 @@ void nat46_ipv6_input(struct sk_buff *ol + + nat46debug(5, "about to send v4 packet, flags: %02x", IPCB(new_skb)->flags); + nat46_netdev_count_xmit(new_skb, old_skb->dev); ++ ++ /* set skb->iif */ ++ new_skb->skb_iif = old_skb->skb_iif; ++ + netif_rx(new_skb); + + /* TBD: should copy be released here? */ +@@ -1732,6 +1740,10 @@ int pairs_xlate_v4_to_v6_outer(nat46_ins + return 0; + } + ++int xlate_4_to_6(struct net_device *dev, struct iphdr *hdr4, uint16_t sport, uint16_t dport, void *v6saddr, void *v6daddr) { ++ return pairs_xlate_v4_to_v6_outer(netdev_nat46_instance(dev), hdr4, &sport, &dport, v6saddr, v6daddr); ++} ++EXPORT_SYMBOL(xlate_4_to_6); + + void nat46_ipv4_input(struct sk_buff *old_skb) { + nat46_instance_t *nat46 = get_nat46_instance(old_skb); +@@ -1859,10 +1871,32 @@ void nat46_ipv4_input(struct sk_buff *ol + + nat46debug(5, "about to send v6 packet, flags: %02x", IPCB(new_skb)->flags); + nat46_netdev_count_xmit(new_skb, old_skb->dev); ++ ++ /* set skb->iif */ ++ new_skb->skb_iif = old_skb->skb_iif; ++ + netif_rx(new_skb); + + done: + release_nat46_instance(nat46); + } + ++int nat46_get_npairs(struct net_device *dev) { ++ nat46_instance_t *nat46 = netdev_nat46_instance(dev); ++ return nat46->npairs; ++} ++EXPORT_SYMBOL(nat46_get_npairs); + ++bool nat46_get_rule_config(struct net_device *dev, nat46_xlate_rulepair_t **nat46_rule_pair, int *count) { ++ nat46_instance_t *nat46 = netdev_nat46_instance(dev); ++ if (nat46->npairs < 1) { ++ /* ++ * no rules ? ++ */ ++ return false; ++ } ++ *count = nat46->npairs; ++ *nat46_rule_pair = nat46->pairs; ++ return true; ++} ++EXPORT_SYMBOL(nat46_get_rule_config); +--- a/nat46/modules/nat46-core.h ++++ b/nat46/modules/nat46-core.h +@@ -42,18 +42,18 @@ typedef enum { + #define NAT46_SIGNATURE 0x544e3634 + #define FREED_NAT46_SIGNATURE 0xdead544e + +-typedef struct { ++typedef struct nat46_xlate_rule { + nat46_xlate_style_t style; + struct in6_addr v6_pref; +- int v6_pref_len; +- u32 v4_pref; +- int v4_pref_len; +- int ea_len; +- int psid_offset; +- int fmr_flag; ++ int v6_pref_len; ++ u32 v4_pref; ++ int v4_pref_len; ++ int ea_len; ++ int psid_offset; ++ int fmr_flag; + } nat46_xlate_rule_t; + +-typedef struct { ++typedef struct nat46_xlate_rulepair { + nat46_xlate_rule_t local; + nat46_xlate_rule_t remote; + } nat46_xlate_rulepair_t; +@@ -82,4 +82,9 @@ nat46_instance_t *get_nat46_instance(str + nat46_instance_t *alloc_nat46_instance(int npairs, nat46_instance_t *old, int from_ipair, int to_ipair); + void release_nat46_instance(nat46_instance_t *nat46); + ++int xlate_6_to_4(struct net_device *dev, struct ipv6hdr *ip6h, uint16_t proto, __u32 *pv4saddr, __u32 *pv4daddr); ++int xlate_4_to_6(struct net_device *dev, struct iphdr *hdr4, uint16_t sport, uint16_t dport, void *v6saddr, void *v6daddr); ++bool nat46_get_rule_config(struct net_device *dev, nat46_xlate_rulepair_t **nat46_rule_pair, int *count); ++int nat46_get_npairs(struct net_device *dev); ++ + #endif +--- a/nat46/modules/nat46-netdev.c ++++ b/nat46/modules/nat46-netdev.c +@@ -24,10 +24,12 @@ + #include + #include + #include ++#include + #include "nat46-core.h" + #include "nat46-module.h" + + #define NETDEV_DEFAULT_NAME "nat46." ++static RADIX_TREE(netdev_tree, GFP_ATOMIC); + + typedef struct { + u32 sig; +@@ -79,6 +81,18 @@ void nat46_netdev_count_xmit(struct sk_b + dev->stats.tx_bytes += skb->len; + } + ++void nat46_update_stats(struct net_device *dev, uint32_t rx_packets, uint32_t rx_bytes, ++ uint32_t tx_packets, uint32_t tx_bytes, uint32_t rx_dropped, uint32_t tx_dropped) ++{ ++ dev->stats.rx_packets += rx_packets; ++ dev->stats.rx_bytes += rx_bytes; ++ dev->stats.tx_packets += tx_packets; ++ dev->stats.tx_bytes += tx_bytes; ++ dev->stats.rx_dropped += rx_dropped; ++ dev->stats.tx_dropped += tx_dropped; ++} ++EXPORT_SYMBOL(nat46_update_stats); ++ + void *netdev_nat46_instance(struct net_device *dev) { + nat46_netdev_priv_t *priv = netdev_priv(dev); + return priv->nat46; +@@ -155,6 +169,11 @@ int nat46_netdev_create(char *basename, + printk("nat46: netdevice nat46 '%s' created successfully.\n", devname); + kfree(devname); + ++ /* ++ * add this netdevice to list ++ */ ++ radix_tree_insert(&netdev_tree, (*dev)->ifindex, (void *)*dev); ++ + return 0; + + err_register_dev: +@@ -169,9 +188,23 @@ void nat46_netdev_destroy(struct net_dev + { + netdev_nat46_set_instance(dev, NULL); + unregister_netdev(dev); ++ radix_tree_delete(&netdev_tree, dev->ifindex); + printk("nat46: Destroying nat46 device.\n"); + } + ++bool is_map_t_dev(struct net_device *dev) ++{ ++ if(!dev) { ++ return false; ++ } ++ ++ if(radix_tree_lookup(&netdev_tree, dev->ifindex)) { ++ return true; ++ } ++ return false; ++} ++EXPORT_SYMBOL(is_map_t_dev); ++ + static int is_nat46(struct net_device *dev) { + nat46_netdev_priv_t *priv = netdev_priv(dev); + return (priv && (NAT46_DEVICE_SIGNATURE == priv->sig)); +--- a/nat46/modules/nat46-netdev.h ++++ b/nat46/modules/nat46-netdev.h +@@ -24,3 +24,6 @@ void nat64_show_all_configs(struct seq_f + void nat46_netdev_count_xmit(struct sk_buff *skb, struct net_device *dev); + void *netdev_nat46_instance(struct net_device *dev); + ++void nat46_update_stats(struct net_device *dev, uint32_t rx_packets, uint32_t rx_bytes, uint32_t tx_packets, uint32_t tx_bytes, ++ uint32_t rx_dropped, uint32_t tx_dropped); ++bool is_map_t_dev(struct net_device *dev); diff --git a/package/kernel/nat46/patches/103-tos.patch b/package/kernel/nat46/patches/103-tos.patch new file mode 100644 index 00000000000000..253da044a7ae81 --- /dev/null +++ b/package/kernel/nat46/patches/103-tos.patch @@ -0,0 +1,56 @@ +Author: Pavithra R +Date: Sat Aug 1 13:55:33 2020 +0530 + +nat46: Set IPv6 traffic class from IPv4 ToS value + +Set IPv6 traffic class from IPv4 ToS value during +IPv4 to IPv6 translation and vice-versa. + +This patch is propagated from kernel 4.4 commit +1cd3b55b059d4513649bb73bc69da931ed3beb7b + +Change-Id: Ia14e53447e829c8648c01656237ac902ad8674ec +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -807,11 +807,12 @@ void *get_next_header_ptr6(void *pv6, in + } + + void fill_v4hdr_from_v6hdr(struct iphdr * iph, struct ipv6hdr *ip6h, __u32 v4saddr, __u32 v4daddr, __u16 id, __u16 frag_off, __u16 proto, int l3_payload_len) { ++ uint32_t ver_class_flow = ntohl(*(__be32 *)ip6h); + iph->ttl = ip6h->hop_limit; + iph->saddr = v4saddr; + iph->daddr = v4daddr; + iph->protocol = proto; +- *((__be16 *)iph) = htons((4 << 12) | (5 << 8) | (0x00/*tos*/ & 0xff)); ++ *((__be16 *)iph) = htons((4 << 12) | (5 << 8) | ((ver_class_flow >> 20) & 0xff)); + iph->frag_off = frag_off; + iph->id = id; + iph->tot_len = htons( l3_payload_len + IPV4HDRSIZE ); +@@ -1750,7 +1751,7 @@ void nat46_ipv4_input(struct sk_buff *ol + struct sk_buff *new_skb; + uint16_t sport = 0, dport = 0; + +- int tclass = 0; ++ uint8_t tclass; + int flowlabel = 0; + int check_for_l4 = 0; + int having_l4 = 0; +@@ -1761,6 +1762,8 @@ void nat46_ipv4_input(struct sk_buff *ol + + char v6saddr[16], v6daddr[16]; + ++ tclass = hdr4->tos; ++ + memset(v6saddr, 1, 16); + memset(v6daddr, 2, 16); + +@@ -1843,7 +1846,6 @@ void nat46_ipv4_input(struct sk_buff *ol + memset(hdr6, 0, sizeof(*hdr6) + (add_frag_header?8:0)); + + /* build IPv6 header */ +- tclass = 0; /* traffic class */ + *(__be32 *)hdr6 = htonl(0x60000000 | (tclass << 20)) | flowlabel; /* version, priority, flowlabel */ + + /* IPv6 length is a payload length, IPv4 is hdr+payload */ diff --git a/package/kernel/nat46/patches/104-icmp.patch b/package/kernel/nat46/patches/104-icmp.patch new file mode 100644 index 00000000000000..3733fd0ab1941b --- /dev/null +++ b/package/kernel/nat46/patches/104-icmp.patch @@ -0,0 +1,440 @@ +Author: Pavithra R +Date: Mon Aug 3 17:03:37 2020 +0530 + +nat46: Fix for icmp translation issues. + +This patch is propagated from kernel 4.4 commit +45fce10ba0105515289930b3e3f9df57bf3c22b6. + +Fixed icmpv4 to icmpv6 and vice-versa translation issues, in accordance with RFC6145. + +The change covers: +1. Translation of ICMP errors from IPv4 to IPv6 and vice-versa. +2. Translation of inner L3 packet header {Eth:IPv4:ICMP:IPv4:ICMP} in ICMP error messages. +3. Address translation for packets not having port numbers, hence CE/BR needs to fetch this + information from inner header (atleast 28 bytes (IP hdr + 8 bytes) of orignal packet received + that is transmitted back will be there in response). + +Change-Id: I677474728aeaee656376fdb1edcb9476783d5b40 +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -22,6 +22,9 @@ + #include "nat46-glue.h" + #include "nat46-core.h" + ++static uint16_t xlate_pkt_in_err_v4_to_v6(nat46_instance_t *nat46, struct iphdr *iph, ++ struct sk_buff *old_skb, uint16_t *sport, uint16_t *dport); ++ + void + nat46debug_dump(nat46_instance_t *nat46, int level, void *addr, int len) + { +@@ -806,6 +809,14 @@ void *get_next_header_ptr6(void *pv6, in + return ret; + } + ++void fill_v6hdr_from_v4hdr(struct iphdr *iph, struct ipv6hdr *ip6h) { ++ *((__be16 *)ip6h) = htons((6 << 12) | (iph->tos << 4)); /* Version, Traffic Class */ ++ memset(&(ip6h->flow_lbl), 0, sizeof(ip6h->flow_lbl)); /* Flowlabel */ ++ ip6h->payload_len = htons(ntohs(iph->tot_len) - IPV4HDRSIZE); ++ ip6h->nexthdr = iph->protocol; ++ ip6h->hop_limit = iph->ttl; ++} ++ + void fill_v4hdr_from_v6hdr(struct iphdr * iph, struct ipv6hdr *ip6h, __u32 v4saddr, __u32 v4daddr, __u16 id, __u16 frag_off, __u16 proto, int l3_payload_len) { + uint32_t ver_class_flow = ntohl(*(__be32 *)ip6h); + iph->ttl = ip6h->hop_limit; +@@ -1128,34 +1139,34 @@ static void nat46_fixup_icmp6_paramprob( + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -1 }; + u32 *pptr6 = icmp6_parameter_ptr(icmp6h); + u8 *pptr4 = icmp_parameter_ptr((struct icmphdr *)icmp6h); +- int new_pptr = -1; ++ int8_t new_pptr = -1; + int len = ntohs(ip6h->payload_len)-sizeof(*icmp6h); + + switch(icmp6h->icmp6_code) { ++ case 1: ++ update_icmp6_type_code(nat46, icmp6h, 3, 2); ++ break; + case 0: + if(*pptr6 < sizeof(ptr6_4)/sizeof(ptr6_4[0])) { + new_pptr = ptr6_4[*pptr6]; + if (new_pptr >= 0) { + icmp6h->icmp6_cksum = csum16_upd(icmp6h->icmp6_cksum, (*pptr6 & 0xffff), (new_pptr << 8)); + *pptr4 = 0xff & new_pptr; +- } else { +- ip6h->nexthdr = NEXTHDR_NONE; ++ update_icmp6_type_code(nat46, icmp6h, 12, 0); ++ break; + } +- } else { +- ip6h->nexthdr = NEXTHDR_NONE; + } +- break; +- case 1: +- *pptr6 = 0; +- update_icmp6_type_code(nat46, icmp6h, 3, 2); +- len = xlate_payload6_to4(nat46, (icmp6h + 1), get_next_header_ptr6((icmp6h + 1), len), len, &icmp6h->icmp6_cksum, ptailTruncSize); +- break; ++#if __has_attribute(__fallthrough__) ++ __attribute__((__fallthrough__)); ++#endif + case 2: /* fallthrough to default */ + default: + ip6h->nexthdr = NEXTHDR_NONE; ++ return; + } +-} + ++ len = xlate_payload6_to4(nat46, (icmp6h + 1), get_next_header_ptr6((icmp6h + 1), len), len, &icmp6h->icmp6_cksum, ptailTruncSize); ++} + + /* Fixup ICMP6->ICMP before IP header translation, according to http://tools.ietf.org/html/rfc6145 */ + +@@ -1211,17 +1222,19 @@ int ip6_input_not_interested(nat46_insta + return 0; + } + +-static uint16_t nat46_fixup_icmp_time_exceeded(nat46_instance_t *nat46, struct iphdr *iph, struct icmphdr *icmph, struct sk_buff *old_skb) { ++static uint16_t nat46_fixup_icmp_time_exceeded(nat46_instance_t *nat46, struct iphdr *iph, ++ struct icmphdr *icmph, struct sk_buff *old_skb, uint16_t *sport, uint16_t *dport) { + /* + * Set the Type to 3, and adjust the + * ICMP checksum both to take the type change into account and + * to include the ICMPv6 pseudo-header. The Code is unchanged. + */ + icmph->type = 3; +- return 0; ++ return xlate_pkt_in_err_v4_to_v6(nat46, iph, old_skb, sport, dport); + } + +-static uint16_t nat46_fixup_icmp_parameterprob(nat46_instance_t *nat46, struct iphdr *iph, struct icmphdr *icmph, struct sk_buff *old_skb) { ++static uint16_t nat46_fixup_icmp_parameterprob(nat46_instance_t *nat46, struct iphdr *iph, ++ struct icmphdr *icmph, struct sk_buff *old_skb, uint16_t *sport, uint16_t *dport) { + /* + * Set the Type to 4, and adjust the + * ICMP checksum both to take the type/code change into account +@@ -1264,27 +1277,33 @@ static uint16_t nat46_fixup_icmp_paramet + */ + static int ptr4_6[] = { 0, 1, 4, 4, -1, -1, -1, -1, 7, 6, -1, -1, 8, 8, 8, 8, 24, 24, 24, 24, -1 }; + u8 *icmp_pptr = icmp_parameter_ptr(icmph); +- int new_pptr = -1; ++ u32 *icmp6_pptr = icmp6_parameter_ptr((struct icmp6hdr *)icmph); ++ int8_t new_pptr = -1; ++ ++ icmph->type = 4; ++ + switch (icmph->code) { + case 0: + case 2: + if (*icmp_pptr < (sizeof(ptr4_6)/sizeof(ptr4_6[0]))) { + icmph->code = 0; + new_pptr = ptr4_6[*icmp_pptr]; +- if(new_pptr >= 0) { +- /* FIXME: update the parameter pointer in ICMPv6 with new_pptr value */ ++ if (new_pptr >= 0) { ++ *icmp6_pptr = new_pptr; ++ return xlate_pkt_in_err_v4_to_v6(nat46, iph, old_skb, sport, dport); + } +- } else { +- iph->protocol = NEXTHDR_NONE; + } +- break; ++#if __has_attribute(__fallthrough__) ++ __attribute__((__fallthrough__)); ++#endif + default: + iph->protocol = NEXTHDR_NONE; + } + return 0; + } + +-static uint16_t nat46_fixup_icmp_dest_unreach(nat46_instance_t *nat46, struct iphdr *iph, struct icmphdr *icmph, struct sk_buff *old_skb) { ++static uint16_t nat46_fixup_icmp_dest_unreach(nat46_instance_t *nat46, struct iphdr *iph, ++ struct icmphdr *icmph, struct sk_buff *old_skb, uint16_t *sport, uint16_t *dport) { + /* + * Translate the Code as + * described below, set the Type to 1, and adjust the ICMP +@@ -1347,16 +1366,21 @@ static uint16_t nat46_fixup_icmp_dest_un + + u16 *pmtu = ((u16 *)icmph) + 3; /* IPv4-compatible MTU value is 16 bit */ + ++ icmph->type = 1; ++ + switch (icmph->code) { + case 0: + case 1: + icmph->code = 0; + break; +- case 2: +- /* FIXME: set ICMPv6 parameter pointer to 6 */ ++ case 2: { ++ u32 *icmp6_pptr = icmp6_parameter_ptr((struct icmp6hdr *)icmph); ++ *icmp6_pptr = 6; /* Offset to Next Proto field in IPv6 header. */ + icmph->type = 4; + icmph->code = 1; ++ nat46debug(3, "ICMP Proto Unreachable translated into IPv6 Param Prob.\n"); + break; ++ } + case 3: + icmph->code = 4; + break; +@@ -1406,14 +1430,15 @@ static uint16_t nat46_fixup_icmp_dest_un + break; + default: + iph->protocol = NEXTHDR_NONE; ++ return 0; + } +- return 0; ++ return xlate_pkt_in_err_v4_to_v6(nat46, iph, old_skb, sport, dport); + } + +- + /* Fixup ICMP->ICMP6 before IP header translation, according to http://tools.ietf.org/html/rfc6145 */ + +-static uint16_t nat46_fixup_icmp(nat46_instance_t *nat46, struct iphdr *iph, struct sk_buff *old_skb) { ++static uint16_t nat46_fixup_icmp(nat46_instance_t *nat46, struct iphdr *iph, ++ struct sk_buff *old_skb, uint16_t *sport, uint16_t *dport) { + struct icmphdr *icmph = (struct icmphdr *)(iph+1); + uint16_t ret = 0; + +@@ -1422,22 +1447,22 @@ static uint16_t nat46_fixup_icmp(nat46_i + switch(icmph->type) { + case ICMP_ECHO: + icmph->type = ICMPV6_ECHO_REQUEST; +- ret = icmph->un.echo.id; ++ *sport = *dport = icmph->un.echo.id; + nat46debug(3, "ICMP echo request translated into IPv6, id: %d", ntohs(ret)); + break; + case ICMP_ECHOREPLY: + icmph->type = ICMPV6_ECHO_REPLY; +- ret = icmph->un.echo.id; ++ *sport = *dport = icmph->un.echo.id; + nat46debug(3, "ICMP echo reply translated into IPv6, id: %d", ntohs(ret)); + break; + case ICMP_TIME_EXCEEDED: +- ret = nat46_fixup_icmp_time_exceeded(nat46, iph, icmph, old_skb); ++ ret = nat46_fixup_icmp_time_exceeded(nat46, iph, icmph, old_skb, sport, dport); + break; + case ICMP_PARAMETERPROB: +- ret = nat46_fixup_icmp_parameterprob(nat46, iph, icmph, old_skb); ++ ret = nat46_fixup_icmp_parameterprob(nat46, iph, icmph, old_skb, sport, dport); + break; + case ICMP_DEST_UNREACH: +- ret = nat46_fixup_icmp_dest_unreach(nat46, iph, icmph, old_skb); ++ ret = nat46_fixup_icmp_dest_unreach(nat46, iph, icmph, old_skb, sport, dport); + break; + default: + /* Silently drop. */ +@@ -1457,11 +1482,13 @@ int pairs_xlate_v6_to_v4_outer(nat46_ins + + if(-1 == xlate_dst) { + if (xlate_v6_to_v4(nat46, &apair->local, &ip6h->daddr, pv4daddr)) { ++ nat46debug(5, "Dst addr %pI6 to %pI4 \n", &ip6h->daddr, pv4daddr); + xlate_dst = ipair; + } + } + if(-1 == xlate_src) { + if (xlate_v6_to_v4(nat46, &apair->remote, &ip6h->saddr, pv4saddr)) { ++ nat46debug(5, "Src addr %pI6 to %pI4 \n", &ip6h->saddr, pv4saddr); + xlate_src = ipair; + } + } +@@ -1560,6 +1587,7 @@ void nat46_ipv6_input(struct sk_buff *ol + } + + if(!pairs_xlate_v6_to_v4_outer(nat46, ip6h, proto, &v4saddr, &v4daddr)) { ++ nat46debug(0, "[nat46] Could not translate v6->v4"); + goto done; + } + +@@ -1713,11 +1741,13 @@ int pairs_xlate_v4_to_v6_outer(nat46_ins + + if(-1 == xlate_src) { + if(xlate_v4_to_v6(nat46, &apair->local, &hdr4->saddr, v6saddr, sport)) { ++ nat46debug(5, "Src addr %pI4 to %pI6 \n", &hdr4->saddr, v6saddr); + xlate_src = ipair; + } + } + if(-1 == xlate_dst) { + if(xlate_v4_to_v6(nat46, &apair->remote, &hdr4->daddr, v6daddr, dport)) { ++ nat46debug(5, "Dst addr %pI4 to %pI6 \n", &hdr4->daddr, v6daddr); + xlate_dst = ipair; + } + } +@@ -1746,10 +1776,145 @@ int xlate_4_to_6(struct net_device *dev, + } + EXPORT_SYMBOL(xlate_4_to_6); + ++/* FIXME: This is a workaround, till the LPM is not added. The sport & dport in inner header will be dport & sport of the outer ++ * header, respectively. Hence, dest. and source ips of inner header will be found in local & remote rules, respectively. ++ * Will work only for a pair of local & remote rules. Once LPM is brought in, this method can be removed and ++ * pairs_xlate_v4_to_v6_outer be used instead. ++ */ ++int pairs_xlate_v4_to_v6_inner(nat46_instance_t *nat46, struct iphdr *iph, ++ uint16_t sport, uint16_t dport, void *v6saddr, void *v6daddr) { ++ int ipair = 0; ++ nat46_xlate_rulepair_t *apair = NULL; ++ int xlate_src = -1; ++ int xlate_dst = -1; ++ ++ for (ipair = 0; ipair < nat46->npairs; ipair++) { ++ apair = &nat46->pairs[ipair]; ++ ++ if (-1 == xlate_dst) { ++ if (xlate_v4_to_v6(nat46, &apair->local, &iph->daddr, v6daddr, &dport)) { ++ nat46debug(3, "Dst addr %pI4 to %pI6 \n", &iph->daddr, v6daddr); ++ xlate_dst = ipair; ++ } ++ } ++ if (-1 == xlate_src) { ++ if(xlate_v4_to_v6(nat46, &apair->remote, &iph->saddr, v6saddr, &sport)) { ++ nat46debug(3, "Src addr %pI4 to %pI6 \n", &iph->saddr, v6saddr); ++ xlate_src = ipair; ++ } ++ } ++ if ((xlate_src >= 0) && (xlate_dst >= 0)) { ++ /* we did manage to translate it */ ++ nat46debug(5, "[nat46] Inner header xlate results: src %d dst %d", xlate_src, xlate_dst); ++ return 1; ++ } else { ++ /* We did not match fully and there are more rules */ ++ if((ipair+1 < nat46->npairs) && is_last_pair_in_group(apair)) { ++ xlate_src = -1; ++ xlate_dst = -1; ++ } ++ } ++} ++ ++ nat46debug(1, "[nat46] Could not find a translation pair v4->v6"); ++ return 0; ++} ++ ++static uint16_t xlate_pkt_in_err_v4_to_v6(nat46_instance_t *nat46, struct iphdr *iph, ++ struct sk_buff *old_skb, uint16_t *sport, uint16_t *dport) { ++ struct ipv6hdr ip6h; ++ char v6saddr[16], v6daddr[16]; ++ uint16_t temp_port = 0; ++ int ret = 0; ++ struct icmphdr *icmph = (struct icmphdr *)(iph + 1); ++ struct iphdr *iiph = (struct iphdr *)(icmph + 1); ++ ++ switch (iiph->protocol) { ++ case IPPROTO_TCP: { ++ struct tcphdr *th = (struct tcphdr *)(iiph + 1); ++ *sport = th->source; ++ *dport = th->dest; ++ iiph->protocol = NEXTHDR_TCP; ++ break; ++ } ++ case IPPROTO_UDP: { ++ struct udphdr *udp = (struct udphdr *)(iiph + 1); ++ *sport = udp->source; ++ *dport = udp->dest; ++ iiph->protocol = NEXTHDR_UDP; ++ break; ++ } ++ case IPPROTO_ICMP: { ++ struct icmphdr *icmph = (struct icmphdr *)(iiph + 1); ++ iiph->protocol = NEXTHDR_ICMP; ++ switch (icmph->type) { ++ case ICMP_ECHO: ++ icmph->type = ICMPV6_ECHO_REQUEST; ++ *sport = *dport = icmph->un.echo.id; ++ break; ++ case ICMP_ECHOREPLY: ++ icmph->type = ICMPV6_ECHO_REPLY; ++ *sport = *dport = icmph->un.echo.id; ++ break; ++ default: ++ nat46debug(3, "ICMP Error message can't be inside another ICMP Error messgae."); ++ *sport = *dport = 0; ++ return 0; ++ } ++ break; ++ } ++ default: ++ nat46debug(3, "[ICMPv4] Next header: %u. Only TCP, UDP, and ICMP are supported.", iiph->protocol); ++ *sport = *dport = 0; ++ return 0; ++ } ++ ++ nat46debug(3, "Retrieved from pkt in error: dest port %d, and src port %d.", ntohs(*dport), ntohs(*sport)); ++ ++ if (!pairs_xlate_v4_to_v6_inner(nat46, iiph, *sport, *dport, v6saddr, v6daddr)) { ++ nat46debug(0, "[nat46] Could not translate inner header v4->v6"); ++ *sport = *dport = 0; ++ return 0; ++ } ++ ++ fill_v6hdr_from_v4hdr (iiph, &ip6h); ++ memcpy(&ip6h.saddr, v6saddr, sizeof(ip6h.saddr)); ++ memcpy(&ip6h.daddr, v6daddr, sizeof(ip6h.daddr)); ++ ++ if (skb_tailroom(old_skb) >= IPV6V4HDRDELTA){ ++ skb_put(old_skb, IPV6V4HDRDELTA); ++ memmove(((char *)iiph + IPV6HDRSIZE), (iiph + 1), ntohs(iiph->tot_len) - IPV4HDRSIZE); ++ memcpy(iiph, &ip6h, IPV6HDRSIZE); ++ } ++ else { ++ ret = pskb_expand_head(old_skb, 0, IPV6V4HDRDELTA, GFP_ATOMIC); ++ if (unlikely(ret)) { ++ nat46debug(0, "[nat46] Could not copy v4 skb"); ++ *sport = *dport = 0; ++ return 0; ++ } ++ ++ skb_put(old_skb, IPV6V4HDRDELTA); ++ iiph = (struct iphdr *)(icmp_hdr(old_skb) + 1); ++ memmove(((char *)iiph + IPV6HDRSIZE), (iiph + 1), ntohs(iiph->tot_len) - IPV4HDRSIZE); ++ memcpy(iiph, &ip6h, IPV6HDRSIZE); ++ nat46 = get_nat46_instance(old_skb); ++ iph = ip_hdr(old_skb); ++ } ++ ++ /* Swapping Ports for outer header */ ++ /* Another work-around till LPM is not present. */ ++ temp_port = *sport; ++ *sport = *dport; ++ *dport = temp_port; ++ ++ return 1; ++} ++ + void nat46_ipv4_input(struct sk_buff *old_skb) { + nat46_instance_t *nat46 = get_nat46_instance(old_skb); + struct sk_buff *new_skb; +- uint16_t sport = 0, dport = 0; ++ uint16_t sport = 0, dport = 0, ret = 0; + + uint8_t tclass; + int flowlabel = 0; +@@ -1772,11 +1937,11 @@ void nat46_ipv4_input(struct sk_buff *ol + } + nat46debug(1, "nat46_ipv4_input packet"); + nat46debug(5, "nat46_ipv4_input protocol: %d, len: %d, flags: %02x", hdr4->protocol, old_skb->len, IPCB(old_skb)->flags); +- if(0 == (ntohs(hdr4->frag_off) & 0x3FFF) ) { ++ if(0 == (ntohs(hdr4->frag_off) & 0x3FFF) ) { /* Checking for MF */ + check_for_l4 = 1; + } else { + add_frag_header = 1; +- if (0 == (ntohs(hdr4->frag_off) & 0x1FFF)) { ++ if (0 == (ntohs(hdr4->frag_off) & 0x1FFF)) { /* Checking for Frag Offset */ + check_for_l4 = 1; + } + } +@@ -1798,9 +1963,10 @@ void nat46_ipv4_input(struct sk_buff *ol + break; + } + case IPPROTO_ICMP: +- sport = dport = nat46_fixup_icmp(nat46, hdr4, old_skb); +- having_l4 = 1; +- break; ++ ret = nat46_fixup_icmp(nat46, hdr4, old_skb, &sport, &dport); ++ nat46debug(3, "ICMP translated to dest port %d, and src port %d.", ntohs(dport), ntohs(sport)); ++ having_l4 = 1; ++ break; + default: + break; + } diff --git a/package/kernel/nat46/patches/105-longest-prefix-match.patch b/package/kernel/nat46/patches/105-longest-prefix-match.patch new file mode 100644 index 00000000000000..beef42d646cab3 --- /dev/null +++ b/package/kernel/nat46/patches/105-longest-prefix-match.patch @@ -0,0 +1,639 @@ +Author: Pavithra R +Date: Tue Aug 4 10:33:59 2020 +0530 + +nat46: Adding support for multiple MAP-T rules. + +This patch is propagated from kernel 4.4 commit +05a122b0cb0d3a99f040c94b3f626e7350f1445b + +This change covers: +1. Support for adding maximum of 32 MAP-T rules (DMR + FMRs). +2. Support for rule lookup based on Longest Prefix Match method. +3. Support for validation of new rules being inserted. + +Change-Id: Id87448a8f544273b40c20aaab6e5c63b0dbd72e +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -121,6 +121,13 @@ int try_parse_ipv6_prefix(struct in6_add + *arg_plen++ = 0; + if (pref_len) { + *pref_len = simple_strtol(arg_plen, NULL, 10); ++ ++ /* ++ * ipv6 prefix should be <= 128 ++ */ ++ if (*pref_len > IPV6_BITS_MAX) { ++ return -1; ++ } + } + } + err = (1 != in6_pton(arg, -1, (u8 *)pref, '\0', NULL)); +@@ -134,6 +141,13 @@ int try_parse_ipv4_prefix(u32 *v4addr, i + *arg_plen++ = 0; + if (pref_len) { + *pref_len = simple_strtol(arg_plen, NULL, 10); ++ ++ /* ++ * ipv4 prefix len should be <= 32 ++ */ ++ if (*pref_len > IPV4_BITS_MAX) { ++ return -1; ++ } + } + } + err = (1 != in4_pton(arg, -1, (u8 *)v4addr, '/', NULL)); +@@ -176,11 +190,127 @@ int try_parse_rule_arg(nat46_xlate_rule_ + return err; + } + +-/* +- * Parse the config commands in the buffer, +- * destructive (puts zero between the args) ++static inline void nat46_swap(nat46_xlate_rulepair_t *var1, nat46_xlate_rulepair_t *var2) { ++ nat46_xlate_rulepair_t temp; ++ temp = *var1; ++ *var1 = *var2; ++ *var2 = temp; ++} ++ ++/* ++ * Sort rule pairs based on prefix length. + */ ++void nat46_sort_rule_array(nat46_instance_t *nat46) { ++ int i, j; ++ int nelem = nat46->npairs; ++ nat46_xlate_rulepair_t *array = NULL; ++ ++ memcpy(nat46->sorted_ipv4_local_pairs, nat46->pairs, nelem * sizeof(nat46_xlate_rulepair_t)); ++ memcpy(nat46->sorted_ipv4_remote_pairs, nat46->pairs, nelem * sizeof(nat46_xlate_rulepair_t)); ++ memcpy(nat46->sorted_ipv6_local_pairs, nat46->pairs, nelem * sizeof(nat46_xlate_rulepair_t)); ++ memcpy(nat46->sorted_ipv6_remote_pairs, nat46->pairs, nelem * sizeof(nat46_xlate_rulepair_t)); ++ ++ array = &nat46->sorted_ipv4_local_pairs[0]; ++ for (i = 0; i < nelem - 1; i++) { ++ for (j = 0; j < nelem - i - 1; j++) { ++ if (array[j].local.v4_pref_len < array[j+1].local.v4_pref_len) { ++ nat46_swap (&array[j], &array[j+1]); ++ } ++ } ++ } ++ ++ array = &nat46->sorted_ipv4_remote_pairs[0]; ++ for (i = 0; i < nelem - 1; i++) { ++ for (j = 0; j < nelem - i - 1; j++) { ++ if (array[j].remote.v4_pref_len < array[j+1].remote.v4_pref_len) { ++ nat46_swap (&array[j], &array[j+1]); ++ } ++ } ++ } + ++ array = &nat46->sorted_ipv6_local_pairs[0]; ++ for (i = 0; i < nelem - 1; i++) { ++ for (j = 0; j < nelem - i - 1; j++) { ++ if (array[j].local.v6_pref_len < array[j+1].local.v6_pref_len) { ++ nat46_swap (&array[j], &array[j+1]); ++ } ++ } ++ } ++ ++ array = &nat46->sorted_ipv6_remote_pairs[0]; ++ for (i = 0; i < nelem - 1; i++) { ++ for (j = 0; j < nelem - i - 1; j++) { ++ if (array[j].remote.v6_pref_len < array[j+1].remote.v6_pref_len) { ++ nat46_swap (&array[j], &array[j+1]); ++ } ++ } ++ } ++} ++ ++bool nat46_validate_RFC6052_style(nat46_instance_t *nat46, nat46_xlate_rule_t rule) ++{ ++ if (rule.style == NAT46_XLATE_RFC6052) { ++ if (!((rule.v6_pref_len == 32) || (rule.v6_pref_len == 40) || ++ (rule.v6_pref_len == 48) || (rule.v6_pref_len == 56) || ++ (rule.v6_pref_len == 64) || (rule.v6_pref_len == 96))) { ++ nat46debug(3, "IPv6 prefix len is invalid"); ++ return false; ++ } ++ } ++ return true; ++} ++ ++bool nat46_validate_MAP_style(nat46_instance_t *nat46, nat46_xlate_rule_t rule) ++{ ++ int psid_len; ++ if (rule.style == NAT46_XLATE_MAP) { ++ ++ /* ++ * max ea_len is 48 ++ */ ++ if (rule.ea_len > EA_LEN_MAX) { ++ nat46debug(3, "EA-length should not exceed 48"); ++ return false; ++ } ++ ++ if (rule.v4_pref_len + rule.ea_len > IPV4_BITS_MAX) { ++ psid_len = rule.ea_len - (IPV4_BITS_MAX - rule.v4_pref_len); ++ } else { ++ psid_len = 0; ++ } ++ ++ if (psid_len + rule.psid_offset > PSID_LEN_MAX) { ++ nat46debug(3, "psid_len + psid_offset should not exceed 16"); ++ return false; ++ } ++ } ++ return true; ++} ++ ++int nat46_validate_ipair_config(nat46_instance_t *nat46, nat46_xlate_rulepair_t *apair) ++{ ++ if (!nat46_validate_RFC6052_style(nat46, apair->local)) { ++ return -1; ++ } ++ ++ if (!nat46_validate_RFC6052_style(nat46, apair->remote)) { ++ return -1; ++ } ++ ++ if (!nat46_validate_MAP_style(nat46, apair->local)) { ++ return -1; ++ } ++ ++ if (!nat46_validate_MAP_style(nat46, apair->remote)) { ++ return -1; ++ } ++ return 0; ++} ++ ++/* ++ * Parse the config commands in the buffer, ++ * destructive (puts zero between the args) ++ */ + int nat46_set_ipair_config(nat46_instance_t *nat46, int ipair, char *buf, int count) { + char *tail = buf; + char *arg_name; +@@ -210,7 +340,18 @@ int nat46_set_ipair_config(nat46_instanc + err = try_parse_rule_arg(&apair->remote, arg_name, &tail); + } + } +- return err; ++ ++ err = nat46_validate_ipair_config(nat46, apair); ++ if (err) { ++ return err; ++ } ++ ++ /* ++ * sort nat46->pairs based on prefix length. ++ */ ++ nat46_sort_rule_array(nat46); ++ ++ return 0; + } + + int nat46_set_config(nat46_instance_t *nat46, char *buf, int count) { +@@ -854,37 +995,120 @@ int is_last_pair_in_group(nat46_xlate_ru + return ( (apair->local.style != NAT46_XLATE_NONE) && (apair->remote.style != NAT46_XLATE_NONE) ); + } + ++nat46_xlate_rulepair_t *nat46_lpm(nat46_instance_t *nat46, nat46_rule_type_t type, void *paddr) { ++ int ipair = 0; ++ nat46_xlate_rulepair_t *apair = NULL; ++ uint32_t mask = 0; ++ uint8_t *pa1; ++ uint8_t *pa2; ++ ++ if(!nat46 || !paddr) { ++ return NULL; ++ } ++ ++ switch (type) { ++ case NAT46_IPV4_LOCAL: ++ for (ipair = 0; ipair < nat46->npairs; ipair++) { ++ apair = &nat46->sorted_ipv4_local_pairs[ipair]; ++ ++ /* ++ * For a 32-bit number, if the shift count is 32, then the ++ * result of the left shift operation is always 0. ++ */ ++ if (apair->local.v4_pref_len) { ++ mask = htonl(U32_MASK << (IPV4_BITS_MAX - apair->local.v4_pref_len)); ++ } ++ ++ if((*(uint32_t *)paddr & mask) == (apair->local.v4_pref & mask)) { ++ return apair; ++ } ++ } ++ break; ++ case NAT46_IPV4_REMOTE: ++ for (ipair = 0; ipair < nat46->npairs; ipair++) { ++ apair = &nat46->sorted_ipv4_remote_pairs[ipair]; ++ ++ /* ++ * For a 32-bit number, if the shift count is 32, then the ++ * result of the left shift operation is always 0. ++ */ ++ if (apair->remote.v4_pref_len) { ++ mask = htonl(U32_MASK << (IPV4_BITS_MAX - apair->remote.v4_pref_len)); ++ } ++ ++ if((*(uint32_t *)paddr & mask) == (apair->remote.v4_pref & mask)) { ++ return apair; ++ } ++ } ++ break; ++ case NAT46_IPV6_LOCAL: ++ for (ipair = 0; ipair < nat46->npairs; ipair++) { ++ apair = &nat46->sorted_ipv6_local_pairs[ipair]; ++ if(memcmp(paddr, &apair->local.v6_pref, apair->local.v6_pref_len / BITS_PER_BYTE)) { ++ continue; ++ } ++ if(apair->local.v6_pref_len % BITS_PER_BYTE) { ++ mask = U8_MASK << (BITS_PER_BYTE - (apair->local.v6_pref_len % BITS_PER_BYTE)); ++ pa1 = (uint8_t *)paddr + (apair->local.v6_pref_len / BITS_PER_BYTE); ++ pa2 = (uint8_t *)&apair->local.v6_pref + (apair->local.v6_pref_len / BITS_PER_BYTE); ++ ++ if ((*pa1 & mask) == (*pa2 & mask)) { ++ return apair; ++ } ++ } ++ else ++ return apair; ++ } ++ break; ++ case NAT46_IPV6_REMOTE: ++ for (ipair = 0; ipair < nat46->npairs; ipair++) { ++ apair = &nat46->sorted_ipv6_remote_pairs[ipair]; ++ if(memcmp(paddr, &apair->remote.v6_pref, apair->remote.v6_pref_len / BITS_PER_BYTE)) { ++ continue; ++ } ++ if(apair->remote.v6_pref_len % BITS_PER_BYTE) { ++ mask = U8_MASK << (BITS_PER_BYTE - (apair->remote.v6_pref_len % BITS_PER_BYTE)); ++ pa1 = (uint8_t *)paddr + (apair->remote.v6_pref_len / BITS_PER_BYTE); ++ pa2 = (uint8_t *)&apair->remote.v6_pref + (apair->remote.v6_pref_len / BITS_PER_BYTE); ++ ++ if((*pa1 & mask) == (*pa2 & mask)) { ++ return apair; ++ } ++ } ++ else ++ return apair; ++ } ++ break; ++ default: ++ nat46debug(0, "%s : Invalid prefix type.\n", __func__); ++ } ++ return NULL; ++} ++ + void pairs_xlate_v6_to_v4_inner(nat46_instance_t *nat46, struct ipv6hdr *ip6h, __u32 *pv4saddr, __u32 *pv4daddr) { + int ipair = 0; + nat46_xlate_rulepair_t *apair = NULL; + int xlate_src = -1; + int xlate_dst = -1; + +- for(ipair = 0; ipair < nat46->npairs; ipair++) { +- apair = &nat46->pairs[ipair]; ++ apair = nat46_lpm(nat46, NAT46_IPV6_REMOTE, &ip6h->daddr); ++ if (!apair) { ++ return; ++ } + +- if(-1 == xlate_dst) { +- if(xlate_v6_to_v4(nat46, &apair->remote, &ip6h->daddr, pv4daddr)) { +- xlate_dst = ipair; +- } +- } +- if(-1 == xlate_src) { +- if(xlate_v6_to_v4(nat46, &apair->local, &ip6h->saddr, pv4saddr)) { +- xlate_src = ipair; +- } +- } +- if((xlate_src >= 0) && (xlate_dst >= 0)) { +- /* we did manage to translate it */ +- break; +- } else { +- /* We did not match fully and there are more rules */ +- if((ipair+1 < nat46->npairs) && is_last_pair_in_group(apair)) { +- xlate_src = -1; +- xlate_dst = -1; +- } +- } ++ if (xlate_v6_to_v4(nat46, &apair->remote, &ip6h->daddr, pv4daddr)) { ++ xlate_dst = ipair; ++ } ++ if (xlate_v6_to_v4(nat46, &apair->local, &ip6h->saddr, pv4saddr)) { ++ xlate_src = ipair; ++ } ++ ++ if ((xlate_src >= 0) && (xlate_dst >= 0)) { ++ /* we did manage to translate it */ ++ nat46debug(5, "[nat46payload] xlate results: src %d dst %d", xlate_src, xlate_dst); ++ } else { ++ nat46debug(1, "[nat46] Could not find a translation pair v6->v4 src %pI6c dst %pI6c", &ip6h->saddr, &ip6h->daddr); + } +- nat46debug(5, "[nat46payload] xlate results: src %d dst %d", xlate_src, xlate_dst); + } + + /* +@@ -1471,40 +1695,28 @@ static uint16_t nat46_fixup_icmp(nat46_i + return ret; + } + +-int pairs_xlate_v6_to_v4_outer(nat46_instance_t *nat46, struct ipv6hdr *ip6h, uint16_t proto, __u32 *pv4saddr, __u32 *pv4daddr) { ++int pairs_xlate_v6_to_v4_outer(nat46_instance_t *nat46, nat46_xlate_rulepair_t *apair, ++ struct ipv6hdr *ip6h, uint16_t proto, __u32 *pv4saddr, __u32 *pv4daddr) { + int ipair = 0; +- nat46_xlate_rulepair_t *apair = NULL; + int xlate_src = -1; + int xlate_dst = -1; + +- for(ipair = 0; ipair < nat46->npairs; ipair++) { +- apair = &nat46->pairs[ipair]; ++ apair = nat46_lpm(nat46, NAT46_IPV6_REMOTE, &ip6h->saddr); ++ if (!apair) { ++ return 0; ++ } + +- if(-1 == xlate_dst) { +- if (xlate_v6_to_v4(nat46, &apair->local, &ip6h->daddr, pv4daddr)) { +- nat46debug(5, "Dst addr %pI6 to %pI4 \n", &ip6h->daddr, pv4daddr); +- xlate_dst = ipair; +- } +- } +- if(-1 == xlate_src) { +- if (xlate_v6_to_v4(nat46, &apair->remote, &ip6h->saddr, pv4saddr)) { +- nat46debug(5, "Src addr %pI6 to %pI4 \n", &ip6h->saddr, pv4saddr); +- xlate_src = ipair; +- } +- } +- if( (xlate_src >= 0) && (xlate_dst >= 0) ) { +- break; +- } else { +- /* We did not match fully and there are more rules */ +- if((ipair+1 < nat46->npairs) && is_last_pair_in_group(apair)) { +- xlate_src = -1; +- xlate_dst = -1; +- } +- } ++ if (xlate_v6_to_v4(nat46, &apair->local, &ip6h->daddr, pv4daddr)) { ++ nat46debug(5, "Dst addr %pI6 to %pI4 \n", &ip6h->daddr, pv4daddr); ++ xlate_dst = ipair; ++ } ++ if (xlate_v6_to_v4(nat46, &apair->remote, &ip6h->saddr, pv4saddr)) { ++ nat46debug(5, "Src addr %pI6 to %pI4 \n", &ip6h->saddr, pv4saddr); ++ xlate_src = ipair; + } + if (xlate_dst >= 0) { + if (xlate_src < 0) { +- if(proto == NEXTHDR_ICMP) { ++ if (proto == NEXTHDR_ICMP) { + nat46debug(1, "[nat46] Could not translate remote address v6->v4, ipair %d, for ICMP6 use dest addr", ipair); + *pv4saddr = *pv4daddr; + xlate_src = xlate_dst; +@@ -1520,12 +1732,14 @@ int pairs_xlate_v6_to_v4_outer(nat46_ins + } + + int xlate_6_to_4(struct net_device *dev, struct ipv6hdr *ip6h, uint16_t proto, __u32 *pv4saddr, __u32 *pv4daddr) { +- return pairs_xlate_v6_to_v4_outer(netdev_nat46_instance(dev), ip6h, proto, pv4saddr, pv4daddr); ++ nat46_xlate_rulepair_t apair; ++ return pairs_xlate_v6_to_v4_outer(netdev_nat46_instance(dev), &apair, ip6h, proto, pv4saddr, pv4daddr); + } + EXPORT_SYMBOL(xlate_6_to_4); + + void nat46_ipv6_input(struct sk_buff *old_skb) { + struct ipv6hdr *ip6h = ipv6_hdr(old_skb); ++ nat46_xlate_rulepair_t apair; + nat46_instance_t *nat46 = get_nat46_instance(old_skb); + uint16_t proto; + uint16_t frag_off; +@@ -1586,7 +1800,7 @@ void nat46_ipv6_input(struct sk_buff *ol + check_for_l4 = 1; + } + +- if(!pairs_xlate_v6_to_v4_outer(nat46, ip6h, proto, &v4saddr, &v4daddr)) { ++ if (!pairs_xlate_v6_to_v4_outer(nat46, &apair, ip6h, proto, &v4saddr, &v4daddr)) { + nat46debug(0, "[nat46] Could not translate v6->v4"); + goto done; + } +@@ -1730,56 +1944,44 @@ int ip4_input_not_interested(nat46_insta + return 0; + } + +-int pairs_xlate_v4_to_v6_outer(nat46_instance_t *nat46, struct iphdr *hdr4, uint16_t *sport, uint16_t *dport, void *v6saddr, void *v6daddr) { ++int pairs_xlate_v4_to_v6_outer(nat46_instance_t *nat46, nat46_xlate_rulepair_t *apair, ++ struct iphdr *hdr4, uint16_t *sport, uint16_t *dport, void *v6saddr, void *v6daddr) { + int ipair = 0; +- nat46_xlate_rulepair_t *apair = NULL; + int xlate_src = -1; + int xlate_dst = -1; ++ int ret = 0; + +- for(ipair = 0; ipair < nat46->npairs; ipair++) { +- apair = &nat46->pairs[ipair]; ++ apair = nat46_lpm(nat46, NAT46_IPV4_REMOTE, &hdr4->daddr); ++ if (!apair) { ++ return 0; ++ } + +- if(-1 == xlate_src) { +- if(xlate_v4_to_v6(nat46, &apair->local, &hdr4->saddr, v6saddr, sport)) { +- nat46debug(5, "Src addr %pI4 to %pI6 \n", &hdr4->saddr, v6saddr); +- xlate_src = ipair; +- } +- } +- if(-1 == xlate_dst) { +- if(xlate_v4_to_v6(nat46, &apair->remote, &hdr4->daddr, v6daddr, dport)) { +- nat46debug(5, "Dst addr %pI4 to %pI6 \n", &hdr4->daddr, v6daddr); +- xlate_dst = ipair; +- } +- } +- if( (xlate_src >= 0) && (xlate_dst >= 0) ) { +- break; +- } else { +- /* We did not match fully and there are more rules */ +- if((ipair+1 < nat46->npairs) && is_last_pair_in_group(apair)) { +- xlate_src = -1; +- xlate_dst = -1; +- } +- } ++ if (xlate_v4_to_v6(nat46, &apair->local, &hdr4->saddr, v6saddr, sport)) { ++ nat46debug(5, "Src addr %pI4 to %pI6 \n", &hdr4->saddr, v6saddr); ++ xlate_src = ipair; ++ } ++ if (xlate_v4_to_v6(nat46, &apair->remote, &hdr4->daddr, v6daddr, dport)) { ++ nat46debug(5, "Dst addr %pI4 to %pI6 \n", &hdr4->daddr, v6daddr); ++ xlate_dst = ipair; + } + nat46debug(5, "[nat46] pairs_xlate_v4_to_v6_outer result: src %d dst %d", xlate_src, xlate_dst); + if ( (xlate_src >= 0) && (xlate_dst >= 0) ) { +- return 1; ++ ret = 1; ++ } else { ++ nat46debug(1, "[nat46] Could not find a translation pair v4->v6"); + } +- +- nat46debug(1, "[nat46] Could not find a translation pair v4->v6"); +- +- return 0; ++ return ret; + } + + int xlate_4_to_6(struct net_device *dev, struct iphdr *hdr4, uint16_t sport, uint16_t dport, void *v6saddr, void *v6daddr) { +- return pairs_xlate_v4_to_v6_outer(netdev_nat46_instance(dev), hdr4, &sport, &dport, v6saddr, v6daddr); ++ nat46_xlate_rulepair_t apair; ++ return pairs_xlate_v4_to_v6_outer(netdev_nat46_instance(dev), &apair, hdr4, &sport, &dport, v6saddr, v6daddr); + } + EXPORT_SYMBOL(xlate_4_to_6); + +-/* FIXME: This is a workaround, till the LPM is not added. The sport & dport in inner header will be dport & sport of the outer +- * header, respectively. Hence, dest. and source ips of inner header will be found in local & remote rules, respectively. +- * Will work only for a pair of local & remote rules. Once LPM is brought in, this method can be removed and +- * pairs_xlate_v4_to_v6_outer be used instead. ++/* ++ * The sport & dport in inner header will be dport & sport of the outer header, respectively. ++ * Hence, dest. and source ips of inner header will be found in local & remote rules, respectively. + */ + int pairs_xlate_v4_to_v6_inner(nat46_instance_t *nat46, struct iphdr *iph, + uint16_t sport, uint16_t dport, void *v6saddr, void *v6daddr) { +@@ -1788,35 +1990,27 @@ int pairs_xlate_v4_to_v6_inner(nat46_ins + int xlate_src = -1; + int xlate_dst = -1; + +- for (ipair = 0; ipair < nat46->npairs; ipair++) { +- apair = &nat46->pairs[ipair]; ++ apair = nat46_lpm(nat46, NAT46_IPV4_REMOTE, &iph->saddr); ++ if (!apair) { ++ return 0; ++ } + +- if (-1 == xlate_dst) { +- if (xlate_v4_to_v6(nat46, &apair->local, &iph->daddr, v6daddr, &dport)) { +- nat46debug(3, "Dst addr %pI4 to %pI6 \n", &iph->daddr, v6daddr); +- xlate_dst = ipair; +- } +- } +- if (-1 == xlate_src) { +- if(xlate_v4_to_v6(nat46, &apair->remote, &iph->saddr, v6saddr, &sport)) { +- nat46debug(3, "Src addr %pI4 to %pI6 \n", &iph->saddr, v6saddr); +- xlate_src = ipair; +- } +- } +- if ((xlate_src >= 0) && (xlate_dst >= 0)) { +- /* we did manage to translate it */ +- nat46debug(5, "[nat46] Inner header xlate results: src %d dst %d", xlate_src, xlate_dst); +- return 1; +- } else { +- /* We did not match fully and there are more rules */ +- if((ipair+1 < nat46->npairs) && is_last_pair_in_group(apair)) { +- xlate_src = -1; +- xlate_dst = -1; +- } +- } +-} ++ if (xlate_v4_to_v6(nat46, &apair->local, &iph->daddr, v6daddr, &dport)) { ++ nat46debug(3, "Dst addr %pI4 to %pI6 \n", &iph->daddr, v6daddr); ++ xlate_dst = ipair; ++ } ++ if (xlate_v4_to_v6(nat46, &apair->remote, &iph->saddr, v6saddr, &sport)) { ++ nat46debug(3, "Src addr %pI4 to %pI6 \n", &iph->saddr, v6saddr); ++ xlate_src = ipair; ++ } ++ if ((xlate_src >= 0) && (xlate_dst >= 0)) { ++ /* we did manage to translate it */ ++ nat46debug(5, "[nat46] Inner header xlate results: src %d dst %d", xlate_src, xlate_dst); ++ return 1; ++ } else { ++ nat46debug(1, "[nat46] Could not find a translation pair v4->v6"); ++ } + +- nat46debug(1, "[nat46] Could not find a translation pair v4->v6"); + return 0; + } + +@@ -1913,6 +2107,7 @@ static uint16_t xlate_pkt_in_err_v4_to_v + + void nat46_ipv4_input(struct sk_buff *old_skb) { + nat46_instance_t *nat46 = get_nat46_instance(old_skb); ++ nat46_xlate_rulepair_t apair; + struct sk_buff *new_skb; + uint16_t sport = 0, dport = 0, ret = 0; + +@@ -1979,7 +2174,7 @@ void nat46_ipv4_input(struct sk_buff *ol + having_l4 = 1; + } + +- if(!pairs_xlate_v4_to_v6_outer(nat46, hdr4, having_l4 ? &sport : NULL, having_l4 ? &dport : NULL, v6saddr, v6daddr)) { ++ if(!pairs_xlate_v4_to_v6_outer(nat46, &apair, hdr4, having_l4 ? &sport : NULL, having_l4 ? &dport : NULL, v6saddr, v6daddr)) { + nat46debug(0, "[nat46] Could not translate v4->v6"); + goto done; + } +--- a/nat46/modules/nat46-core.h ++++ b/nat46/modules/nat46-core.h +@@ -23,6 +23,15 @@ + // #define nat46debug(level, format, ...) + #define nat46debug(level, format, ...) do { if(nat46->debug >= level) { printk(format "\n", ##__VA_ARGS__); } } while (0) + ++#define U8_MASK (uint8_t)(0xFF) ++#define U32_MASK (uint32_t)(~0U) ++#define BITS_PER_BYTE 8 ++#define PSID_LEN_MAX 16 ++#define NUM_RULE_PAIRS_MAX 32 ++#define IPV4_BITS_MAX 32 ++#define EA_LEN_MAX 48 ++#define IPV6_BITS_MAX 128 ++ + #define IPV6HDRSIZE 40 + #define IPV4HDRSIZE 20 + #define IPV6V4HDRDELTA (IPV6HDRSIZE - IPV4HDRSIZE) +@@ -39,6 +48,17 @@ typedef enum { + NAT46_XLATE_RFC6052 + } nat46_xlate_style_t; + ++/* ++ * Enumeration for sorting pairs based on ++ * type of prefix length. ++ */ ++typedef enum { ++ NAT46_IPV4_LOCAL = 0, ++ NAT46_IPV4_REMOTE, ++ NAT46_IPV6_LOCAL, ++ NAT46_IPV6_REMOTE ++} nat46_rule_type_t; ++ + #define NAT46_SIGNATURE 0x544e3634 + #define FREED_NAT46_SIGNATURE 0xdead544e + +@@ -64,7 +84,11 @@ typedef struct { + int debug; + + int npairs; +- nat46_xlate_rulepair_t pairs[0]; /* npairs */ ++ nat46_xlate_rulepair_t pairs[NUM_RULE_PAIRS_MAX]; /* npairs */ ++ nat46_xlate_rulepair_t sorted_ipv4_local_pairs[NUM_RULE_PAIRS_MAX]; /* npairs */ ++ nat46_xlate_rulepair_t sorted_ipv4_remote_pairs[NUM_RULE_PAIRS_MAX]; /* npairs */ ++ nat46_xlate_rulepair_t sorted_ipv6_local_pairs[NUM_RULE_PAIRS_MAX]; /* npairs */ ++ nat46_xlate_rulepair_t sorted_ipv6_remote_pairs[NUM_RULE_PAIRS_MAX]; /* npairs */ + } nat46_instance_t; + + void nat46_ipv6_input(struct sk_buff *old_skb); +--- a/nat46/modules/nat46-netdev.c ++++ b/nat46/modules/nat46-netdev.c +@@ -263,7 +263,13 @@ int nat46_insert(char *devname, char *bu + int ret = -1; + if(dev) { + nat46_instance_t *nat46 = netdev_nat46_instance(dev); +- nat46_instance_t *nat46_new = alloc_nat46_instance(nat46->npairs+1, nat46, 0, 1); ++ nat46_instance_t *nat46_new; ++ if(nat46->npairs == NUM_RULE_PAIRS_MAX) { ++ printk("Could not insert a new rule on device %s\n", devname); ++ return ret; ++ } ++ ++ nat46_new = alloc_nat46_instance(nat46->npairs+1, nat46, 0, 1); + if(nat46_new) { + netdev_nat46_set_instance(dev, nat46_new); + ret = nat46_set_ipair_config(nat46_new, 0, buf, strlen(buf)); diff --git a/package/kernel/nat46/patches/106-dummy_header.patch b/package/kernel/nat46/patches/106-dummy_header.patch new file mode 100644 index 00000000000000..66754fd6378d18 --- /dev/null +++ b/package/kernel/nat46/patches/106-dummy_header.patch @@ -0,0 +1,100 @@ +Author: Pavithra R +Date: Wed Aug 5 10:09:45 2020 +0530 + +nat46: Add dummy fragment header for DF=0 IPv4 packet. + +This patch is propagated from 4.4 kernel commit +b45f19e86ebcc19ea26d5e014bfdcb837148f99e. + +Add dummy fragment header to IPv6 translated packet for +every DF=0 IPv4 packet. + +Change-Id: Id72945eefac030e95e4fd18305e48c46e525def3 +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -21,6 +21,7 @@ + + #include "nat46-glue.h" + #include "nat46-core.h" ++#include "nat46-module.h" + + static uint16_t xlate_pkt_in_err_v4_to_v6(nat46_instance_t *nat46, struct iphdr *iph, + struct sk_buff *old_skb, uint16_t *sport, uint16_t *dport); +@@ -2134,6 +2135,11 @@ void nat46_ipv4_input(struct sk_buff *ol + nat46debug(5, "nat46_ipv4_input protocol: %d, len: %d, flags: %02x", hdr4->protocol, old_skb->len, IPCB(old_skb)->flags); + if(0 == (ntohs(hdr4->frag_off) & 0x3FFF) ) { /* Checking for MF */ + check_for_l4 = 1; ++ if (add_dummy_header) { ++ if (0 == (ntohs(hdr4->frag_off) & IP_DF)) { ++ add_frag_header = 1; ++ } ++ } + } else { + add_frag_header = 1; + if (0 == (ntohs(hdr4->frag_off) & 0x1FFF)) { /* Checking for Frag Offset */ +@@ -2263,3 +2269,24 @@ bool nat46_get_rule_config(struct net_de + return true; + } + EXPORT_SYMBOL(nat46_get_rule_config); ++ ++/* ++ * Function to get MAP-T rules and flags. ++ */ ++bool nat46_get_info(struct net_device *dev, nat46_xlate_rulepair_t **nat46_rule_pair, ++ int *count, u8 *flag) { ++ if ((!dev) || (!nat46_rule_pair) || (!count) || (!flag)) { ++ return false; ++ } ++ ++ if (!nat46_get_rule_config(dev, nat46_rule_pair, count)) { ++ return false; ++ } ++ ++ /* Check add dummy header flag */ ++ if (add_dummy_header) { ++ *flag = ADD_DUMMY_HEADER; ++ } ++ return true; ++} ++EXPORT_SYMBOL(nat46_get_info); +--- a/nat46/modules/nat46-core.h ++++ b/nat46/modules/nat46-core.h +@@ -32,6 +32,9 @@ + #define EA_LEN_MAX 48 + #define IPV6_BITS_MAX 128 + ++/* Flag definations for MAP-T */ ++#define ADD_DUMMY_HEADER 0x01 ++ + #define IPV6HDRSIZE 40 + #define IPV4HDRSIZE 20 + #define IPV6V4HDRDELTA (IPV6HDRSIZE - IPV4HDRSIZE) +@@ -110,5 +113,6 @@ int xlate_6_to_4(struct net_device *dev, + int xlate_4_to_6(struct net_device *dev, struct iphdr *hdr4, uint16_t sport, uint16_t dport, void *v6saddr, void *v6daddr); + bool nat46_get_rule_config(struct net_device *dev, nat46_xlate_rulepair_t **nat46_rule_pair, int *count); + int nat46_get_npairs(struct net_device *dev); +- ++bool nat46_get_info(struct net_device *dev, nat46_xlate_rulepair_t **nat46_rule_pair, ++ int *count, u8 *flag); + #endif +--- a/nat46/modules/nat46-module.c ++++ b/nat46/modules/nat46-module.c +@@ -57,6 +57,9 @@ MODULE_DESCRIPTION("NAT46 stateless tran + int debug = 0; + module_param(debug, int, 0); + MODULE_PARM_DESC(debug, "debugging messages level (default=1)"); ++bool add_dummy_header = 0; ++module_param(add_dummy_header, bool, 0); ++MODULE_PARM_DESC(add_dummy_header, "Add dummy fragment header"); + + static struct proc_dir_entry *nat46_proc_entry; + static struct proc_dir_entry *nat46_proc_parent; +--- a/nat46/modules/nat46-module.h ++++ b/nat46/modules/nat46-module.h +@@ -14,3 +14,4 @@ + */ + + extern int debug; ++extern bool add_dummy_header; diff --git a/package/kernel/nat46/patches/107-stats.patch b/package/kernel/nat46/patches/107-stats.patch new file mode 100644 index 00000000000000..2fcfef623f0856 --- /dev/null +++ b/package/kernel/nat46/patches/107-stats.patch @@ -0,0 +1,134 @@ +Author: Pavithra R +Date: Wed Aug 5 10:57:25 2020 +0530 + +nat46: Add support for 64-bits stats. + +This patch is propagated from 4.4 kernel commit +4a2d1dd9bc9331392c7a4947126c361217c82e0c + +Add 64-bits stats functionality for MAP-T interface. + +Change-Id: I4a6f9c7ed3554ac0ec672aa5fa283be2e95cfdc0 +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-netdev.c ++++ b/nat46/modules/nat46-netdev.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include + #include "nat46-core.h" + #include "nat46-module.h" +@@ -40,16 +41,40 @@ static u8 netdev_count = 0; + + static int nat46_netdev_up(struct net_device *dev); + static int nat46_netdev_down(struct net_device *dev); +- ++static int nat46_netdev_init(struct net_device *dev); ++static void nat46_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *tot); + static netdev_tx_t nat46_netdev_xmit(struct sk_buff *skb, struct net_device *dev); + + + static const struct net_device_ops nat46_netdev_ops = { ++ .ndo_init = nat46_netdev_init, /* device specific initialization */ + .ndo_open = nat46_netdev_up, /* Called at ifconfig nat46 up */ + .ndo_stop = nat46_netdev_down, /* Called at ifconfig nat46 down */ + .ndo_start_xmit = nat46_netdev_xmit, /* REQUIRED, must return NETDEV_TX_OK */ ++ .ndo_get_stats64 = nat46_get_stats64, /* 64 bit device stats */ + }; + ++static int nat46_netdev_init(struct net_device *dev) ++{ ++ int i; ++ dev->tstats = alloc_percpu(struct pcpu_sw_netstats); ++ if (!dev->tstats) { ++ return -ENOMEM; ++ } ++ ++ for_each_possible_cpu(i) { ++ struct pcpu_sw_netstats *ipt_stats; ++ ipt_stats = per_cpu_ptr(dev->tstats, i); ++ u64_stats_init(&ipt_stats->syncp); ++ } ++ return 0; ++} ++ ++static void nat46_netdev_resource_free(struct net_device *dev) ++{ ++ free_percpu(dev->tstats); ++} ++ + static int nat46_netdev_up(struct net_device *dev) + { + netif_start_queue(dev); +@@ -64,8 +89,13 @@ static int nat46_netdev_down(struct net_ + + static netdev_tx_t nat46_netdev_xmit(struct sk_buff *skb, struct net_device *dev) + { +- dev->stats.rx_packets++; +- dev->stats.rx_bytes += skb->len; ++ struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats); ++ ++ u64_stats_update_begin(&tstats->syncp); ++ tstats->rx_packets++; ++ tstats->rx_bytes += skb->len; ++ u64_stats_update_end(&tstats->syncp); ++ put_cpu_ptr(tstats); + if(ETH_P_IP == ntohs(skb->protocol)) { + nat46_ipv4_input(skb); + } +@@ -77,22 +107,38 @@ static netdev_tx_t nat46_netdev_xmit(str + } + + void nat46_netdev_count_xmit(struct sk_buff *skb, struct net_device *dev) { +- dev->stats.tx_packets++; +- dev->stats.tx_bytes += skb->len; ++ struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats); ++ ++ u64_stats_update_begin(&tstats->syncp); ++ tstats->tx_packets++; ++ tstats->tx_bytes += skb->len; ++ u64_stats_update_end(&tstats->syncp); ++ put_cpu_ptr(tstats); + } + + void nat46_update_stats(struct net_device *dev, uint32_t rx_packets, uint32_t rx_bytes, + uint32_t tx_packets, uint32_t tx_bytes, uint32_t rx_dropped, uint32_t tx_dropped) + { +- dev->stats.rx_packets += rx_packets; +- dev->stats.rx_bytes += rx_bytes; +- dev->stats.tx_packets += tx_packets; +- dev->stats.tx_bytes += tx_bytes; ++ struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats); ++ ++ u64_stats_update_begin(&tstats->syncp); ++ tstats->rx_packets += rx_packets; ++ tstats->rx_bytes += rx_bytes; ++ tstats->tx_packets += tx_packets; ++ tstats->tx_bytes += tx_bytes; + dev->stats.rx_dropped += rx_dropped; + dev->stats.tx_dropped += tx_dropped; ++ u64_stats_update_end(&tstats->syncp); ++ put_cpu_ptr(tstats); + } + EXPORT_SYMBOL(nat46_update_stats); + ++static void nat46_get_stats64(struct net_device *dev, ++ struct rtnl_link_stats64 *tot) ++{ ++ dev_get_tstats64(dev, tot); ++} ++ + void *netdev_nat46_instance(struct net_device *dev) { + nat46_netdev_priv_t *priv = netdev_priv(dev); + return priv->nat46; +@@ -116,6 +162,7 @@ static void nat46_netdev_setup(struct ne + priv->nat46 = nat46; + + dev->netdev_ops = &nat46_netdev_ops; ++ dev->priv_destructor = nat46_netdev_resource_free; + dev->type = ARPHRD_NONE; + dev->hard_header_len = 0; + dev->addr_len = 0; diff --git a/package/kernel/nat46/patches/108-ce_port.patch b/package/kernel/nat46/patches/108-ce_port.patch new file mode 100644 index 00000000000000..18d33089f4cd66 --- /dev/null +++ b/package/kernel/nat46/patches/108-ce_port.patch @@ -0,0 +1,134 @@ +Author: Pavithra R +Date: Wed Aug 5 18:59:20 2020 +0530 + +nat46: Copy CE's port number to IPv6 fragment header. + +This patch is propagated from kernel 4.4 commit +7886fd3eb081c7767b02685593bc1d19deaecba8 + +Copy CE's port number to the lower 16-bits of IPv6 identification +number. + +Change-Id: I6946e93bf8bed4c1378d19e75db0729097e0d9eb +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -25,6 +25,7 @@ + + static uint16_t xlate_pkt_in_err_v4_to_v6(nat46_instance_t *nat46, struct iphdr *iph, + struct sk_buff *old_skb, uint16_t *sport, uint16_t *dport); ++static DEFINE_SPINLOCK(port_id_lock); + + void + nat46debug_dump(nat46_instance_t *nat46, int level, void *addr, int len) +@@ -2106,6 +2107,73 @@ static uint16_t xlate_pkt_in_err_v4_to_v + return 1; + } + ++/* Return the port number from CE's port set */ ++static uint16_t nat46_get_ce_port(nat46_xlate_rulepair_t *pair, uint16_t sport) ++{ ++ /* ++ * 'psid_bits_len' represents number of bits in PSID. ++ * 'offset' represents offset of PSID in a port number. ++ */ ++ uint8_t psid_bits_len, offset, port_set_bitmask; ++ ++ /* ++ * 'psid16' represent PSID value. ++ * 'm' represents number of bits in excluded port set. ++ * 'a' represents number of bits in a 16-bit port number after PSID. ++ * It is used to control number of port in one contiguous port set. ++ * ++ * Name of a variable 'a' and 'm' is as per Appendix B of [RFC7597]. ++ */ ++ uint16_t psid16, value, m, a; ++ nat46_xlate_rule_t *rule; ++ ++ /* stores to last port number from CE's port set */ ++ static uint16_t port_num; ++ ++ rule = &pair->local; ++ offset = rule->psid_offset; ++ ++ if (rule->ea_len + rule->v4_pref_len > IPV4_BITS_MAX) { ++ psid_bits_len = rule->ea_len - (IPV4_BITS_MAX - rule->v4_pref_len); ++ } else { ++ return 0; ++ } ++ a = PSID_LEN_MAX - offset - psid_bits_len; ++ psid16 = (ntohs(sport) >> a) & (0xffff >> (PSID_LEN_MAX - psid_bits_len)); ++ ++ spin_lock(&port_id_lock); ++ ++ /* Start case */ ++ if (0 == port_num) { ++ m = (offset) ? 1 : 0; ++ port_num = (m << (PSID_LEN_MAX - offset)) | (psid16 << a); ++ value = port_num; ++ spin_unlock(&port_id_lock); ++ return value; ++ } ++ ++ /* End of one port set */ ++ port_set_bitmask = (1 << a) - 1; ++ value = port_num & port_set_bitmask; ++ if (0 == (value ^ port_set_bitmask)) { ++ m = port_num >> (PSID_LEN_MAX - offset); ++ m++; ++ /* End case */ ++ if (m >= (1 << offset)) { ++ m = (offset) ? 1 : 0; ++ } ++ port_num = (m << (PSID_LEN_MAX - offset)) | (psid16 << a); ++ value = port_num; ++ spin_unlock(&port_id_lock); ++ return value; ++ } ++ ++ port_num++; ++ value = port_num; ++ spin_unlock(&port_id_lock); ++ return value; ++} ++ + void nat46_ipv4_input(struct sk_buff *old_skb) { + nat46_instance_t *nat46 = get_nat46_instance(old_skb); + nat46_xlate_rulepair_t apair; +@@ -2226,9 +2294,34 @@ void nat46_ipv4_input(struct sk_buff *ol + + if (add_frag_header) { + struct frag_hdr *fh = (struct frag_hdr*)(hdr6 + 1); ++ uint16_t ce_port_num = 0; ++ ++ /* Flag to represent whether PSID is assigned to MAP-T node or not */ ++ bool is_psid = false; ++ + fh->frag_off = htons(((ntohs(hdr4->frag_off) >> 13) & 7) + ((ntohs(hdr4->frag_off) & 0x1FFF) << 3)); + fh->nexthdr = hdr4->protocol; +- fh->identification = htonl(ntohs(hdr4->id)); ++ ++ /* ++ * PSID assigned MAP-T node will have non-zero ea_len and we are currently ++ * only supporting NAT46_XLATE_MAP as the CE's rule style. ++ */ ++ is_psid = (apair.local.style == NAT46_XLATE_MAP) && apair.local.ea_len; ++ if (is_psid) { ++ ce_port_num = nat46_get_ce_port(nat46->pairs, sport); ++ nat46debug(10, "\n ce port number is %02x\n", ce_port_num); ++ ++ /* Assign CE's port number as the fragment identifier */ ++ if (ce_port_num) { ++ fh->identification = htonl(ce_port_num); ++ } else { ++ fh->identification = htonl(ntohs(hdr4->id)); ++ } ++ } else { ++ fh->identification = htonl(ntohs(hdr4->id)); ++ } ++ ++ + } + ip6_update_csum(new_skb, hdr6, add_frag_header); + diff --git a/package/kernel/nat46/patches/109-fragment_if_not_df_and_larger_than_mtu.patch b/package/kernel/nat46/patches/109-fragment_if_not_df_and_larger_than_mtu.patch new file mode 100644 index 00000000000000..3bb07f0396a9ad --- /dev/null +++ b/package/kernel/nat46/patches/109-fragment_if_not_df_and_larger_than_mtu.patch @@ -0,0 +1,30 @@ +Author: Pavithra R +Date: Wed Aug 5 19:26:48 2020 +0530 + +nat46: Fix the issue of packets not fragmented + +This patch is propagated from the kernel 4.4 commit +e598f9c249092abd7c7978fe99b6690884f225c9 + +when packets size is larger than the MTU of dst, if DF flag is not set, +fragment it instead of dropping it with PktTooBig ICMPv6 message. + +Change-Id: I380d42f59bb4f46a45e542f251f5710f2cca8b62 +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -2203,10 +2203,11 @@ void nat46_ipv4_input(struct sk_buff *ol + nat46debug(5, "nat46_ipv4_input protocol: %d, len: %d, flags: %02x", hdr4->protocol, old_skb->len, IPCB(old_skb)->flags); + if(0 == (ntohs(hdr4->frag_off) & 0x3FFF) ) { /* Checking for MF */ + check_for_l4 = 1; +- if (add_dummy_header) { +- if (0 == (ntohs(hdr4->frag_off) & IP_DF)) { ++ if (0 == (ntohs(hdr4->frag_off) & IP_DF)) { ++ if (add_dummy_header) { + add_frag_header = 1; + } ++ old_skb->ignore_df = 1; + } + } else { + add_frag_header = 1; diff --git a/package/kernel/nat46/patches/110-icmp_error_not_handled.patch b/package/kernel/nat46/patches/110-icmp_error_not_handled.patch new file mode 100644 index 00000000000000..7f0ead0773e5aa --- /dev/null +++ b/package/kernel/nat46/patches/110-icmp_error_not_handled.patch @@ -0,0 +1,99 @@ +Author: Pavithra R +Date: Wed Aug 5 20:16:27 2020 +0530 + +nat46: fix ICMPv6 error message dropped locally + +This patch is propagated from the kernel 4.4 commit +1b96bd0e9ee9182566b119741854c03bf4b94a99 + +While routing IPv6 packets from a customer-side translated device (CLAT) +to a provider-side translated device (PLAT), it is possible that the IPv6 +destination is unknown. In such a scenario, the IPv6 stack must send back +an ICMP error. However, the source IPv6 address of this error message does +not have a MAP-T translation. According to RFC2473, the translation layer +should use the tunnel's own IPv4 address for the IPv6 ICMP packet's source +address. + +Change-Id: I784473cddf9214843c466d10763cb66852139ef6 +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -1697,17 +1697,19 @@ static uint16_t nat46_fixup_icmp(nat46_i + return ret; + } + +-int pairs_xlate_v6_to_v4_outer(nat46_instance_t *nat46, nat46_xlate_rulepair_t *apair, ++int pairs_xlate_v6_to_v4_outer(nat46_instance_t *nat46, nat46_xlate_rulepair_t **papair, + struct ipv6hdr *ip6h, uint16_t proto, __u32 *pv4saddr, __u32 *pv4daddr) { + int ipair = 0; + int xlate_src = -1; + int xlate_dst = -1; ++ nat46_xlate_rulepair_t *apair; + + apair = nat46_lpm(nat46, NAT46_IPV6_REMOTE, &ip6h->saddr); + if (!apair) { + return 0; + } + ++ *papair = apair; + if (xlate_v6_to_v4(nat46, &apair->local, &ip6h->daddr, pv4daddr)) { + nat46debug(5, "Dst addr %pI6 to %pI4 \n", &ip6h->daddr, pv4daddr); + xlate_dst = ipair; +@@ -1734,14 +1736,14 @@ int pairs_xlate_v6_to_v4_outer(nat46_ins + } + + int xlate_6_to_4(struct net_device *dev, struct ipv6hdr *ip6h, uint16_t proto, __u32 *pv4saddr, __u32 *pv4daddr) { +- nat46_xlate_rulepair_t apair; ++ nat46_xlate_rulepair_t *apair; + return pairs_xlate_v6_to_v4_outer(netdev_nat46_instance(dev), &apair, ip6h, proto, pv4saddr, pv4daddr); + } + EXPORT_SYMBOL(xlate_6_to_4); + + void nat46_ipv6_input(struct sk_buff *old_skb) { + struct ipv6hdr *ip6h = ipv6_hdr(old_skb); +- nat46_xlate_rulepair_t apair; ++ nat46_xlate_rulepair_t *apair; + nat46_instance_t *nat46 = get_nat46_instance(old_skb); + uint16_t proto; + uint16_t frag_off; +@@ -1803,8 +1805,37 @@ void nat46_ipv6_input(struct sk_buff *ol + } + + if (!pairs_xlate_v6_to_v4_outer(nat46, &apair, ip6h, proto, &v4saddr, &v4daddr)) { +- nat46debug(0, "[nat46] Could not translate v6->v4"); +- goto done; ++ if (proto == NEXTHDR_ICMP) { ++ struct icmp6hdr *icmp6h = add_offset(ip6h, v6packet_l3size); ++ struct ipv6hdr *ip6h_inner = (struct ipv6hdr *) (icmp6h + 1); ++ struct ipv6hdr hdr6; ++ switch(icmp6h->icmp6_type) { ++ case ICMPV6_DEST_UNREACH: ++ case ICMPV6_PKT_TOOBIG: ++ case ICMPV6_TIME_EXCEED: ++ case ICMPV6_PARAMPROB: ++ /* ++ * For icmpv6 error message, using the original message ++ * address to locate the apair one more time according ++ * to the RFC 2473, and use the ipv4 address of the ++ * tunnel as SRC ipv4 address ++ */ ++ memcpy(&hdr6.saddr, &ip6h_inner->daddr, 16); ++ memcpy(&hdr6.daddr, &ip6h_inner->saddr, 16); ++ if (!pairs_xlate_v6_to_v4_outer(nat46, &apair, &hdr6, proto, &v4saddr, &v4daddr)) { ++ nat46debug(0, "[nat46] Could not translate v6->v4"); ++ goto done; ++ } ++ v4saddr = apair->local.v4_pref; ++ break; ++ default: ++ nat46debug(0, "[nat46] Could not translate v6->v4"); ++ goto done; ++ } ++ } else { ++ nat46debug(0, "[nat46] Could not translate v6->v4"); ++ goto done; ++ } + } + + if (check_for_l4) { diff --git a/package/kernel/nat46/patches/111-fix_null_point_reference.patch b/package/kernel/nat46/patches/111-fix_null_point_reference.patch new file mode 100644 index 00000000000000..4386c41e9a8ed9 --- /dev/null +++ b/package/kernel/nat46/patches/111-fix_null_point_reference.patch @@ -0,0 +1,40 @@ +Author: Pavithra R +Date: Wed Aug 5 20:35:00 2020 +0530 + +nat46: Fix null pointer dereference issue + +This patch is propagated from the kernel 4.4 commit +5bdf9bd5500c45ab5a3fd43e60c40a09d5e5a13d + +get_nat46_instance possibly returns null point, before using the returning +point, caller needs to check if it is null. + +Change-Id: Id407a71ca8eccd60a713c34429e7e3f16e2cdd12 +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -1758,6 +1758,11 @@ void nat46_ipv6_input(struct sk_buff *ol + int l3_infrag_payload_len = ntohs(ip6h->payload_len); + int check_for_l4 = 0; + ++ if (nat46 == NULL) { ++ printk("nat46:%p skb is dropped for no valid instance found\n", old_skb); ++ return; ++ } ++ + nat46debug(4, "nat46_ipv6_input packet"); + + if(ip6_input_not_interested(nat46, ip6h, old_skb)) { +@@ -2222,6 +2227,11 @@ void nat46_ipv4_input(struct sk_buff *ol + + char v6saddr[16], v6daddr[16]; + ++ if (nat46 == NULL) { ++ printk("nat46:%p skb is dropped for no valid instance found\n", old_skb); ++ return; ++ } ++ + tclass = hdr4->tos; + + memset(v6saddr, 1, 16); diff --git a/package/kernel/nat46/patches/112-fix_icmp_crash.patch b/package/kernel/nat46/patches/112-fix_icmp_crash.patch new file mode 100644 index 00000000000000..61eeae17e43e05 --- /dev/null +++ b/package/kernel/nat46/patches/112-fix_icmp_crash.patch @@ -0,0 +1,40 @@ +Author: Pavithra R +Date: Wed Aug 5 20:57:33 2020 +0530 + +Fix crash of free skb + +This patch is propagated from the 4.4 kernel commit +b959b0d45c66ae004a5bfc1687980093fa5b8cc3. + +This is caused by the translation of the inner ipv6 header, it +move memory by the inner head's tot_len which is not exact that +inner packet will be trimmed for icmp error packets size no more +than 576. + +Change-Id: Id5d41fa0721acdf6ea76721c45415fe3be432207 +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -2115,7 +2115,9 @@ static uint16_t xlate_pkt_in_err_v4_to_v + + if (skb_tailroom(old_skb) >= IPV6V4HDRDELTA){ + skb_put(old_skb, IPV6V4HDRDELTA); +- memmove(((char *)iiph + IPV6HDRSIZE), (iiph + 1), ntohs(iiph->tot_len) - IPV4HDRSIZE); ++ /* ErrorICMP size is less than 576, the inner ipv4 packet will be trimmed */ ++ memmove(((char *)iiph + IPV6HDRSIZE), (iiph + 1), ++ ntohs(iph->tot_len) - 2 * IPV4HDRSIZE - sizeof(struct icmphdr)); + memcpy(iiph, &ip6h, IPV6HDRSIZE); + } + else { +@@ -2128,7 +2130,9 @@ static uint16_t xlate_pkt_in_err_v4_to_v + + skb_put(old_skb, IPV6V4HDRDELTA); + iiph = (struct iphdr *)(icmp_hdr(old_skb) + 1); +- memmove(((char *)iiph + IPV6HDRSIZE), (iiph + 1), ntohs(iiph->tot_len) - IPV4HDRSIZE); ++ /* ErrorICMP size is less than 576, the inner ipv4 packet will be trimmed */ ++ memmove(((char *)iiph + IPV6HDRSIZE), (iiph + 1), ++ ntohs(iph->tot_len) - 2 * IPV4HDRSIZE - sizeof(struct icmphdr)); + memcpy(iiph, &ip6h, IPV6HDRSIZE); + nat46 = get_nat46_instance(old_skb); + iph = ip_hdr(old_skb); diff --git a/package/kernel/nat46/patches/113-fix_delete_race_condition.patch b/package/kernel/nat46/patches/113-fix_delete_race_condition.patch new file mode 100644 index 00000000000000..add6c36a46b97a --- /dev/null +++ b/package/kernel/nat46/patches/113-fix_delete_race_condition.patch @@ -0,0 +1,52 @@ +Author: Pavithra R +Date: Wed Aug 5 21:16:50 2020 +0530 + +nat46: fix nat46 crash during stability test + +This patch is propagated from the kernel 4.4 commit +8a2df2e4170f6f9b7eb0930d067e197bfec68129 + +when deleting the same device in a very close time, the first deletion +is not finished yet, the second one will hit the BUG_ON. + +Change-Id: I09ec95a132e925a304b57c35d1cb51619be37229 +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-module.c ++++ b/nat46/modules/nat46-module.c +@@ -61,6 +61,7 @@ bool add_dummy_header = 0; + module_param(add_dummy_header, bool, 0); + MODULE_PARM_DESC(add_dummy_header, "Add dummy fragment header"); + ++static DEFINE_MUTEX(add_del_lock); + static struct proc_dir_entry *nat46_proc_entry; + static struct proc_dir_entry *nat46_proc_parent; + +@@ -115,19 +116,27 @@ static ssize_t nat46_proc_write(struct f + if (0 == strcmp(arg_name, "add")) { + devname = get_devname(&tail); + printk(KERN_INFO "nat46: adding device (%s)\n", devname); ++ mutex_lock(&add_del_lock); + nat46_create(devname); ++ mutex_unlock(&add_del_lock); + } else if (0 == strcmp(arg_name, "del")) { + devname = get_devname(&tail); + printk(KERN_INFO "nat46: deleting device (%s)\n", devname); ++ mutex_lock(&add_del_lock); + nat46_destroy(devname); ++ mutex_unlock(&add_del_lock); + } else if (0 == strcmp(arg_name, "config")) { + devname = get_devname(&tail); + printk(KERN_INFO "nat46: configure device (%s) with '%s'\n", devname, tail); ++ mutex_lock(&add_del_lock); + nat46_configure(devname, tail); ++ mutex_unlock(&add_del_lock); + } else if (0 == strcmp(arg_name, "insert")) { + devname = get_devname(&tail); + printk(KERN_INFO "nat46: insert new rule into device (%s) with '%s'\n", devname, tail); ++ mutex_lock(&add_del_lock); + nat46_insert(devname, tail); ++ mutex_unlock(&add_del_lock); + } + } + diff --git a/package/kernel/nat46/patches/114-fix-get-release-instance-protect.patch b/package/kernel/nat46/patches/114-fix-get-release-instance-protect.patch new file mode 100644 index 00000000000000..9258f783cd86b9 --- /dev/null +++ b/package/kernel/nat46/patches/114-fix-get-release-instance-protect.patch @@ -0,0 +1,51 @@ +Author: Pavithra R +Date: Thu Aug 13 12:59:50 2020 +0530 + +This patch is propogated from the kernel 4.4 commit +56e2435c782e7cdb5c274ea012557f525d0a3b88 + +nat46: fix race condition in the get and release operation + +when get and release the nat46 instance, it could run into race +condition, use spin_lock protect them. + +Change-Id: I7a38164699a5b856f3407dae592a3d8fc82e7ffe +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-glue.c ++++ b/nat46/modules/nat46-glue.c +@@ -18,6 +18,7 @@ + #include "nat46-glue.h" + #include "nat46-core.h" + ++static DEFINE_MUTEX(ref_lock); + int is_valid_nat46(nat46_instance_t *nat46) { + return (nat46 && (nat46->sig == NAT46_SIGNATURE)); + } +@@ -46,20 +47,25 @@ nat46_instance_t *alloc_nat46_instance(i + + nat46_instance_t *get_nat46_instance(struct sk_buff *sk) { + nat46_instance_t *nat46 = netdev_nat46_instance(sk->dev); ++ mutex_lock(&ref_lock); + if (is_valid_nat46(nat46)) { + nat46->refcount++; ++ mutex_unlock(&ref_lock); + return nat46; + } else { ++ mutex_unlock(&ref_lock); + printk("[nat46] get_nat46_instance: Could not find a valid NAT46 instance!"); + return NULL; + } + } + + void release_nat46_instance(nat46_instance_t *nat46) { ++ mutex_lock(&ref_lock); + nat46->refcount--; + if(0 == nat46->refcount) { +- printk("[nat46] release_nat46_instance: freeing nat46 instance with %d pairs\n", nat46->npairs); + nat46->sig = FREED_NAT46_SIGNATURE; ++ printk("[nat46] release_nat46_instance: freeing nat46 instance with %d pairs\n", nat46->npairs); + kfree(nat46); + } ++ mutex_unlock(&ref_lock); + } diff --git a/package/kernel/nat46/patches/115-export-ip6_update_csm-api.patch b/package/kernel/nat46/patches/115-export-ip6_update_csm-api.patch new file mode 100644 index 00000000000000..37cb14367e3d22 --- /dev/null +++ b/package/kernel/nat46/patches/115-export-ip6_update_csm-api.patch @@ -0,0 +1,33 @@ +Author: Pavithra R +Date: Tue Sep 22 10:49:35 2020 +0530 + +This patch is propogated from the kernel 4.4 commit +0907c30387c89bbec23f426891a756ca17e421ed + +nat46: export ip6_update_csum api + +export ip6_update_csum for other modules. + +Change-Id: I08de067f7a2d54d687c352154f1a1ab441652445 +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -1972,6 +1972,7 @@ void ip6_update_csum(struct sk_buff * sk + } + } + } ++EXPORT_SYMBOL(ip6_update_csum); + + int ip4_input_not_interested(nat46_instance_t *nat46, struct iphdr *iph, struct sk_buff *old_skb) { + if (old_skb->protocol != htons(ETH_P_IP)) { +--- a/nat46/modules/nat46-core.h ++++ b/nat46/modules/nat46-core.h +@@ -111,6 +111,7 @@ void release_nat46_instance(nat46_instan + + int xlate_6_to_4(struct net_device *dev, struct ipv6hdr *ip6h, uint16_t proto, __u32 *pv4saddr, __u32 *pv4daddr); + int xlate_4_to_6(struct net_device *dev, struct iphdr *hdr4, uint16_t sport, uint16_t dport, void *v6saddr, void *v6daddr); ++void ip6_update_csum(struct sk_buff * skb, struct ipv6hdr * ip6hdr, int do_atomic_frag); + bool nat46_get_rule_config(struct net_device *dev, nat46_xlate_rulepair_t **nat46_rule_pair, int *count); + int nat46_get_npairs(struct net_device *dev); + bool nat46_get_info(struct net_device *dev, nat46_xlate_rulepair_t **nat46_rule_pair, diff --git a/package/kernel/nat46/patches/116-rate-limit-the-print.patch b/package/kernel/nat46/patches/116-rate-limit-the-print.patch new file mode 100644 index 00000000000000..5719b8a601ca4d --- /dev/null +++ b/package/kernel/nat46/patches/116-rate-limit-the-print.patch @@ -0,0 +1,34 @@ +Author: Pavithra R +Date: Wed Sep 30 14:05:50 2020 +0530 + +nat46: Add rate limit to a print. + +This patch is propagated from the kernel 4.4 commit +d47f62508d2c105f236470e56bedbe279db0e6f1 + +Change-Id: I2119fbe54d630c3ed39535f1cb1b8a0d9d3199b4 +Signed-off-by: Pavithra R +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -1828,7 +1828,9 @@ void nat46_ipv6_input(struct sk_buff *ol + memcpy(&hdr6.saddr, &ip6h_inner->daddr, 16); + memcpy(&hdr6.daddr, &ip6h_inner->saddr, 16); + if (!pairs_xlate_v6_to_v4_outer(nat46, &apair, &hdr6, proto, &v4saddr, &v4daddr)) { +- nat46debug(0, "[nat46] Could not translate v6->v4"); ++ if (net_ratelimit()) { ++ nat46debug(0, "[nat46] Could not translate v6->v4"); ++ } + goto done; + } + v4saddr = apair->local.v4_pref; +@@ -2296,7 +2298,9 @@ void nat46_ipv4_input(struct sk_buff *ol + } + + if(!pairs_xlate_v4_to_v6_outer(nat46, &apair, hdr4, having_l4 ? &sport : NULL, having_l4 ? &dport : NULL, v6saddr, v6daddr)) { +- nat46debug(0, "[nat46] Could not translate v4->v6"); ++ if (net_ratelimit()) { ++ nat46debug(0, "[nat46] Could not translate v4->v6"); ++ } + goto done; + } + diff --git a/package/kernel/nat46/patches/117-fix-icmp-no-payload-bug.patch b/package/kernel/nat46/patches/117-fix-icmp-no-payload-bug.patch new file mode 100644 index 00000000000000..289963c0fb9af8 --- /dev/null +++ b/package/kernel/nat46/patches/117-fix-icmp-no-payload-bug.patch @@ -0,0 +1,34 @@ +Author: Pavithra R +Date: Wed Sep 30 14:27:37 2020 +0530 + +nat46: Fix for ICMP error packets with no payload. + +This patch is propagated from the kernel 4.4 commit +d8b29a8e31f948a5d7338aa69c36e0f654fcb9e4 + +When no payload is attached to the original packet, any +ICMP error message generated in response to such packets +gets dropped due to malformed packet at CE. + +During the translation of packet-in-error in ICMP, +the IPv6 header in ICMPv6 payload gets corrupted. +Hence, the translated packet gets dropped at CE. + +This fix updates the outer IPv4 header's total length +before translating to IPv6 header. + +Change-Id: Ifd9802afb50771de39b4c6fb734d36b0801613ec +Signed-off-by: Pavithra R +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -2137,9 +2137,8 @@ static uint16_t xlate_pkt_in_err_v4_to_v + memmove(((char *)iiph + IPV6HDRSIZE), (iiph + 1), + ntohs(iph->tot_len) - 2 * IPV4HDRSIZE - sizeof(struct icmphdr)); + memcpy(iiph, &ip6h, IPV6HDRSIZE); +- nat46 = get_nat46_instance(old_skb); +- iph = ip_hdr(old_skb); + } ++ iph->tot_len = htons(ntohs(iph->tot_len) + IPV6V4HDRDELTA); + + /* Swapping Ports for outer header */ + /* Another work-around till LPM is not present. */ diff --git a/package/kernel/nat46/patches/117-fix-proc_create-to-file_operations.patch b/package/kernel/nat46/patches/117-fix-proc_create-to-file_operations.patch new file mode 100644 index 00000000000000..b50d32feb0d4be --- /dev/null +++ b/package/kernel/nat46/patches/117-fix-proc_create-to-file_operations.patch @@ -0,0 +1,43 @@ +--- a/nat46/modules/nat46-module.c ++++ b/nat46/modules/nat46-module.c +@@ -15,6 +15,7 @@ + * + */ + ++#include + #include + #include + #include +@@ -82,7 +83,7 @@ static char *get_devname(char **ptail) + { + const int maxlen = IFNAMSIZ-1; + char *devname = get_next_arg(ptail); +- if(strlen(devname) > maxlen) { ++ if(devname && (strlen(devname) > maxlen)) { + printk(KERN_INFO "nat46: '%s' is " + "longer than %d chars, truncating\n", devname, maxlen); + devname[maxlen] = 0; +@@ -144,6 +145,7 @@ static ssize_t nat46_proc_write(struct f + return count; + } + ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5,6,0) + static const struct file_operations nat46_proc_fops = { + .owner = THIS_MODULE, + .open = nat46_proc_open, +@@ -152,6 +154,15 @@ static const struct file_operations nat4 + .release = single_release, + .write = nat46_proc_write, + }; ++#else ++static const struct proc_ops nat46_proc_fops = { ++ .proc_open = nat46_proc_open, ++ .proc_read = seq_read, ++ .proc_lseek = seq_lseek, ++ .proc_release = single_release, ++ .proc_write = nat46_proc_write, ++}; ++#endif + + + int create_nat46_proc_entry(void) { diff --git a/package/kernel/nat46/patches/118-add-nat46_remove.patch b/package/kernel/nat46/patches/118-add-nat46_remove.patch new file mode 100644 index 00000000000000..424939f29013e7 --- /dev/null +++ b/package/kernel/nat46/patches/118-add-nat46_remove.patch @@ -0,0 +1,80 @@ +--- a/nat46/modules/nat46-module.c ++++ b/nat46/modules/nat46-module.c +@@ -138,6 +138,12 @@ static ssize_t nat46_proc_write(struct f + mutex_lock(&add_del_lock); + nat46_insert(devname, tail); + mutex_unlock(&add_del_lock); ++ } else if (0 == strcmp(arg_name, "remove")) { ++ devname = get_devname(&tail); ++ printk(KERN_INFO "nat46: remove a rule from the device (%s) with '%s'\n", devname, tail); ++ mutex_lock(&add_del_lock); ++ nat46_remove(devname, tail); ++ mutex_unlock(&add_del_lock); + } + } + +--- a/nat46/modules/nat46-netdev.c ++++ b/nat46/modules/nat46-netdev.c +@@ -337,6 +337,46 @@ int nat46_configure(char *devname, char + } + } + ++int nat46_remove(char *devname, char *buf) { ++ int ret = -1; ++ char config_remove[NAT46_CFG_BUFLEN]; ++ struct net_device *dev; ++ nat46_instance_t *nat46; ++ nat46_instance_t *nat46_remove; ++ int result_rem; ++ int i; ++ ++ if((dev = find_dev(devname)) == NULL || ++ (nat46 = netdev_nat46_instance(dev)) == NULL || ++ (nat46_remove = alloc_nat46_instance(1, NULL, -1, -1, -1)) == NULL) { ++ return ret; ++ } ++ ++ if(nat46_set_ipair_config(nat46_remove, 0, buf, NAT46_CFG_BUFLEN) < 0) { ++ release_nat46_instance(nat46_remove); ++ return ret; ++ } ++ ++ result_rem = nat46_get_ipair_config(nat46_remove, 0, config_remove, NAT46_CFG_BUFLEN); ++ for(i = 0; i < nat46->npairs; i++) { ++ char config[NAT46_CFG_BUFLEN]; ++ int result = nat46_get_ipair_config(nat46, i, config, NAT46_CFG_BUFLEN); ++ ++ if (result_rem == result && strncmp(config_remove, config, result_rem) == 0) { ++ nat46_instance_t *nat46_new = alloc_nat46_instance(nat46->npairs-1, nat46, 0, 0, i); ++ if(nat46_new) { ++ netdev_nat46_set_instance(dev, nat46_new); ++ ret = 0; ++ } else { ++ printk("Could not remove the rule from device %s\n", devname); ++ } ++ break; ++ } ++ } ++ release_nat46_instance(nat46_remove); ++ return ret; ++} ++ + void nat64_show_all_configs(struct seq_file *m) { + struct net_device *dev; + read_lock(&dev_base_lock); +--- a/nat46/modules/nat46-netdev.h ++++ b/nat46/modules/nat46-netdev.h +@@ -14,11 +14,13 @@ + */ + + #define NAT46_DEVICE_SIGNATURE 0x544e36dd ++#define NAT46_CFG_BUFLEN 200 + + int nat46_create(char *devname); + int nat46_destroy(char *devname); + int nat46_insert(char *devname, char *buf); + int nat46_configure(char *devname, char *buf); ++int nat46_remove(char *devname, char *buf); + void nat46_destroy_all(void); + void nat64_show_all_configs(struct seq_file *m); + void nat46_netdev_count_xmit(struct sk_buff *skb, struct net_device *dev); diff --git a/package/kernel/nat46/patches/119-upgrade-alloc_nat46_instance.patch b/package/kernel/nat46/patches/119-upgrade-alloc_nat46_instance.patch new file mode 100644 index 00000000000000..b86369281c7fd1 --- /dev/null +++ b/package/kernel/nat46/patches/119-upgrade-alloc_nat46_instance.patch @@ -0,0 +1,56 @@ +--- a/nat46/modules/nat46-core.h ++++ b/nat46/modules/nat46-core.h +@@ -106,7 +106,7 @@ int nat46_get_config(nat46_instance_t *n + char *get_next_arg(char **ptail); + nat46_instance_t *get_nat46_instance(struct sk_buff *sk); + +-nat46_instance_t *alloc_nat46_instance(int npairs, nat46_instance_t *old, int from_ipair, int to_ipair); ++nat46_instance_t *alloc_nat46_instance(int npairs, nat46_instance_t *old, int from_ipair, int to_ipair, int remove_ipair); + void release_nat46_instance(nat46_instance_t *nat46); + + int xlate_6_to_4(struct net_device *dev, struct ipv6hdr *ip6h, uint16_t proto, __u32 *pv4saddr, __u32 *pv4daddr); +--- a/nat46/modules/nat46-glue.c ++++ b/nat46/modules/nat46-glue.c +@@ -23,7 +23,7 @@ int is_valid_nat46(nat46_instance_t *nat + return (nat46 && (nat46->sig == NAT46_SIGNATURE)); + } + +-nat46_instance_t *alloc_nat46_instance(int npairs, nat46_instance_t *old, int from_ipair, int to_ipair) { ++nat46_instance_t *alloc_nat46_instance(int npairs, nat46_instance_t *old, int from_ipair, int to_ipair, int remove_ipair) { + nat46_instance_t *nat46 = kzalloc(sizeof(nat46_instance_t) + npairs*sizeof(nat46_xlate_rulepair_t), GFP_KERNEL); + if (!nat46) { + printk("[nat46] make_nat46_instance: can not alloc a nat46 instance with %d pairs\n", npairs); +@@ -37,8 +37,11 @@ nat46_instance_t *alloc_nat46_instance(i + if (old) { + nat46->debug = old->debug; + for(; (from_ipair >= 0) && (to_ipair >= 0) && +- (from_ipair < old->npairs) && (to_ipair < nat46->npairs); from_ipair++, to_ipair++) { +- nat46->pairs[to_ipair] = old->pairs[from_ipair]; ++ (from_ipair < old->npairs) && (to_ipair < nat46->npairs); from_ipair++) { ++ if (from_ipair != remove_ipair) { ++ nat46->pairs[to_ipair] = old->pairs[from_ipair]; ++ to_ipair++; ++ } + } + } + return nat46; +--- a/nat46/modules/nat46-netdev.c ++++ b/nat46/modules/nat46-netdev.c +@@ -155,7 +155,7 @@ static void netdev_nat46_set_instance(st + static void nat46_netdev_setup(struct net_device *dev) + { + nat46_netdev_priv_t *priv = netdev_priv(dev); +- nat46_instance_t *nat46 = alloc_nat46_instance(1, NULL, -1, -1); ++ nat46_instance_t *nat46 = alloc_nat46_instance(1, NULL, -1, -1, -1); + + memset(priv, 0, sizeof(*priv)); + priv->sig = NAT46_DEVICE_SIGNATURE; +@@ -316,7 +316,7 @@ int nat46_insert(char *devname, char *bu + return ret; + } + +- nat46_new = alloc_nat46_instance(nat46->npairs+1, nat46, 0, 1); ++ nat46_new = alloc_nat46_instance(nat46->npairs+1, nat46, 0, 1, -1); + if(nat46_new) { + netdev_nat46_set_instance(dev, nat46_new); + ret = nat46_set_ipair_config(nat46_new, 0, buf, strlen(buf)); diff --git a/package/kernel/nat46/patches/16-fix-l3_payload-length-wrong-in-fragment-case.patch b/package/kernel/nat46/patches/16-fix-l3_payload-length-wrong-in-fragment-case.patch new file mode 100644 index 00000000000000..22828f262a4847 --- /dev/null +++ b/package/kernel/nat46/patches/16-fix-l3_payload-length-wrong-in-fragment-case.patch @@ -0,0 +1,144 @@ +Author: Ken Zhu +Date: Fri Mar 26 12:27:17 2021 -0700 + + [nat46]: fix icmp checksum error based on the correct packet length + + UDP/TCP checksum includes the pseudo header in addition to the palyload. + But in nat46 case, their length in the pseudo header could be ignored + since it keeps unchanged between IPv4/IPv6 transition. + + ICMPv6 checksum includes pseudo IPV6 header in addition to packet payload + while ICMPv4 does not counter in the pseudo header. + the length of pseudo header should count in all fragmented payload. + + The change get the length by reassembling the fragments. + + Change-Id: I56e59958aa21eed5b595ae1a9ab02285dba2185b + Signed-off-by: Ken Zhu +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -18,6 +18,8 @@ + + #include + #include ++#include ++#include + + #include "nat46-glue.h" + #include "nat46-core.h" +@@ -1751,7 +1753,8 @@ void nat46_ipv6_input(struct sk_buff *ol + + struct iphdr * iph; + __u32 v4saddr, v4daddr; +- struct sk_buff * new_skb = 0; ++ struct sk_buff *new_skb = NULL; ++ struct sk_buff *reasm_skb = NULL; + int truncSize = 0; + int tailTruncSize = 0; + int v6packet_l3size = sizeof(*ip6h); +@@ -1802,6 +1805,46 @@ void nat46_ipv6_input(struct sk_buff *ol + frag_id = fold_ipv6_frag_id(fh->identification); + nat46debug(2, "Not first fragment, frag_off: %04X, frag id: %04X orig frag_off: %04X", ntohs(frag_off), frag_id, ntohs(fh->frag_off)); + } ++ ++ /* ICMPv6 counts the pseudo ipv6 header into its checksum, but ICMP doesn't ++ * but the length filed of the pseudo header count in all fragmented ++ * packets, so we need gather the framented packets into one packet to ++ * get the l3 payload length. ++ */ ++ if (proto == NEXTHDR_ICMP) { ++ struct sk_buff *skb = skb_get(old_skb); ++ int err; ++ if (skb == NULL) { ++ goto done; ++ } ++ ++ err = nf_ct_frag6_gather(dev_net(old_skb->dev), skb, IP6_DEFRAG_LOCAL_DELIVER); ++ ++ /* EINPROGRESS means the skb was queued but the gather not finished yet */ ++ if (err == -EINPROGRESS) { ++ goto done; ++ } ++ ++ reasm_skb = skb; ++ /* other than EINPROGRESS error returned means the skb wasn't queued ++ * 0 returned means that all fragments are all gathered ++ * and the original skb was queued ++ */ ++ if (err != 0) { ++ goto done; ++ } ++ ++ /* Use the reassembly packet as the input */ ++ ip6h = ipv6_hdr(reasm_skb); ++ proto = ip6h->nexthdr; ++ v6packet_l3size = sizeof(*ip6h); ++ ++ /* No fragment header in the re-assembly packet */ ++ frag_off = 0; ++ l3_infrag_payload_len = ntohs(ip6h->payload_len); ++ old_skb = reasm_skb; ++ check_for_l4 = 1; ++ } + } + } else { + frag_off = htons(IP_DF); +@@ -1850,20 +1893,28 @@ void nat46_ipv6_input(struct sk_buff *ol + /* CHECKSUMS UPDATE */ + case NEXTHDR_TCP: { + struct tcphdr *th = add_offset(ip6h, v6packet_l3size); +- u16 sum1 = csum_ipv6_unmagic(nat46, &ip6h->saddr, &ip6h->daddr, l3_infrag_payload_len, NEXTHDR_TCP, th->check); +- u16 sum2 = csum_tcpudp_remagic(v4saddr, v4daddr, l3_infrag_payload_len, NEXTHDR_TCP, sum1); ++ ++ /* TCP payload length won't change, needn't unmagic its value. */ ++ u16 sum1 = csum_ipv6_unmagic(nat46, &ip6h->saddr, &ip6h->daddr, 0, NEXTHDR_TCP, th->check); ++ u16 sum2 = csum_tcpudp_remagic(v4saddr, v4daddr, 0, NEXTHDR_TCP, sum1); + th->check = sum2; + break; + } + case NEXTHDR_UDP: { + struct udphdr *udp = add_offset(ip6h, v6packet_l3size); +- u16 sum1 = csum_ipv6_unmagic(nat46, &ip6h->saddr, &ip6h->daddr, l3_infrag_payload_len, NEXTHDR_UDP, udp->check); +- u16 sum2 = csum_tcpudp_remagic(v4saddr, v4daddr, l3_infrag_payload_len, NEXTHDR_UDP, sum1); ++ ++ /* UDP payload length won't change, needn't unmagic its value. */ ++ u16 sum1 = csum_ipv6_unmagic(nat46, &ip6h->saddr, &ip6h->daddr, 0, NEXTHDR_UDP, udp->check); ++ u16 sum2 = csum_tcpudp_remagic(v4saddr, v4daddr, 0, NEXTHDR_UDP, sum1); + udp->check = sum2; + break; + } + case NEXTHDR_ICMP: { + struct icmp6hdr *icmp6h = add_offset(ip6h, v6packet_l3size); ++ ++ /* ICMPv6 count the pseudo IPv6 header into its checksum, but icmp ++ * doesn't, unmagic the whole the pseudo IPv6 header from the checksum. ++ */ + u16 sum1 = csum_ipv6_unmagic(nat46, &ip6h->saddr, &ip6h->daddr, l3_infrag_payload_len, NEXTHDR_ICMP, icmp6h->icmp6_cksum); + icmp6h->icmp6_cksum = sum1; + nat46debug_dump(nat46, 10, icmp6h, l3_infrag_payload_len); +@@ -1909,10 +1960,6 @@ void nat46_ipv6_input(struct sk_buff *ol + fill_v4hdr_from_v6hdr(iph, ip6h, v4saddr, v4daddr, frag_id, frag_off, proto, l3_infrag_payload_len); + new_skb->protocol = htons(ETH_P_IP); + +- if (ntohs(iph->tot_len) >= 2000) { +- nat46debug(0, "Too big IP len: %d", ntohs(iph->tot_len)); +- } +- + nat46debug(5, "about to send v4 packet, flags: %02x", IPCB(new_skb)->flags); + nat46_netdev_count_xmit(new_skb, old_skb->dev); + +@@ -1924,11 +1971,12 @@ void nat46_ipv6_input(struct sk_buff *ol + /* TBD: should copy be released here? */ + + done: ++ if (reasm_skb) { ++ kfree_skb(reasm_skb); ++ } + release_nat46_instance(nat46); + } + +- +- + void ip6_update_csum(struct sk_buff * skb, struct ipv6hdr * ip6hdr, int do_atomic_frag) + { + u32 sum1=0; diff --git a/package/kernel/nat46/patches/17-add-support-ipv6-udp-checksum-0.patch b/package/kernel/nat46/patches/17-add-support-ipv6-udp-checksum-0.patch new file mode 100644 index 00000000000000..142a2a89c84354 --- /dev/null +++ b/package/kernel/nat46/patches/17-add-support-ipv6-udp-checksum-0.patch @@ -0,0 +1,32 @@ +Author: Ken Zhu +Date: Wed Feb 17 13:37:15 2021 -0800 + + nat46: keep ipv4 checksum zero when incoming ipv6 UDP checksum is zero + + When an incoming ipv6 UDP packet has 0 checksum, the ipv4 checksum is + kept zero after translation. + + Change-Id: I8ddd0c586e5cfbd5a57dc5632e93543d6db5c312 + Signed-off-by: Ken Zhu + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -1903,10 +1903,14 @@ void nat46_ipv6_input(struct sk_buff *ol + case NEXTHDR_UDP: { + struct udphdr *udp = add_offset(ip6h, v6packet_l3size); + +- /* UDP payload length won't change, needn't unmagic its value. */ +- u16 sum1 = csum_ipv6_unmagic(nat46, &ip6h->saddr, &ip6h->daddr, 0, NEXTHDR_UDP, udp->check); +- u16 sum2 = csum_tcpudp_remagic(v4saddr, v4daddr, 0, NEXTHDR_UDP, sum1); +- udp->check = sum2; ++ /* UDP payload length won't change, needn't unmagic its value. ++ * UDP checksum zero then skip the calculation of the checksum. ++ */ ++ if (udp->check) { ++ u16 sum1 = csum_ipv6_unmagic(nat46, &ip6h->saddr, &ip6h->daddr, 0, NEXTHDR_UDP, udp->check); ++ u16 sum2 = csum_tcpudp_remagic(v4saddr, v4daddr, 0, NEXTHDR_UDP, sum1); ++ udp->check = sum2; ++ } + break; + } + case NEXTHDR_ICMP: { From 8a69600ca08eda430a993a6a3d1b7ccf95c6affd Mon Sep 17 00:00:00 2001 From: bitthief Date: Mon, 17 Jul 2023 23:46:17 +0300 Subject: [PATCH 018/225] package: kernel: nat46: add kernel 6.1 support Signed-off-by: bitthief --- .../nat46/patches/900-kernel-6.1-compat.patch | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 package/kernel/nat46/patches/900-kernel-6.1-compat.patch diff --git a/package/kernel/nat46/patches/900-kernel-6.1-compat.patch b/package/kernel/nat46/patches/900-kernel-6.1-compat.patch new file mode 100644 index 00000000000000..ed7e4aaf55fade --- /dev/null +++ b/package/kernel/nat46/patches/900-kernel-6.1-compat.patch @@ -0,0 +1,39 @@ +--- a/nat46/modules/nat46-netdev.c ++++ b/nat46/modules/nat46-netdev.c +@@ -92,8 +92,8 @@ static netdev_tx_t nat46_netdev_xmit(str + struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats); + + u64_stats_update_begin(&tstats->syncp); +- tstats->rx_packets++; +- tstats->rx_bytes += skb->len; ++ u64_stats_inc(&tstats->rx_packets); ++ u64_stats_add(&tstats->rx_bytes, skb->len); + u64_stats_update_end(&tstats->syncp); + put_cpu_ptr(tstats); + if(ETH_P_IP == ntohs(skb->protocol)) { +@@ -110,8 +110,8 @@ void nat46_netdev_count_xmit(struct sk_b + struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats); + + u64_stats_update_begin(&tstats->syncp); +- tstats->tx_packets++; +- tstats->tx_bytes += skb->len; ++ u64_stats_inc(&tstats->tx_packets); ++ u64_stats_add(&tstats->tx_bytes, skb->len); + u64_stats_update_end(&tstats->syncp); + put_cpu_ptr(tstats); + } +@@ -122,10 +122,10 @@ void nat46_update_stats(struct net_devic + struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats); + + u64_stats_update_begin(&tstats->syncp); +- tstats->rx_packets += rx_packets; +- tstats->rx_bytes += rx_bytes; +- tstats->tx_packets += tx_packets; +- tstats->tx_bytes += tx_bytes; ++ u64_stats_add(&tstats->rx_packets, rx_packets); ++ u64_stats_add(&tstats->rx_bytes, rx_bytes); ++ u64_stats_add(&tstats->tx_packets, tx_packets); ++ u64_stats_add(&tstats->tx_bytes, tx_bytes); + dev->stats.rx_dropped += rx_dropped; + dev->stats.tx_dropped += tx_dropped; + u64_stats_update_end(&tstats->syncp); From c461ccc1abc0bbfe1a425c14c703c52a198771e2 Mon Sep 17 00:00:00 2001 From: bitthief Date: Sat, 4 Feb 2023 01:28:51 +0200 Subject: [PATCH 019/225] package: network: iproute2: add NSS QDISC support Signed-off-by: bitthief --- .../iproute2/patches/400-add-nss-qdisc.patch | 2093 +++++++++++++++++ .../iproute2/patches/500-add-nssmirred.patch | 243 ++ 2 files changed, 2336 insertions(+) create mode 100644 package/network/utils/iproute2/patches/400-add-nss-qdisc.patch create mode 100644 package/network/utils/iproute2/patches/500-add-nssmirred.patch diff --git a/package/network/utils/iproute2/patches/400-add-nss-qdisc.patch b/package/network/utils/iproute2/patches/400-add-nss-qdisc.patch new file mode 100644 index 00000000000000..e5d7024904d0d7 --- /dev/null +++ b/package/network/utils/iproute2/patches/400-add-nss-qdisc.patch @@ -0,0 +1,2093 @@ +--- a/include/uapi/linux/pkt_sched.h ++++ b/include/uapi/linux/pkt_sched.h +@@ -119,6 +119,251 @@ enum { + + #define TCA_STAB_MAX (__TCA_STAB_MAX - 1) + ++enum { ++ TCA_NSS_ACCEL_MODE_NSS_FW, ++ TCA_NSS_ACCEL_MODE_PPE, ++ TCA_NSS_ACCEL_MODE_MAX ++}; ++ ++/* NSSFIFO section */ ++ ++enum { ++ TCA_NSSFIFO_UNSPEC, ++ TCA_NSSFIFO_PARMS, ++ __TCA_NSSFIFO_MAX ++}; ++ ++#define TCA_NSSFIFO_MAX (__TCA_NSSFIFO_MAX - 1) ++ ++struct tc_nssfifo_qopt { ++ __u32 limit; /* Queue length: bytes for bfifo, packets for pfifo */ ++ __u8 set_default; /* Sets qdisc to be the default qdisc for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSWRED section */ ++ ++enum { ++ TCA_NSSWRED_UNSPEC, ++ TCA_NSSWRED_PARMS, ++ __TCA_NSSWRED_MAX ++}; ++ ++#define TCA_NSSWRED_MAX (__TCA_NSSWRED_MAX - 1) ++#define NSSWRED_CLASS_MAX 6 ++struct tc_red_alg_parameter { ++ __u32 min; /* qlen_avg < min: pkts are all enqueued */ ++ __u32 max; /* qlen_avg > max: pkts are all dropped */ ++ __u32 probability;/* Drop probability at qlen_avg = max */ ++ __u32 exp_weight_factor;/* exp_weight_factor for calculate qlen_avg */ ++}; ++ ++struct tc_nsswred_traffic_class { ++ __u32 limit; /* Queue length */ ++ __u32 weight_mode_value; /* Weight mode value */ ++ struct tc_red_alg_parameter rap;/* Parameters for RED alg */ ++}; ++ ++/* ++ * Weight modes for WRED ++ */ ++enum tc_nsswred_weight_modes { ++ TC_NSSWRED_WEIGHT_MODE_DSCP = 0,/* Weight mode is DSCP */ ++ TC_NSSWRED_WEIGHT_MODES, /* Must be last */ ++}; ++typedef enum tc_nsswred_weight_modes tc_nsswred_weight_mode_t; ++ ++struct tc_nsswred_qopt { ++ __u32 limit; /* Queue length */ ++ enum tc_nsswred_weight_modes weight_mode; ++ /* Weight mode */ ++ __u32 traffic_classes; /* How many traffic classes: DPs */ ++ __u32 def_traffic_class; /* Default traffic if no match: def_DP */ ++ __u32 traffic_id; /* The traffic id to be configured: DP */ ++ __u32 weight_mode_value; /* Weight mode value */ ++ struct tc_red_alg_parameter rap;/* RED algorithm parameters */ ++ struct tc_nsswred_traffic_class tntc[NSSWRED_CLASS_MAX]; ++ /* Traffic settings for dumpping */ ++ __u8 ecn; /* Setting ECN bit or dropping */ ++ __u8 set_default; /* Sets qdisc to be the default for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSCODEL section */ ++ ++enum { ++ TCA_NSSCODEL_UNSPEC, ++ TCA_NSSCODEL_PARMS, ++ __TCA_NSSCODEL_MAX ++}; ++ ++#define TCA_NSSCODEL_MAX (__TCA_NSSCODEL_MAX - 1) ++ ++struct tc_nsscodel_qopt { ++ __u32 target; /* Acceptable queueing delay */ ++ __u32 limit; /* Max number of packets that can be held in the queue */ ++ __u32 interval; /* Monitoring interval */ ++ __u32 flows; /* Number of flow buckets */ ++ __u32 quantum; /* Weight (in bytes) used for DRR of flow buckets */ ++ __u8 ecn; /* 0 - disable ECN, 1 - enable ECN */ ++ __u8 set_default; /* Sets qdisc to be the default qdisc for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++struct tc_nsscodel_xstats { ++ __u32 peak_queue_delay; /* Peak delay experienced by a dequeued packet */ ++ __u32 peak_drop_delay; /* Peak delay experienced by a dropped packet */ ++}; ++ ++/* NSSFQ_CODEL section */ ++ ++struct tc_nssfq_codel_xstats { ++ __u32 new_flow_count; /* Total number of new flows seen */ ++ __u32 new_flows_len; /* Current number of new flows */ ++ __u32 old_flows_len; /* Current number of old flows */ ++ __u32 ecn_mark; /* Number of packets marked with ECN */ ++ __u32 drop_overlimit; /* Number of packets dropped due to overlimit */ ++ __u32 maxpacket; /* The largest packet seen so far in the queue */ ++}; ++ ++/* NSSTBL section */ ++ ++enum { ++ TCA_NSSTBL_UNSPEC, ++ TCA_NSSTBL_PARMS, ++ __TCA_NSSTBL_MAX ++}; ++ ++#define TCA_NSSTBL_MAX (__TCA_NSSTBL_MAX - 1) ++ ++struct tc_nsstbl_qopt { ++ __u32 burst; /* Maximum burst size */ ++ __u32 rate; /* Limiting rate of TBF */ ++ __u32 peakrate; /* Maximum rate at which TBF is allowed to send */ ++ __u32 mtu; /* Max size of packet, or minumim burst size */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSPRIO section */ ++ ++#define TCA_NSSPRIO_MAX_BANDS 256 ++ ++enum { ++ TCA_NSSPRIO_UNSPEC, ++ TCA_NSSPRIO_PARMS, ++ __TCA_NSSPRIO_MAX ++}; ++ ++#define TCA_NSSPRIO_MAX (__TCA_NSSPRIO_MAX - 1) ++ ++struct tc_nssprio_qopt { ++ __u32 bands; /* Number of bands */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSBF section */ ++ ++enum { ++ TCA_NSSBF_UNSPEC, ++ TCA_NSSBF_CLASS_PARMS, ++ TCA_NSSBF_QDISC_PARMS, ++ __TCA_NSSBF_MAX ++}; ++ ++#define TCA_NSSBF_MAX (__TCA_NSSBF_MAX - 1) ++ ++struct tc_nssbf_class_qopt { ++ __u32 burst; /* Maximum burst size */ ++ __u32 rate; /* Allowed bandwidth for this class */ ++ __u32 mtu; /* MTU of the associated interface */ ++ __u32 quantum; /* Quantum allocation for DRR */ ++}; ++ ++struct tc_nssbf_qopt { ++ __u16 defcls; /* Default class value */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSWRR section */ ++ ++enum { ++ TCA_NSSWRR_UNSPEC, ++ TCA_NSSWRR_CLASS_PARMS, ++ TCA_NSSWRR_QDISC_PARMS, ++ __TCA_NSSWRR_MAX ++}; ++ ++#define TCA_NSSWRR_MAX (__TCA_NSSWRR_MAX - 1) ++ ++struct tc_nsswrr_class_qopt { ++ __u32 quantum; /* Weight associated to this class */ ++}; ++ ++struct tc_nsswrr_qopt { ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSWFQ section */ ++ ++enum { ++ TCA_NSSWFQ_UNSPEC, ++ TCA_NSSWFQ_CLASS_PARMS, ++ TCA_NSSWFQ_QDISC_PARMS, ++ __TCA_NSSWFQ_MAX ++}; ++ ++#define TCA_NSSWFQ_MAX (__TCA_NSSWFQ_MAX - 1) ++ ++struct tc_nsswfq_class_qopt { ++ __u32 quantum; /* Weight associated to this class */ ++}; ++ ++struct tc_nsswfq_qopt { ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSHTB section */ ++ ++enum { ++ TCA_NSSHTB_UNSPEC, ++ TCA_NSSHTB_CLASS_PARMS, ++ TCA_NSSHTB_QDISC_PARMS, ++ __TCA_NSSHTB_MAX ++}; ++ ++#define TCA_NSSHTB_MAX (__TCA_NSSHTB_MAX - 1) ++ ++struct tc_nsshtb_class_qopt { ++ __u32 burst; /* Allowed burst size */ ++ __u32 rate; /* Allowed bandwidth for this class */ ++ __u32 cburst; /* Maximum burst size */ ++ __u32 crate; /* Maximum bandwidth for this class */ ++ __u32 quantum; /* Quantum allocation for DRR */ ++ __u32 priority; /* Priority value associated with this class */ ++ __u32 overhead; /* Overhead in bytes per packet */ ++}; ++ ++struct tc_nsshtb_qopt { ++ __u32 r2q; /* Rate to quantum ratio */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSBLACKHOLE section */ ++ ++enum { ++ TCA_NSSBLACKHOLE_UNSPEC, ++ TCA_NSSBLACKHOLE_PARMS, ++ __TCA_NSSBLACKHOLE_MAX ++}; ++ ++#define TCA_NSSBLACKHOLE_MAX (__TCA_NSSBLACKHOLE_MAX - 1) ++ ++struct tc_nssblackhole_qopt { ++ __u8 set_default; /* Sets qdisc to be the default qdisc for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++ + /* FIFO section */ + + struct tc_fifo_qopt { +--- a/tc/Makefile ++++ b/tc/Makefile +@@ -82,6 +82,7 @@ TCMODULES += q_etf.o + TCMODULES += q_taprio.o + TCMODULES += q_plug.o + TCMODULES += q_ets.o ++TCMODULES += q_nss.o + + TCSO := + ifeq ($(TC_CONFIG_ATM),y) +--- /dev/null ++++ b/tc/q_nss.c +@@ -0,0 +1,1826 @@ ++/* ++ ************************************************************************** ++ * Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved. ++ * Permission to use, copy, modify, and/or distribute this software for ++ * any purpose with or without fee is hereby granted, provided that the ++ * above copyright notice and this permission notice appear in all copies. ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT ++ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ ************************************************************************** ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "utils.h" ++#include "tc_util.h" ++#include "tc_red.h" ++ ++/* ======================== NSSWRED =======================*/ ++ ++static void nssred_explain(void) ++{ ++ fprintf(stderr, "Usage: ... nssred limit BYTES avpkt BYTES [ min BYTES ] [ max BYTES ] [ probability VALUE ]\n"); ++ fprintf(stderr, " [ burst PACKETS ] [ecn] [ set_default ] [ accel_mode ]\n"); ++} ++ ++static void nsswred_explain(void) ++{ ++ fprintf(stderr, "Usage: ... nsswred setup DPs NUMBER dp_default NUMBER [ weight_mode dscp ] [ecn] [ set_default ] [ accel_mode ]\n"); ++ fprintf(stderr, " nsswred limit BYTES DP NUMBER min BYTES max BYTES avpkt BYTES dscp NUMBER [ probability VALUE ] [ burst PACKETS ]\n"); ++} ++ ++static int nsswred_setup(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ struct rtattr *tail; ++ struct tc_nsswred_qopt opt; ++ ++ memset(&opt, 0, sizeof(opt)); ++ unsigned int dps = 0; ++ unsigned int def_dp = 0; ++ bool accel_mode = false; ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "DPs") == 0) { ++ NEXT_ARG(); ++ if (get_unsigned(&dps, *argv, 0) || dps > NSSWRED_CLASS_MAX) { ++ ++ fprintf(stderr, "DPs should be between 1 - %d\n", NSSWRED_CLASS_MAX); ++ return -1; ++ } ++ } else if (strcmp(*argv, "weight_mode") == 0) { ++ NEXT_ARG(); ++ if (strcmp(*argv, "dscp") == 0) { ++ opt.weight_mode = TC_NSSWRED_WEIGHT_MODE_DSCP; ++ } else { ++ fprintf(stderr, "Illegal \"weight_mode\", we only support dscp at this moment\n"); ++ } ++ } else if (strcmp(*argv, "ecn") == 0) { ++ opt.ecn = 1; ++ } else if (strcmp(*argv, "dp_default") == 0) { ++ NEXT_ARG(); ++ if (get_unsigned(&def_dp, *argv, 0) || def_dp > dps) { ++ fprintf(stderr, "Illegal dp_default value\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "help") == 0) { ++ nsswred_explain(); ++ return -1; ++ } else if (strcmp(*argv, "set_default") == 0) { ++ opt.set_default = 1; ++ } else if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ nsswred_explain(); ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_NSS_FW; ++ } else if (opt.accel_mode != TCA_NSS_ACCEL_MODE_NSS_FW) { ++ fprintf(stderr, "accel_mode should be %d\n", TCA_NSS_ACCEL_MODE_NSS_FW); ++ return -1; ++ } ++ ++ if (!dps || !def_dp) { ++ fprintf(stderr, "Illegal nsswred setup parameters\n"); ++ return -1; ++ } ++ opt.traffic_classes = dps; ++ opt.def_traffic_class = def_dp; ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSWRED_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nsswred_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ struct rtattr *tail; ++ struct tc_nsswred_qopt opt; ++ ++ int total_args = argc; ++ unsigned burst = 0; ++ unsigned avpkt = 0; ++ double probability = 0.0; ++ unsigned char weighted = (strcmp(qu->id, "nsswred") == 0); ++ bool accel_mode = false; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "limit") == 0) { ++ NEXT_ARG(); ++ if (get_size(&opt.limit, *argv)) { ++ fprintf(stderr, "Illegal \"limit\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "set_default") == 0) { ++ opt.set_default = 1; ++ } else if (strcmp(*argv, "min") == 0) { ++ NEXT_ARG(); ++ if (get_size(&opt.rap.min, *argv)) { ++ fprintf(stderr, "Illegal \"min\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "max") == 0) { ++ NEXT_ARG(); ++ if (get_size(&opt.rap.max, *argv)) { ++ fprintf(stderr, "Illegal \"max\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "burst") == 0) { ++ NEXT_ARG(); ++ if (get_unsigned(&burst, *argv, 0)) { ++ fprintf(stderr, "Illegal \"burst\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "avpkt") == 0) { ++ NEXT_ARG(); ++ if (get_size(&avpkt, *argv)) { ++ fprintf(stderr, "Illegal \"avpkt\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "probability") == 0) { ++ NEXT_ARG(); ++ if (sscanf(*argv, "%lg", &probability) != 1) { ++ fprintf(stderr, "Illegal \"probability\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "ecn") == 0) { ++ opt.ecn = 1; ++ } else if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else if (strcmp(*argv, "help") == 0) { ++ if (weighted) { ++ nsswred_explain(); ++ } else { ++ nssred_explain(); ++ } ++ return -1; ++ } else if (weighted) { ++ if (strcmp(*argv, "setup") == 0) { ++ if (argc != total_args) { ++ fprintf(stderr, "Setup command must be the first parameter\n"); ++ return -1; ++ } ++ return nsswred_setup(qu, argc-1, argv+1, n); ++ } else if (strcmp(*argv, "DP") == 0) { ++ NEXT_ARG(); ++ if (get_unsigned(&opt.traffic_id, *argv, 0)) { ++ fprintf(stderr, "Illegal \"DP\""); ++ return -1; ++ } ++ } else if (strcmp(*argv, "dscp") == 0) { ++ NEXT_ARG(); ++ if (get_unsigned(&opt.weight_mode_value, *argv, 0)) { ++ fprintf(stderr, "Illegal \"dscp\" value\n"); ++ return -1; ++ } ++ } ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ if (weighted) { ++ nsswred_explain(); ++ } else { ++ nssred_explain(); ++ } ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_PPE; ++ } else if (opt.accel_mode >= TCA_NSS_ACCEL_MODE_MAX) { ++ fprintf(stderr, "Accel_mode should be < %d\n", TCA_NSS_ACCEL_MODE_MAX); ++ return -1; ++ } ++ ++ if (weighted) { ++ if (!opt.limit || !opt.rap.min || !opt.rap.max || !opt.traffic_id || !avpkt || !opt.weight_mode_value) { ++ fprintf(stderr, "Require limit, min, max, avpkt, DP, weight_mode_value\n"); ++ return -1; ++ } ++ } else { ++ if (!opt.limit || !avpkt) { ++ fprintf(stderr, "Require limit, avpkt"); ++ return -1; ++ } ++ } ++ ++ /* ++ * Compute default min/max thresholds based on ++ * Sally Floyd's recommendations: ++ * http://www.icir.org/floyd/REDparameters.txt ++ */ ++ if (!opt.rap.max) ++ opt.rap.max = opt.rap.min ? opt.rap.min * 3 : opt.limit / 4; ++ if (!opt.rap.min) ++ opt.rap.min = opt.rap.max / 3; ++ if (!burst) ++ burst = (2 * opt.rap.min + opt.rap.max) / (3 * avpkt); ++ if ((opt.rap.exp_weight_factor = tc_red_eval_ewma(opt.rap.min, burst, avpkt)) < 0) { ++ fprintf(stderr, "Failed to calculate EWMA constant.\n"); ++ return -1; ++ } ++ ++ /* ++ * project [0.0-1.0] to [0-255] to avoid floating point calculation ++ */ ++ opt.rap.probability = probability * (pow(2, 8)-1); ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSWRED_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nsswred_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSWRED_MAX + 1]; ++ struct tc_nsswred_qopt *qopt; ++ int i; ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSWRED_MAX, opt); ++ ++ if (tb[TCA_NSSWRED_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSWRED_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSWRED_PARMS]); ++ ++ if (strcmp(qu->id, "nsswred") == 0) { ++ fprintf(f, "DPs %d def_DP %d weight mode: " , qopt->traffic_classes, qopt->def_traffic_class); ++ if (qopt->weight_mode == TC_NSSWRED_WEIGHT_MODE_DSCP) ++ fprintf(f, "DSCP\n"); ++ else ++ fprintf(f, "Unknown\n"); ++ for (i = 0;i < qopt->traffic_classes; i ++) { ++ if (qopt->tntc[i].rap.exp_weight_factor) { ++ double prob = (double)qopt->tntc[i].rap.probability; ++ fprintf(f, "DP %d: limit %d, weight mode value: %d min: %d max: %d exp_weight_factor: %d probability %.2f\n", ++ i + 1, qopt->tntc[i].limit, qopt->tntc[i].weight_mode_value ++ , qopt->tntc[i].rap.min,qopt->tntc[i].rap.max,qopt->tntc[i].rap.exp_weight_factor,prob/255); ++ } ++ } ++ } else { ++ double prob = (double)qopt->rap.probability; ++ fprintf(f, "limit %d, min: %d max: %d exp_weight_factor: %d probability %.2f\n", ++ qopt->limit, qopt->rap.min,qopt->rap.max,qopt->rap.exp_weight_factor,prob/255); ++ } ++ ++ if (qopt->ecn) ++ fprintf(f, "ECN enabled "); ++ if (qopt->set_default) ++ fprintf(f, "set_default "); ++ ++ fprintf(f, "accel_mode: %d ", qopt->accel_mode); ++ ++ return 0; ++} ++ ++struct qdisc_util nssred_qdisc_util = { ++ .id = "nssred", ++ .parse_qopt = nsswred_parse_opt, ++ .print_qopt = nsswred_print_opt, ++}; ++ ++struct qdisc_util nsswred_qdisc_util = { ++ .id = "nsswred", ++ .parse_qopt = nsswred_parse_opt, ++ .print_qopt = nsswred_print_opt, ++}; ++ ++/* ======================== NSSFIFO =======================*/ ++ ++static void nssfifo_explain(void) ++{ ++ fprintf(stderr, "Usage: ... nsspfifo [ limit PACKETS ] [ set_default ] [ accel_mode ]\n"); ++} ++ ++static int nssfifo_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ struct rtattr *tail; ++ struct tc_nssfifo_qopt opt; ++ bool accel_mode = false; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "limit") == 0) { ++ NEXT_ARG(); ++ if (get_size(&opt.limit, *argv) || opt.limit == 0) { ++ fprintf(stderr, "Illegal \"limit\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "set_default") == 0) { ++ opt.set_default = 1; ++ } else if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else if (strcmp(*argv, "help") == 0) { ++ nssfifo_explain(); ++ return -1; ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ nssfifo_explain(); ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_PPE; ++ } else if (opt.accel_mode >= TCA_NSS_ACCEL_MODE_MAX) { ++ fprintf(stderr, "accel_mode should be < %d\n", TCA_NSS_ACCEL_MODE_MAX); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSFIFO_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nssfifo_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSFIFO_MAX + 1]; ++ struct tc_nssfifo_qopt *qopt; ++ SPRINT_BUF(b1); ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSFIFO_MAX, opt); ++ ++ if (tb[TCA_NSSFIFO_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSFIFO_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSFIFO_PARMS]); ++ ++ if (strcmp(qu->id, "nssbfifo") == 0) ++ fprintf(f, "limit %s ", sprint_size(qopt->limit, b1)); ++ else ++ fprintf(f, "limit %up ", qopt->limit); ++ ++ if (qopt->set_default) ++ fprintf(f, "set_default "); ++ ++ fprintf(f, "accel_mode %d ", qopt->accel_mode); ++ ++ return 0; ++} ++ ++struct qdisc_util nsspfifo_qdisc_util = { ++ .id = "nsspfifo", ++ .parse_qopt = nssfifo_parse_opt, ++ .print_qopt = nssfifo_print_opt, ++}; ++ ++struct qdisc_util nssbfifo_qdisc_util = { ++ .id = "nssbfifo", ++ .parse_qopt = nssfifo_parse_opt, ++ .print_qopt = nssfifo_print_opt, ++}; ++ ++/* ======================== NSSFQ_CODEL =======================*/ ++ ++static void nssfq_codel_explain(void) ++{ ++ fprintf(stderr, "Usage: ... nssfq_codel target TIME interval TIME [ flows NUMBER ] [ quantum BYTES ]" ++ "[ limit PACKETS ] [ set_default ] [ accel_mode ]\n"); ++} ++ ++static void nssfq_codel_explain_err1(void) ++{ ++ fprintf(stderr, "Value of target and interval should be greater than 1ms\n"); ++} ++ ++static int nssfq_codel_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ struct rtattr *tail; ++ struct tc_nsscodel_qopt opt; ++ bool accel_mode = false; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "target") == 0) { ++ NEXT_ARG(); ++ if (get_time(&opt.target, *argv)) { ++ fprintf(stderr, "Illegal \"target\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "limit") == 0) { ++ NEXT_ARG(); ++ if (get_size(&opt.limit, *argv) || opt.limit == 0) { ++ fprintf(stderr, "Illegal \"limit\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "flows") == 0) { ++ NEXT_ARG(); ++ if (get_size(&opt.flows, *argv) || opt.flows == 0) { ++ fprintf(stderr, "Illegal \"flows\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "quantum") == 0) { ++ NEXT_ARG(); ++ if (get_size(&opt.quantum, *argv) || opt.quantum == 0) { ++ fprintf(stderr, "Illegal \"quantum\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "interval") == 0) { ++ NEXT_ARG(); ++ if (get_time(&opt.interval, *argv)) { ++ fprintf(stderr, "Illegal \"interval\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "ecn") == 0) { ++ fprintf(stderr, "Illegal, ECN not supported\n"); ++ nssfq_codel_explain(); ++ return -1; ++ } else if (strcmp(*argv, "set_default") == 0) { ++ opt.set_default = 1; ++ } else if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else if (strcmp(*argv, "help") == 0) { ++ nssfq_codel_explain(); ++ return -1; ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ nssfq_codel_explain(); ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_NSS_FW; ++ } else if (opt.accel_mode != TCA_NSS_ACCEL_MODE_NSS_FW) { ++ fprintf(stderr, "accel_mode should be %d\n", TCA_NSS_ACCEL_MODE_NSS_FW); ++ return -1; ++ } ++ ++ if (!opt.target || !opt.interval) { ++ nssfq_codel_explain(); ++ return -1; ++ } ++ ++ if (opt.target < 1000 || opt.interval < 1000) { ++ nssfq_codel_explain_err1(); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSCODEL_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nssfq_codel_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSCODEL_MAX + 1]; ++ struct tc_nsscodel_qopt *qopt; ++ SPRINT_BUF(b1); ++ SPRINT_BUF(b2); ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSCODEL_MAX, opt); ++ ++ if (tb[TCA_NSSCODEL_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSCODEL_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSCODEL_PARMS]); ++ ++ fprintf(f, "target %s limit %up interval %s flows %u quantum %u ", ++ sprint_time(qopt->target, b1), ++ qopt->limit, ++ sprint_time(qopt->interval, b2), ++ qopt->flows, ++ qopt->quantum); ++ ++ if (qopt->ecn) ++ fprintf(f, "ecn "); ++ ++ if (qopt->set_default) ++ fprintf(f, "set_default "); ++ ++ fprintf(f, "accel_mode %d ", qopt->accel_mode); ++ ++ return 0; ++} ++ ++static int nssfq_codel_print_xstats(struct qdisc_util *qu, FILE *f, struct rtattr *xstats) ++{ ++ struct tc_nssfq_codel_xstats *st; ++ ++ if (xstats == NULL) ++ return 0; ++ ++ if (RTA_PAYLOAD(xstats) < sizeof(*st)) ++ return -1; ++ ++ st = RTA_DATA(xstats); ++ fprintf(f, " maxpacket %u drop_overlimit %u new_flow_count %u ecn_mark %u\n", ++ st->maxpacket, st->drop_overlimit, st->new_flow_count, st->ecn_mark); ++ fprintf(f, " new_flows_len %u old_flows_len %u", st->new_flows_len, st->old_flows_len); ++ ++ return 0; ++} ++ ++struct qdisc_util nssfq_codel_qdisc_util = { ++ .id = "nssfq_codel", ++ .parse_qopt = nssfq_codel_parse_opt, ++ .print_qopt = nssfq_codel_print_opt, ++ .print_xstats = nssfq_codel_print_xstats, ++}; ++ ++/* ======================== NSSCODEL =======================*/ ++ ++static void nsscodel_explain(void) ++{ ++ fprintf(stderr, "Usage: ... nsscodel target TIME interval TIME [ limit PACKETS ] [ set_default ] [ accel_mode ]\n"); ++} ++ ++static void nsscodel_explain_err1(void) ++{ ++ fprintf(stderr, "Value of target and interval should be greater than 1ms\n"); ++} ++ ++static int nsscodel_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ struct rtattr *tail; ++ struct tc_nsscodel_qopt opt; ++ bool accel_mode = false; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "target") == 0) { ++ NEXT_ARG(); ++ if (get_time(&opt.target, *argv)) { ++ fprintf(stderr, "Illegal \"target\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "limit") == 0) { ++ NEXT_ARG(); ++ if (get_size(&opt.limit, *argv) || opt.limit == 0) { ++ fprintf(stderr, "Illegal \"limit\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "interval") == 0) { ++ NEXT_ARG(); ++ if (get_time(&opt.interval, *argv)) { ++ fprintf(stderr, "Illegal \"interval\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "set_default") == 0) { ++ opt.set_default = 1; ++ } else if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else if (strcmp(*argv, "help") == 0) { ++ nsscodel_explain(); ++ return -1; ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ nsscodel_explain(); ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_NSS_FW; ++ } else if (opt.accel_mode != TCA_NSS_ACCEL_MODE_NSS_FW) { ++ fprintf(stderr, "accel_mode should be %d\n", TCA_NSS_ACCEL_MODE_NSS_FW); ++ return -1; ++ } ++ ++ if (!opt.target || !opt.interval) { ++ nsscodel_explain(); ++ return -1; ++ } ++ ++ if (opt.target < 1000 || opt.interval < 1000) { ++ nsscodel_explain_err1(); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSCODEL_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nsscodel_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSCODEL_MAX + 1]; ++ struct tc_nsscodel_qopt *qopt; ++ SPRINT_BUF(b1); ++ SPRINT_BUF(b2); ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSCODEL_MAX, opt); ++ ++ if (tb[TCA_NSSCODEL_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSCODEL_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSCODEL_PARMS]); ++ ++ fprintf(f, "target %s limit %up interval %s ", ++ sprint_time(qopt->target, b1), ++ qopt->limit, ++ sprint_time(qopt->interval, b2)); ++ ++ if (qopt->set_default) ++ fprintf(f, "set_default "); ++ ++ fprintf(f, "accel_mode %d ", qopt->accel_mode); ++ ++ return 0; ++} ++ ++static int nsscodel_print_xstats(struct qdisc_util *qu, FILE *f, struct rtattr *xstats) ++{ ++ struct tc_nsscodel_xstats *st; ++ ++ if (xstats == NULL) ++ return 0; ++ ++ if (RTA_PAYLOAD(xstats) < sizeof(*st)) ++ return -1; ++ ++ st = RTA_DATA(xstats); ++ fprintf(f, " peak queue delay %ums peak drop delay %ums", ++ st->peak_queue_delay, st->peak_drop_delay); ++ ++ return 0; ++} ++ ++struct qdisc_util nsscodel_qdisc_util = { ++ .id = "nsscodel", ++ .parse_qopt = nsscodel_parse_opt, ++ .print_qopt = nsscodel_print_opt, ++ .print_xstats = nsscodel_print_xstats, ++}; ++ ++/* ======================== NSSTBL =======================*/ ++ ++static void nsstbl_explain(void) ++{ ++ fprintf(stderr, "Usage: ... nsstbl burst BYTES rate BPS [ mtu BYTES ] [ accel_mode ]\n"); ++} ++ ++static int nsstbl_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ int ok = 0; ++ struct rtattr *tail; ++ struct tc_nsstbl_qopt opt; ++ bool accel_mode = false; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "burst") == 0 || ++ strcmp(*argv, "buffer") == 0 || ++ strcmp(*argv, "maxburst") == 0) { ++ NEXT_ARG(); ++ if (opt.burst) { ++ fprintf(stderr, "Double \"buffer/burst\" spec\n"); ++ return -1; ++ } ++ if (get_size(&opt.burst, *argv)) { ++ fprintf(stderr, "Illegal \"burst\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "mtu") == 0 || ++ strcmp(*argv, "minburst") == 0) { ++ NEXT_ARG(); ++ if (opt.mtu) { ++ fprintf(stderr, "Double \"mtu/minburst\" spec\n"); ++ return -1; ++ } ++ if (get_size(&opt.mtu, *argv)) { ++ fprintf(stderr, "Illegal \"mtu\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "rate") == 0) { ++ NEXT_ARG(); ++ if (opt.rate) { ++ fprintf(stderr, "Double \"rate\" spec\n"); ++ return -1; ++ } ++ if (get_rate(&opt.rate, *argv)) { ++ fprintf(stderr, "Illegal \"rate\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else if (strcmp(*argv, "help") == 0) { ++ nsstbl_explain(); ++ return -1; ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ nsstbl_explain(); ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!ok) { ++ nsstbl_explain(); ++ return -1; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_PPE; ++ } else if (opt.accel_mode >= TCA_NSS_ACCEL_MODE_MAX) { ++ fprintf(stderr, "accel_mode should be < %d\n", TCA_NSS_ACCEL_MODE_MAX); ++ return -1; ++ } ++ ++ if (!opt.rate || !opt.burst) { ++ fprintf(stderr, "Both \"rate\" and \"burst\" are required.\n"); ++ return -1; ++ } ++ ++ /* ++ * Peakrate is currently not supported, but we keep the infrastructure ++ * for future use. However, we have disabled taking input for this. ++ */ ++ if (opt.peakrate) { ++ if (!opt.mtu) { ++ fprintf(stderr, "\"mtu\" is required, if \"peakrate\" is requested.\n"); ++ return -1; ++ } ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSTBL_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nsstbl_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSTBL_MAX + 1]; ++ struct tc_nsstbl_qopt *qopt; ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSTBL_MAX, opt); ++ ++ if (tb[TCA_NSSTBL_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSTBL_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSTBL_PARMS]); ++ ++ print_size(PRINT_FP, NULL, "buffer/maxburst %s ", qopt->burst); ++ tc_print_rate(PRINT_FP, NULL, "rate %s ", qopt->rate); ++ print_size(PRINT_FP, NULL, "mtu %s ", qopt->mtu); ++ fprintf(f, "accel_mode %d ", qopt->accel_mode); ++ ++ return 0; ++} ++ ++struct qdisc_util nsstbl_qdisc_util = { ++ .id = "nsstbl", ++ .parse_qopt = nsstbl_parse_opt, ++ .print_qopt = nsstbl_print_opt, ++}; ++ ++/* ======================== NSSPRIO =======================*/ ++ ++static void nssprio_explain(void) ++{ ++ fprintf(stderr, "Usage: ... nssprio [ bands NUMBER (default 256) ] [ accel_mode ]\n"); ++} ++ ++static int nssprio_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ int ok = 0; ++ struct rtattr *tail; ++ struct tc_nssprio_qopt opt; ++ bool accel_mode = false; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "bands") == 0) { ++ NEXT_ARG(); ++ if (get_unsigned(&opt.bands, *argv, 0)) { ++ fprintf(stderr, "Illegal \"limit\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else if (strcmp(*argv, "help") == 0) { ++ nssprio_explain(); ++ return -1; ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ nssprio_explain(); ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!ok) { ++ opt.bands = TCA_NSSPRIO_MAX_BANDS; ++ } else if (opt.bands > TCA_NSSPRIO_MAX_BANDS) { ++ nssprio_explain(); ++ return -1; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_PPE; ++ } else if (opt.accel_mode >= TCA_NSS_ACCEL_MODE_MAX) { ++ fprintf(stderr, "accel_mode should be < %d\n", TCA_NSS_ACCEL_MODE_MAX); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSPRIO_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nssprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSPRIO_MAX + 1]; ++ struct tc_nssprio_qopt *qopt; ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSPRIO_MAX, opt); ++ ++ if (tb[TCA_NSSPRIO_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSPRIO_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSPRIO_PARMS]); ++ ++ fprintf(f, "bands %u ", qopt->bands); ++ fprintf(f, "accel_mode %d ", qopt->accel_mode); ++ ++ return 0; ++} ++ ++struct qdisc_util nssprio_qdisc_util = { ++ .id = "nssprio", ++ .parse_qopt = nssprio_parse_opt, ++ .print_qopt = nssprio_print_opt, ++}; ++ ++/* ======================== NSSBF =======================*/ ++ ++static void nssbf_explain_qdisc(void) ++{ ++ fprintf(stderr, ++ "Usage: ... nssbf [ accel_mode ]\n" ++ ); ++} ++ ++static void nssbf_explain_class(void) ++{ ++ fprintf(stderr, "Usage: ... nssbf rate BPS burst BYTES [ mtu BYTES ]\n"); ++ fprintf(stderr, " [ quantum BYTES ]\n"); ++} ++ ++static void nssbf_explain1(char *arg) ++{ ++ fprintf(stderr, "NSSBF: Illegal \"%s\"\n", arg); ++} ++ ++static int nssbf_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ struct tc_nssbf_qopt opt; ++ struct rtattr *tail; ++ bool accel_mode = false; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (matches(*argv, "default") == 0) { ++ NEXT_ARG(); ++ if (opt.defcls != 0) { ++ fprintf(stderr, "NSSBF: Double \"default\"\n"); ++ return -1; ++ } ++ if (get_u16(&opt.defcls, *argv, 16) < 0) { ++ nssbf_explain1("default"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else if (matches(*argv, "help") == 0) { ++ nssbf_explain_qdisc(); ++ return -1; ++ } else { ++ fprintf(stderr, "NSSBF: What is \"%s\" ?\n", *argv); ++ nssbf_explain_qdisc(); ++ return -1; ++ } ++ argc--, argv++; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_NSS_FW; ++ } else if (opt.accel_mode != TCA_NSS_ACCEL_MODE_NSS_FW) { ++ fprintf(stderr, "accel_mode should be %d\n", TCA_NSS_ACCEL_MODE_NSS_FW); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSBF_QDISC_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nssbf_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSBF_MAX + 1]; ++ struct tc_nssbf_qopt *qopt; ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSBF_MAX, opt); ++ ++ if (tb[TCA_NSSBF_QDISC_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSBF_QDISC_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSBF_QDISC_PARMS]); ++ ++ fprintf(f, "accel_mode %d ", qopt->accel_mode); ++ ++ return 0; ++} ++ ++static int nssbf_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ int ok = 0; ++ struct rtattr *tail; ++ struct tc_nssbf_class_qopt opt; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "burst") == 0 || ++ strcmp(*argv, "buffer") == 0 || ++ strcmp(*argv, "maxburst") == 0) { ++ NEXT_ARG(); ++ if (opt.burst) { ++ fprintf(stderr, "Double \"buffer/burst\" spec\n"); ++ return -1; ++ } ++ if (get_size(&opt.burst, *argv)) { ++ fprintf(stderr, "Illegal \"burst\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "mtu") == 0) { ++ NEXT_ARG(); ++ if (opt.mtu) { ++ fprintf(stderr, "Double \"mtu\" spec\n"); ++ return -1; ++ } ++ if (get_size(&opt.mtu, *argv)) { ++ fprintf(stderr, "Illegal \"mtu\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "quantum") == 0) { ++ NEXT_ARG(); ++ if (opt.quantum) { ++ fprintf(stderr, "Double \"quantum\" spec\n"); ++ return -1; ++ } ++ if (get_size(&opt.quantum, *argv)) { ++ fprintf(stderr, "Illegal \"quantum\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "rate") == 0) { ++ NEXT_ARG(); ++ if (opt.rate) { ++ fprintf(stderr, "Double \"rate\" spec\n"); ++ return -1; ++ } ++ if (get_rate(&opt.rate, *argv)) { ++ fprintf(stderr, "Illegal \"rate\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "help") == 0) { ++ nssbf_explain_class(); ++ return -1; ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ nssbf_explain_class(); ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!ok) { ++ nssbf_explain_class(); ++ return -1; ++ } ++ ++ if (!opt.rate || !opt.burst) { ++ fprintf(stderr, "Both \"rate\" and \"burst\" are required.\n"); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSBF_CLASS_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nssbf_print_class_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSBF_MAX + 1]; ++ struct tc_nssbf_class_qopt *qopt; ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSBF_MAX, opt); ++ ++ if (tb[TCA_NSSBF_CLASS_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSBF_CLASS_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSBF_CLASS_PARMS]); ++ ++ print_size(PRINT_FP, NULL, "burst %s ", qopt->burst); ++ tc_print_rate(PRINT_FP, NULL, "rate %s ", qopt->rate); ++ print_size(PRINT_FP, NULL, "quantum %s ", qopt->quantum); ++ print_size(PRINT_FP, NULL, "mtu %s ", qopt->mtu); ++ ++ return 0; ++} ++ ++struct qdisc_util nssbf_qdisc_util = { ++ .id = "nssbf", ++ .parse_qopt = nssbf_parse_opt, ++ .print_qopt = nssbf_print_opt, ++ .parse_copt = nssbf_parse_class_opt, ++ .print_copt = nssbf_print_class_opt, ++}; ++ ++/* ======================== NSSWRR =======================*/ ++ ++static void nsswrr_explain_qdisc(void) ++{ ++ fprintf(stderr, "Usage (qdisc): ... nsswrr [ accel_mode ]\n"); ++} ++ ++static void nsswrr_explain_class(void) ++{ ++ fprintf(stderr, "Usage (class): ... nsswrr quantum PACKETS ]\n"); ++} ++ ++static int nsswrr_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ struct tc_nsswrr_qopt opt; ++ bool accel_mode = false; ++ struct rtattr *tail; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else if (matches(*argv, "help") == 0) { ++ nsswrr_explain_qdisc(); ++ return -1; ++ } else { ++ fprintf(stderr, "What is \"%s\" ?\n", *argv); ++ nsswrr_explain_qdisc(); ++ return -1; ++ } ++ argc--, argv++; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_PPE; ++ } else if (opt.accel_mode >= TCA_NSS_ACCEL_MODE_MAX) { ++ fprintf(stderr, "accel_mode should be < %d\n", TCA_NSS_ACCEL_MODE_MAX); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSWRR_QDISC_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nsswrr_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSWRR_MAX + 1]; ++ struct tc_nsswrr_qopt *qopt; ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSWRR_MAX, opt); ++ ++ if (tb[TCA_NSSWRR_QDISC_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSWRR_QDISC_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSWRR_QDISC_PARMS]); ++ fprintf(f, "accel_mode %d ", qopt->accel_mode); ++ ++ return 0; ++} ++ ++static int nsswrr_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ int ok = 0; ++ struct rtattr *tail; ++ struct tc_nsswrr_class_qopt opt; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "quantum") == 0) { ++ NEXT_ARG(); ++ if (get_u32(&opt.quantum, *argv, 10)) { ++ fprintf(stderr, "Illegal \"quantum\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "help") == 0) { ++ nsswrr_explain_class(); ++ return -1; ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ nsswrr_explain_class(); ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!ok) { ++ nsswrr_explain_class(); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSWRR_CLASS_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nsswrr_print_class_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSWRR_MAX + 1]; ++ struct tc_nsswrr_class_qopt *qopt; ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSWRR_MAX, opt); ++ ++ if (tb[TCA_NSSWRR_CLASS_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSWRR_CLASS_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSWRR_CLASS_PARMS]); ++ ++ fprintf(f, "quantum %up ", qopt->quantum); ++ return 0; ++} ++ ++struct qdisc_util nsswrr_qdisc_util = { ++ .id = "nsswrr", ++ .parse_qopt = nsswrr_parse_opt, ++ .print_qopt = nsswrr_print_opt, ++ .parse_copt = nsswrr_parse_class_opt, ++ .print_copt = nsswrr_print_class_opt, ++}; ++ ++/* ======================== NSSWFQ =======================*/ ++ ++static void nsswfq_explain_qdisc(void) ++{ ++ fprintf(stderr, "Usage (qdisc): ... nsswfq [ accel_mode ]\n"); ++} ++ ++static void nsswfq_explain_class(void) ++{ ++ fprintf(stderr, "Usage (class): ... nsswfq quantum BYTES ]\n"); ++} ++ ++static int nsswfq_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ struct tc_nsswfq_qopt opt; ++ bool accel_mode = false; ++ struct rtattr *tail; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else if (matches(*argv, "help") == 0) { ++ nsswfq_explain_qdisc(); ++ return -1; ++ } else { ++ fprintf(stderr, "NSSWFQ: What is \"%s\" ?\n", *argv); ++ nsswfq_explain_qdisc(); ++ return -1; ++ } ++ argc--, argv++; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_PPE; ++ } else if (opt.accel_mode >= TCA_NSS_ACCEL_MODE_MAX) { ++ fprintf(stderr, "accel_mode should be < %d\n", TCA_NSS_ACCEL_MODE_MAX); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSWFQ_QDISC_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nsswfq_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSWFQ_MAX + 1]; ++ struct tc_nsswfq_qopt *qopt; ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSWFQ_MAX, opt); ++ ++ if (tb[TCA_NSSWFQ_QDISC_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSWFQ_QDISC_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSWFQ_QDISC_PARMS]); ++ fprintf(f, "accel_mode %d ", qopt->accel_mode); ++ ++ return 0; ++} ++ ++static int nsswfq_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ int ok = 0; ++ struct rtattr *tail; ++ struct tc_nsswfq_class_qopt opt; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "quantum") == 0) { ++ NEXT_ARG(); ++ if (get_size(&opt.quantum, *argv)) { ++ fprintf(stderr, "Illegal \"quantum\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "help") == 0) { ++ nsswfq_explain_class(); ++ return -1; ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ nsswfq_explain_class(); ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!ok) { ++ nsswfq_explain_class(); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSWFQ_CLASS_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nsswfq_print_class_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSWFQ_MAX + 1]; ++ struct tc_nsswfq_class_qopt *qopt; ++ SPRINT_BUF(b1); ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSWFQ_MAX, opt); ++ ++ if (tb[TCA_NSSWFQ_CLASS_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSWFQ_CLASS_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSWFQ_CLASS_PARMS]); ++ ++ fprintf(f, "quantum %s ", sprint_size(qopt->quantum, b1)); ++ ++ return 0; ++} ++ ++struct qdisc_util nsswfq_qdisc_util = { ++ .id = "nsswfq", ++ .parse_qopt = nsswfq_parse_opt, ++ .print_qopt = nsswfq_print_opt, ++ .parse_copt = nsswfq_parse_class_opt, ++ .print_copt = nsswfq_print_class_opt, ++}; ++ ++/* ======================== NSSHTB =======================*/ ++ ++static void nsshtb_explain_qdisc(void) ++{ ++ fprintf(stderr, ++ "Usage: ... nsshtb [ r2q ] [ accel_mode ]\n" ++ ); ++} ++ ++static void nsshtb_explain_class(void) ++{ ++ fprintf(stderr, "Usage: ... nsshtb priority 0-3 [ quantum BYTES ] [ rate BPS ] [ burst BYTES ] [crate BPS ] [ cburst BYTES ]\n"); ++ fprintf(stderr, " [ overhead BYTES ] \n"); ++} ++ ++static void nsshtb_explain1(char *arg) ++{ ++ fprintf(stderr, "NSSHTB: Illegal \"%s\"\n", arg); ++} ++ ++static int nsshtb_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ struct tc_nsshtb_qopt opt; ++ struct rtattr *tail; ++ bool accel_mode = false; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "r2q") == 0) { ++ NEXT_ARG(); ++ if (opt.r2q != 0) { ++ fprintf(stderr, "NSSHTB: Double \"r2q\"\n"); ++ return -1; ++ } ++ if (get_u32(&opt.r2q, *argv, 10) < 0) { ++ nsshtb_explain1("r2q"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else if (strcmp(*argv, "help") == 0) { ++ nsshtb_explain_qdisc(); ++ return -1; ++ } else { ++ fprintf(stderr, "NSSHTB: What is \"%s\" ?\n", *argv); ++ nsshtb_explain_qdisc(); ++ return -1; ++ } ++ argc--, argv++; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_PPE; ++ } else if (opt.accel_mode >= TCA_NSS_ACCEL_MODE_MAX) { ++ fprintf(stderr, "accel_mode should be < %d\n", TCA_NSS_ACCEL_MODE_MAX); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSHTB_QDISC_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nsshtb_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSHTB_MAX + 1]; ++ struct tc_nsshtb_qopt *qopt; ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSHTB_MAX, opt); ++ ++ if (tb[TCA_NSSHTB_QDISC_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSHTB_QDISC_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSHTB_QDISC_PARMS]); ++ ++ if (qopt->r2q != 0) ++ fprintf(f, "r2q %u ", qopt->r2q); ++ ++ fprintf(f, "accel_mode %d ", qopt->accel_mode); ++ ++ return 0; ++} ++ ++static int nsshtb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ int ok = 0; ++ struct rtattr *tail; ++ struct tc_nsshtb_class_qopt opt; ++ int crate = 0; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "burst") == 0) { ++ NEXT_ARG(); ++ if (opt.burst) { ++ fprintf(stderr, "Double \"burst\" spec\n"); ++ return -1; ++ } ++ if (get_size(&opt.burst, *argv)) { ++ fprintf(stderr, "Illegal \"burst\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "rate") == 0) { ++ NEXT_ARG(); ++ if (opt.rate) { ++ fprintf(stderr, "Double \"rate\" spec\n"); ++ return -1; ++ } ++ if (get_rate(&opt.rate, *argv)) { ++ fprintf(stderr, "Illegal \"rate\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "cburst") == 0) { ++ NEXT_ARG(); ++ if (opt.cburst) { ++ fprintf(stderr, "Double \"cburst\" spec\n"); ++ return -1; ++ } ++ if (get_size(&opt.cburst, *argv)) { ++ fprintf(stderr, "Illegal \"cburst\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "crate") == 0) { ++ NEXT_ARG(); ++ if (opt.crate) { ++ fprintf(stderr, "Double \"crate\" spec\n"); ++ return -1; ++ } ++ if (get_rate(&opt.crate, *argv)) { ++ fprintf(stderr, "Illegal \"crate\"\n"); ++ return -1; ++ } ++ crate++; ++ ok++; ++ } else if (strcmp(*argv, "priority") == 0) { ++ NEXT_ARG(); ++ if (opt.priority) { ++ fprintf(stderr, "Double \"priority\" spec\n"); ++ return -1; ++ } ++ if (get_u32(&opt.priority, *argv, 10) < 0) { ++ fprintf(stderr, "Illegal \"priority\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "quantum") == 0) { ++ NEXT_ARG(); ++ if (opt.quantum) { ++ fprintf(stderr, "Double \"quantum\" spec\n"); ++ return -1; ++ } ++ if (get_size(&opt.quantum, *argv)) { ++ fprintf(stderr, "Illegal \"quantum\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "overhead") == 0) { ++ NEXT_ARG(); ++ if (opt.overhead) { ++ fprintf(stderr, "Double \"overhead\" spec\n"); ++ return -1; ++ } ++ if (get_size(&opt.overhead, *argv)) { ++ fprintf(stderr, "Illegal \"overhead\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "help") == 0) { ++ nsshtb_explain_class(); ++ return -1; ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ nsshtb_explain_class(); ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!ok) { ++ nsshtb_explain_class(); ++ return -1; ++ } ++ ++ if (opt.rate && !opt.burst) { ++ fprintf(stderr, "\"burst\" required if \"rate\" is specified.\n"); ++ return -1; ++ } ++ ++ if (!crate) { ++ fprintf(stderr, "\"crate\" is required.\n"); ++ return -1; ++ } ++ ++ if (opt.crate && !opt.cburst) { ++ fprintf(stderr, "\"cburst\" required if \"crate\" is non-zero.\n"); ++ return -1; ++ } ++ ++ if (opt.priority > 3) { ++ fprintf(stderr, "\"priority\" should be an integer between 0 and 3.\n"); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSHTB_CLASS_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nsshtb_print_class_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSHTB_MAX + 1]; ++ struct tc_nsshtb_class_qopt *qopt; ++ SPRINT_BUF(b1); ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSHTB_MAX, opt); ++ ++ if (tb[TCA_NSSHTB_CLASS_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSHTB_CLASS_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSHTB_CLASS_PARMS]); ++ ++ print_size(PRINT_FP, NULL, "burst %s ", qopt->burst); ++ tc_print_rate(PRINT_FP, NULL, "rate %s ", qopt->rate); ++ print_size(PRINT_FP, NULL, "cburst %s ", qopt->cburst); ++ tc_print_rate(PRINT_FP, NULL, "crate %s ", qopt->crate); ++ fprintf(f, "priority %u ", qopt->priority); ++ print_size(PRINT_FP, NULL, "quantum %s ", qopt->quantum); ++ print_size(PRINT_FP, NULL, "overhead %s ", qopt->overhead); ++ ++ return 0; ++} ++ ++struct qdisc_util nsshtb_qdisc_util = { ++ .id = "nsshtb", ++ .parse_qopt = nsshtb_parse_opt, ++ .print_qopt = nsshtb_print_opt, ++ .parse_copt = nsshtb_parse_class_opt, ++ .print_copt = nsshtb_print_class_opt, ++}; ++ ++/* ======================== NSSBLACKHOLE ======================= */ ++ ++static void nssblackhole_explain(void) ++{ ++ fprintf(stderr, "Usage: ... nssblackhole [ set_default ] [ accel_mode ]\n"); ++} ++ ++static int nssblackhole_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ struct rtattr *tail; ++ struct tc_nssblackhole_qopt opt; ++ bool accel_mode = false; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "set_default") == 0) { ++ opt.set_default = 1; ++ } else if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else if (strcmp(*argv, "help") == 0) { ++ nssblackhole_explain(); ++ return -1; ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ nssblackhole_explain(); ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_PPE; ++ } else if (opt.accel_mode >= TCA_NSS_ACCEL_MODE_MAX) { ++ fprintf(stderr, "accel_mode should be < %d\n", TCA_NSS_ACCEL_MODE_MAX); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSBLACKHOLE_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nssblackhole_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSBLACKHOLE_MAX + 1]; ++ struct tc_nssblackhole_qopt *qopt; ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSBLACKHOLE_MAX, opt); ++ ++ if (tb[TCA_NSSBLACKHOLE_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSBLACKHOLE_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSBLACKHOLE_PARMS]); ++ ++ if (qopt->set_default) ++ fprintf(f, "set_default "); ++ ++ fprintf(f, "accel_mode %d ", qopt->accel_mode); ++ ++ return 0; ++} ++ ++struct qdisc_util nssblackhole_qdisc_util = { ++ .id = "nssblackhole", ++ .parse_qopt = nssblackhole_parse_opt, ++ .print_qopt = nssblackhole_print_opt, ++}; diff --git a/package/network/utils/iproute2/patches/500-add-nssmirred.patch b/package/network/utils/iproute2/patches/500-add-nssmirred.patch new file mode 100644 index 00000000000000..d5b0d2384e6a54 --- /dev/null +++ b/package/network/utils/iproute2/patches/500-add-nssmirred.patch @@ -0,0 +1,243 @@ +--- a/tc/Makefile ++++ b/tc/Makefile +@@ -55,6 +55,7 @@ TCMODULES += m_tunnel_key.o + TCMODULES += m_sample.o + TCMODULES += m_ct.o + TCMODULES += m_gate.o ++TCMODULES += m_nssmirred.o + TCMODULES += p_ip.o + TCMODULES += p_ip6.o + TCMODULES += p_icmp.o +--- /dev/null ++++ b/tc/m_nssmirred.c +@@ -0,0 +1,183 @@ ++/* ++ ************************************************************************** ++ * Copyright (c) 2019 The Linux Foundation. All rights reserved. ++ * Permission to use, copy, modify, and/or distribute this software for ++ * any purpose with or without fee is hereby granted, provided that the ++ * above copyright notice and this permission notice appear in all copies. ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT ++ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ ************************************************************************** ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "utils.h" ++#include "tc_util.h" ++#include "tc_common.h" ++#include ++ ++/* ++ * explain() ++ * API to print the explaination of nssmirred action statement's ++ * elements. ++ */ ++static void explain(void) ++{ ++ fprintf(stderr, "Usage: nssmirred redirect \n"); ++ fprintf(stderr, "where: \n"); ++ fprintf(stderr, "\tTO_DEVICENAME is the devicename to redirect to\n"); ++ fprintf(stderr, "\tFROM_DEVICENAME is the devicename to redirect from\n"); ++} ++ ++/* ++ * usage() ++ * API to show the usage of the nssmirred action. ++ */ ++static void usage(void) ++{ ++ explain(); ++ exit(-1); ++} ++ ++/* ++ * parse_nss_mirred() ++ * Parse and validate the nssmirred action statement. ++ */ ++static int parse_nss_mirred(struct action_util *a, int *argc_p, char ***argv_p, ++ int tca_id, struct nlmsghdr *n) ++{ ++ int idx, argc = *argc_p; ++ char **argv = *argv_p; ++ struct tc_nss_mirred p; ++ struct rtattr *tail; ++ ++ if (argc < 0) { ++ fprintf(stderr, "nssmirred bad argument count %d. Try option \"help\"\n", argc); ++ goto error; ++ } ++ ++ if (matches(*argv, "nssmirred")) { ++ fprintf(stderr, "nssmirred bad argument %s. Try option \"help\"\n", *argv); ++ goto error; ++ } ++ ++ NEXT_ARG(); ++ if (!matches(*argv, "help")) { ++ usage(); ++ } ++ ++ if (matches(*argv, "redirect")) { ++ fprintf(stderr, "nssmirred bad argument %s. Try option \"help\"\n", *argv); ++ goto error; ++ } ++ ++ NEXT_ARG(); ++ if (matches(*argv, "dev")) { ++ fprintf(stderr, "nssmirred: bad value %s. Try option \"help\"\n", *argv); ++ goto error; ++ } ++ ++ NEXT_ARG(); ++ memset(&p, 0, sizeof(struct tc_nss_mirred)); ++ if ((idx = ll_name_to_index(*argv)) == 0) { ++ fprintf(stderr, "Cannot find to device \"%s\"\n", *argv); ++ goto error; ++ } ++ ++ p.to_ifindex = idx; ++ NEXT_ARG(); ++ if (matches(*argv, "fromdev")) { ++ fprintf(stderr, "nssmirred: bad value %s. Try option \"help\"\n", *argv); ++ goto error; ++ } ++ ++ NEXT_ARG(); ++ if ((idx = ll_name_to_index(*argv)) == 0) { ++ fprintf(stderr, "Cannot find from device \"%s\"\n", *argv); ++ goto error; ++ } ++ ++ p.from_ifindex = idx; ++ p.action = TC_ACT_STOLEN; ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, MAX_MSG, tca_id, NULL, 0); ++ addattr_l(n, MAX_MSG, TCA_NSS_MIRRED_PARMS, &p, sizeof (p)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ argc--; ++ argv++; ++ *argc_p = argc; ++ *argv_p = argv; ++ return 0; ++ ++error: ++ return -1; ++} ++ ++/* ++ * print_nss_mirred() ++ * Print information related to nssmirred action. ++ */ ++static int print_nss_mirred(struct action_util *au, FILE * f, struct rtattr *arg) ++{ ++ struct tc_nss_mirred *p; ++ struct rtattr *tb[TCA_NSS_MIRRED_MAX + 1]; ++ const char *from_dev, *to_dev; ++ ++ if (arg == NULL) { ++ return -1; ++ } ++ ++ parse_rtattr_nested(tb, TCA_NSS_MIRRED_MAX, arg); ++ ++ if (tb[TCA_NSS_MIRRED_PARMS] == NULL) { ++ fprintf(f, "[NULL nssmirred parameters]"); ++ goto error; ++ } ++ ++ p = RTA_DATA(tb[TCA_NSS_MIRRED_PARMS]); ++ if ((from_dev = ll_index_to_name(p->from_ifindex)) == 0) { ++ fprintf(stderr, "Invalid interface (index: %d)\n", p->from_ifindex); ++ goto error; ++ } ++ ++ if ((to_dev = ll_index_to_name(p->to_ifindex)) == 0) { ++ fprintf(stderr, "Invalid interface (index: %d)\n", p->to_ifindex); ++ goto error; ++ } ++ ++ fprintf(f, "nssmirred (%s to device %s) stolen\n", from_dev, to_dev); ++ fprintf(f, "\tindex %d ref %d bind %d\n",p->index,p->refcnt,p->bindcnt); ++ ++ if (show_stats) { ++ if (tb[TCA_NSS_MIRRED_TM]) { ++ struct tcf_t *tm = RTA_DATA(tb[TCA_NSS_MIRRED_TM]); ++ print_tm(f,tm); ++ } ++ } ++ return 0; ++ ++error: ++ return -1; ++} ++ ++/* ++ * nssmirred_action_util ++ * nssmirred action utility structure. ++ */ ++struct action_util nssmirred_action_util = { ++ .id = "nssmirred", ++ .parse_aopt = parse_nss_mirred, ++ .print_aopt = print_nss_mirred, ++}; +--- /dev/null ++++ b/include/linux/tc_act/tc_nssmirred.h +@@ -0,0 +1,44 @@ ++/* ++ ************************************************************************** ++ * Copyright (c) 2019 The Linux Foundation. All rights reserved. ++ * Permission to use, copy, modify, and/or distribute this software for ++ * any purpose with or without fee is hereby granted, provided that the ++ * above copyright notice and this permission notice appear in all copies. ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT ++ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ ************************************************************************** ++ */ ++ ++#ifndef __LINUX_TC_NSS_MIR_H ++#define __LINUX_TC_NSS_MIR_H ++ ++#include ++#include ++ ++/* ++ * tc_nss_mirred ++ * Structure for nssmirred action. ++ */ ++struct tc_nss_mirred { ++ tc_gen; ++ __u32 from_ifindex; /* ifindex of the port to be redirected from */ ++ __u32 to_ifindex; /* ifindex of the port to be redirected to */ ++}; ++ ++/* ++ * Types of nssmirred action parameters. ++ */ ++enum { ++ TCA_NSS_MIRRED_UNSPEC, ++ TCA_NSS_MIRRED_TM, ++ TCA_NSS_MIRRED_PARMS, ++ __TCA_NSS_MIRRED_MAX ++}; ++#define TCA_NSS_MIRRED_MAX (__TCA_NSS_MIRRED_MAX - 1) ++ ++#endif /* __LINUX_TC_NSS_MIR_H */ From 21b5270c725c926bcc35bde0f1a7ef8b22c07939 Mon Sep 17 00:00:00 2001 From: bitthief Date: Mon, 17 Oct 2022 18:37:19 +0300 Subject: [PATCH 020/225] package: kernel: qca-ssdk: fix build with PIE and SSP Signed-off-by: bitthief --- package/kernel/qca-ssdk/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/kernel/qca-ssdk/Makefile b/package/kernel/qca-ssdk/Makefile index d8c8d6cb167c1d..e1430aba76cd56 100644 --- a/package/kernel/qca-ssdk/Makefile +++ b/package/kernel/qca-ssdk/Makefile @@ -42,7 +42,7 @@ MAKE_FLAGS+= \ ARCH=$(LINUX_KARCH) \ TARGET_SUFFIX=$(CONFIG_TARGET_SUFFIX) \ GCC_VERSION=$(GCC_VERSION) \ - EXTRA_CFLAGS=-fno-stack-protector -I$(STAGING_DIR)/usr/include \ + EXTRA_CFLAGS='-fno-PIC -fno-stack-protector -I$(STAGING_DIR)/usr/include' \ SoC=$(CONFIG_TARGET_SUBTARGET) \ PTP_FEATURE=disable SWCONFIG_FEATURE=disable \ ISISC_ENABLE=disable IN_QCA803X_PHY=FALSE \ From 9c8a8af24e6769c8e143836fe2cfdc24e280fc33 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Mon, 22 May 2023 14:49:35 +0200 Subject: [PATCH 021/225] kernel: qca-ssdk: enable parallel building Now that SSDK is being built as a out of tree kmod parallel building finally works, so enable it to cut down the compile time. Signed-off-by: Robert Marko (cherry picked from commit ea663621abd6dba1f04dd4eadc1751987afab16f) Signed-off-by: bitthief --- package/kernel/qca-ssdk/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/package/kernel/qca-ssdk/Makefile b/package/kernel/qca-ssdk/Makefile index e1430aba76cd56..c63a22c8e5d620 100644 --- a/package/kernel/qca-ssdk/Makefile +++ b/package/kernel/qca-ssdk/Makefile @@ -10,6 +10,7 @@ PKG_SOURCE_VERSION:=23a5aa4a4d5834da7a07efb58baebfbee91786b0 PKG_MIRROR_HASH:=9d169ce924a46a4e530031061d3183b92f23c7f46b3106f0b9ba3587846a73ee PKG_FLAGS:=nonshared +PKG_BUILD_PARALLEL:=1 PKG_BUILD_FLAGS:=no-lto include $(INCLUDE_DIR)/kernel.mk From 0d15be189c4e702a40570fb9a3f550f4708d4d32 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 02:01:58 +0300 Subject: [PATCH 022/225] qualcommax: dts: add NSS nodes to IPQ807x devices Signed-off-by: bitthief --- .../arm64/boot/dts/qcom/ipq8070-cax1800.dts | 1 + .../arm64/boot/dts/qcom/ipq8071-ax3600.dtsi | 1 + .../arm64/boot/dts/qcom/ipq8071-eap102.dts | 1 + .../arch/arm64/boot/dts/qcom/ipq8072-301w.dts | 1 + .../arm64/boot/dts/qcom/ipq8072-ax9000.dts | 1 + .../arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts | 1 + .../arch/arm64/boot/dts/qcom/ipq8072-haze.dts | 1 + .../arm64/boot/dts/qcom/ipq8072-wax218.dts | 1 + .../arm64/boot/dts/qcom/ipq8072-wax620.dts | 1 + .../arm64/boot/dts/qcom/ipq8072-wpq873.dts | 1 + .../arm64/boot/dts/qcom/ipq8074-nbg7815.dts | 1 + .../arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi | 271 ++++++++++++++++++ .../arm64/boot/dts/qcom/ipq8074-rax120v2.dts | 1 + .../arm64/boot/dts/qcom/ipq8074-wax630.dts | 3 +- .../boot/dts/qcom/ipq8074-wxr-5950ax12.dts | 1 + 15 files changed, 286 insertions(+), 1 deletion(-) create mode 100644 target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts index 622b8662fa9b66..6064f939219b42 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts @@ -6,6 +6,7 @@ #include "ipq8074-512m.dtsi" #include "ipq8074-ac-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi index 2bb2cce157ca45..2df5ad68c854eb 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi @@ -4,6 +4,7 @@ #include "ipq8074-512m.dtsi" #include "ipq8074-ac-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-eap102.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-eap102.dts index 7067f9296879ca..44b7e9fd669ce8 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-eap102.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-eap102.dts @@ -6,6 +6,7 @@ #include "ipq8074.dtsi" #include "ipq8074-ac-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-301w.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-301w.dts index a7d398ee0f10d1..9681561c74ab26 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-301w.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-301w.dts @@ -6,6 +6,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts index 0df16e9ad7d25b..73d67c7e2c002d 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts @@ -6,6 +6,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts index a4548a77831764..0fb67ed9fe4a89 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts @@ -6,6 +6,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-haze.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-haze.dts index 34499641596b5a..7b1b18117d58de 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-haze.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-haze.dts @@ -5,6 +5,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts index 33a618851c7b43..a159332eec83f2 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts @@ -3,6 +3,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax620.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax620.dts index 74dae6cbf3d593..94fdb977971fcf 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax620.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax620.dts @@ -5,6 +5,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wpq873.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wpq873.dts index a450fbca25ca5e..66d438f335079b 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wpq873.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wpq873.dts @@ -6,6 +6,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts index 5fb8f3b4de4f85..684d714e037cad 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts @@ -9,6 +9,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi new file mode 100644 index 00000000000000..d85a37230a0e04 --- /dev/null +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi @@ -0,0 +1,271 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/ { + nss_dummy_reg: nss-regulator { + compatible = "regulator-fixed"; + regulator-name = "nss-reg"; + regulator-min-microvolt = <848000>; + regulator-max-microvolt = <848000>; + regulator-always-on; + regulator-boot-on; + }; +}; + +&soc { + nss-common { + compatible = "qcom,nss-common"; + reg = <0x01868010 0x1000>; + reg-names = "nss-misc-reset"; + memory-region = <&nss_region>; + }; + + nss0: nss@40000000 { + compatible = "qcom,nss"; + interrupts = , + , + , + , + , + , + , + , + , + ; + reg = <0x39000000 0x1000>, + <0x38000000 0x30000>, + <0x0b111000 0x1000>; + reg-names = "nphys", "vphys", "qgic-phys"; + clocks = <&gcc GCC_NSS_NOC_CLK>, + <&gcc GCC_NSS_PTP_REF_CLK>, + <&gcc GCC_NSS_CSR_CLK>, + <&gcc GCC_NSS_CFG_CLK>, + <&gcc GCC_NSS_IMEM_CLK>, + <&gcc GCC_NSSNOC_QOSGEN_REF_CLK>, + <&gcc GCC_MEM_NOC_NSS_AXI_CLK>, + <&gcc GCC_NSSNOC_SNOC_CLK>, + <&gcc GCC_NSSNOC_TIMEOUT_REF_CLK>, + <&gcc GCC_NSS_CE_AXI_CLK>, + <&gcc GCC_NSS_CE_APB_CLK>, + <&gcc GCC_NSSNOC_CE_AXI_CLK>, + <&gcc GCC_NSSNOC_CE_APB_CLK>, + <&gcc GCC_NSSNOC_UBI0_AHB_CLK>, + <&gcc GCC_UBI0_CORE_CLK>, + <&gcc GCC_UBI0_AHB_CLK>, + <&gcc GCC_UBI0_AXI_CLK>, + <&gcc GCC_UBI0_MPT_CLK>, + <&gcc GCC_UBI0_NC_AXI_CLK>; + clock-names = "nss-noc-clk", + "nss-ptp-ref-clk", + "nss-csr-clk", + "nss-cfg-clk", + "nss-imem-clk", + "nss-nssnoc-qosgen-ref-clk", + "nss-mem-noc-nss-axi-clk", + "nss-nssnoc-snoc-clk", + "nss-nssnoc-timeout-ref-clk", + "nss-ce-axi-clk", + "nss-ce-apb-clk", + "nss-nssnoc-ce-axi-clk", + "nss-nssnoc-ce-apb-clk", + "nss-nssnoc-ahb-clk", + "nss-core-clk", + "nss-ahb-clk", + "nss-axi-clk", + "nss-mpt-clk", + "nss-nc-axi-clk"; + qcom,id = <0>; + qcom,num-queue = <4>; + qcom,num-irq = <10>; + qcom,num-pri = <4>; + qcom,load-addr = <0x40000000>; + qcom,low-frequency = <187200000>; + qcom,mid-frequency = <748800000>; + qcom,max-frequency = <1689600000>; + qcom,bridge-enabled; + qcom,ipv4-enabled; + qcom,ipv4-reasm-enabled; + qcom,ipv6-enabled; + qcom,ipv6-reasm-enabled; + qcom,wlanredirect-enabled; + qcom,tun6rd-enabled; + qcom,l2tpv2-enabled; + qcom,gre-enabled; + qcom,gre-redir-enabled; + qcom,gre-redir-mark-enabled; + qcom,map-t-enabled; + qcom,portid-enabled; + qcom,ppe-enabled; + qcom,pppoe-enabled; + qcom,pptp-enabled; + qcom,tunipip6-enabled; + qcom,shaping-enabled; + qcom,wlan-dataplane-offload-enabled; + qcom,vlan-enabled; + qcom,igs-enabled; + qcom,vxlan-enabled; + qcom,match-enabled; + qcom,mirror-enabled; + qcom,udp-st-enabled; + mx-supply = <&nss_dummy_reg>; + npu-supply = <&nss_dummy_reg>; + }; + + nss1: nss@40800000 { + compatible = "qcom,nss"; + interrupts = , + , + , + , + , + , + , + , + ; + reg = <0x39400000 0x1000>, + <0x38030000 0x30000>, + <0x0b111000 0x1000>; + reg-names = "nphys", "vphys", "qgic-phys"; + clocks = <&gcc GCC_NSS_NOC_CLK>, + <&gcc GCC_NSS_PTP_REF_CLK>, + <&gcc GCC_NSS_CSR_CLK>, + <&gcc GCC_NSS_CFG_CLK>, + <&gcc GCC_NSS_IMEM_CLK>, + <&gcc GCC_NSSNOC_QOSGEN_REF_CLK>, + <&gcc GCC_MEM_NOC_NSS_AXI_CLK>, + <&gcc GCC_NSSNOC_SNOC_CLK>, + <&gcc GCC_NSSNOC_TIMEOUT_REF_CLK>, + <&gcc GCC_NSS_CE_AXI_CLK>, + <&gcc GCC_NSS_CE_APB_CLK>, + <&gcc GCC_NSSNOC_CE_AXI_CLK>, + <&gcc GCC_NSSNOC_CE_APB_CLK>, + <&gcc GCC_NSSNOC_UBI1_AHB_CLK>, + <&gcc GCC_UBI1_CORE_CLK>, + <&gcc GCC_UBI1_AHB_CLK>, + <&gcc GCC_UBI1_AXI_CLK>, + <&gcc GCC_UBI1_MPT_CLK>, + <&gcc GCC_UBI1_NC_AXI_CLK>; + clock-names = "nss-noc-clk", + "nss-ptp-ref-clk", + "nss-csr-clk", + "nss-cfg-clk", + "nss-imem-clk", + "nss-nssnoc-qosgen-ref-clk", + "nss-mem-noc-nss-axi-clk", + "nss-nssnoc-snoc-clk", + "nss-nssnoc-timeout-ref-clk", + "nss-ce-axi-clk", + "nss-ce-apb-clk", + "nss-nssnoc-ce-axi-clk", + "nss-nssnoc-ce-apb-clk", + "nss-nssnoc-ahb-clk", + "nss-core-clk", + "nss-ahb-clk", + "nss-axi-clk", + "nss-mpt-clk", + "nss-nc-axi-clk"; + qcom,id = <1>; + qcom,num-queue = <4>; + qcom,num-irq = <9>; + qcom,num-pri = <4>; + qcom,load-addr = <0x40800000>; + qcom,capwap-enabled; + qcom,dtls-enabled; + qcom,tls-enabled; + qcom,crypto-enabled; + qcom,ipsec-enabled; + qcom,qvpn-enabled; + qcom,pvxlan-enabled; + qcom,clmap-enabled; + qcom,rmnet_rx-enabled; + }; + + nss_crypto: qcom,nss_crypto { + compatible = "qcom,nss-crypto"; + #address-cells = <1>; + #size-cells = <1>; + qcom,max-contexts = <64>; + qcom,max-context-size = <32>; + ranges; + + eip197_node { + compatible = "qcom,eip197"; + reg-names = "crypto_pbase"; + reg = <0x39800000 0x7ffff>; + clocks = <&gcc GCC_NSS_CRYPTO_CLK>, + <&gcc GCC_NSSNOC_CRYPTO_CLK>, + <&gcc GCC_CRYPTO_PPE_CLK>; + clock-names = "crypto_clk", + "crypto_nocclk", + "crypto_ppeclk"; + clock-frequency = /bits/ 64 <600000000 600000000 300000000>; + qcom,dma-mask = <0xff>; + qcom,transform-enabled; + qcom,aes128-cbc; + qcom,aes192-cbc; + qcom,aes256-cbc; + qcom,aes128-ctr; + qcom,aes192-ctr; + qcom,aes256-ctr; + qcom,aes128-ecb; + qcom,aes192-ecb; + qcom,aes256-ecb; + qcom,3des-cbc; + qcom,md5-hash; + qcom,sha160-hash; + qcom,sha224-hash; + qcom,sha384-hash; + qcom,sha512-hash; + qcom,sha256-hash; + qcom,md5-hmac; + qcom,sha160-hmac; + qcom,sha224-hmac; + qcom,sha256-hmac; + qcom,sha384-hmac; + qcom,sha512-hmac; + qcom,aes128-gcm-gmac; + qcom,aes192-gcm-gmac; + qcom,aes256-gcm-gmac; + qcom,aes128-cbc-md5-hmac; + qcom,aes128-cbc-sha160-hmac; + qcom,aes192-cbc-md5-hmac; + qcom,aes192-cbc-sha160-hmac; + qcom,aes256-cbc-md5-hmac; + qcom,aes256-cbc-sha160-hmac; + qcom,aes128-ctr-sha160-hmac; + qcom,aes192-ctr-sha160-hmac; + qcom,aes256-ctr-sha160-hmac; + qcom,aes128-ctr-md5-hmac; + qcom,aes192-ctr-md5-hmac; + qcom,aes256-ctr-md5-hmac; + qcom,3des-cbc-md5-hmac; + qcom,3des-cbc-sha160-hmac; + qcom,aes128-cbc-sha256-hmac; + qcom,aes192-cbc-sha256-hmac; + qcom,aes256-cbc-sha256-hmac; + qcom,aes128-ctr-sha256-hmac; + qcom,aes192-ctr-sha256-hmac; + qcom,aes256-ctr-sha256-hmac; + qcom,3des-cbc-sha256-hmac; + qcom,aes128-cbc-sha384-hmac; + qcom,aes192-cbc-sha384-hmac; + qcom,aes256-cbc-sha384-hmac; + qcom,aes128-ctr-sha384-hmac; + qcom,aes192-ctr-sha384-hmac; + qcom,aes256-ctr-sha384-hmac; + qcom,aes128-cbc-sha512-hmac; + qcom,aes192-cbc-sha512-hmac; + qcom,aes256-cbc-sha512-hmac; + qcom,aes128-ctr-sha512-hmac; + qcom,aes192-ctr-sha512-hmac; + qcom,aes256-ctr-sha512-hmac; + + engine0 { + reg_offset = <0x80000>; + qcom,ifpp-enabled; + qcom,ipue-enabled; + qcom,ofpp-enabled; + qcom,opue-enabled; + }; + }; + }; +}; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-rax120v2.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-rax120v2.dts index 0949d19171a6cf..abb867331cee18 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-rax120v2.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-rax120v2.dts @@ -4,6 +4,7 @@ #include "ipq8074.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include "ipq8074-hk-cpu.dtsi" #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wax630.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wax630.dts index 685e4243ddbf94..cfe0e1708a2ee6 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wax630.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wax630.dts @@ -5,6 +5,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include @@ -15,7 +16,7 @@ aliases { serial0 = &blsp1_uart5; - + ethernet0 = &dp6_syn; ethernet1 = &dp4; label-mac-device = &dp6_syn; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts index 18386c766c3620..5a87bec94554ed 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts @@ -5,6 +5,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include From b00bce04ae0625b69840f29478464fc6f1f6c058 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 02:33:16 +0300 Subject: [PATCH 023/225] qualcommax: dts: provide label for NSS reserved-memory Provide a label for the NSS reserved-memory node so it can be easily passed to the NSS DRV instead of having to global match by name which is fragile. Signed-off-by: bitthief --- .../0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/target/linux/qualcommax/patches-6.1/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch b/target/linux/qualcommax/patches-6.1/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch index af53c077ff1eca..90c3acfb811410 100644 --- a/target/linux/qualcommax/patches-6.1/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch +++ b/target/linux/qualcommax/patches-6.1/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch @@ -22,8 +22,8 @@ Signed-off-by: Robert Marko @@ -85,6 +85,26 @@ #size-cells = <2>; ranges; - -+ nss@40000000 { + ++ nss_region: nss@40000000 { + no-map; + reg = <0x0 0x40000000 0x0 0x01000000>; + }; @@ -66,5 +66,5 @@ Signed-off-by: Robert Marko + reg = <0x0 0x51000000 0x0 0x100000>; + }; }; - + firmware { From 58fa2a766233de5904374e9900586e07cf07c8a3 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 02:12:00 +0300 Subject: [PATCH 024/225] qualcommax: clk: add missing NSS clocks These clocks are needed by ECM and the other NSS drivers. Signed-off-by: bitthief --- ...added-for-necessary-clocks-and-reset.patch | 311 ++++++++++++++++++ ...-gcc_snoc_bus_timeout_ahb_clk-offset.patch | 44 +++ ...074-Fix-gcc_blsp1_ahb_clk-properties.patch | 41 +++ 3 files changed, 396 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/0170-clk-qcom-ipq8074-Support-added-for-necessary-clocks-and-reset.patch create mode 100644 target/linux/qualcommax/patches-6.1/0171-1-clk-qcom-ipq8074-Fix-gcc_snoc_bus_timeout_ahb_clk-offset.patch create mode 100644 target/linux/qualcommax/patches-6.1/0171-2-clk-qcom-ipq8074-Fix-gcc_blsp1_ahb_clk-properties.patch diff --git a/target/linux/qualcommax/patches-6.1/0170-clk-qcom-ipq8074-Support-added-for-necessary-clocks-and-reset.patch b/target/linux/qualcommax/patches-6.1/0170-clk-qcom-ipq8074-Support-added-for-necessary-clocks-and-reset.patch new file mode 100644 index 00000000000000..478de529563e52 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0170-clk-qcom-ipq8074-Support-added-for-necessary-clocks-and-reset.patch @@ -0,0 +1,311 @@ +From 6504bc9edeb1a2a54d813f4bb5d0267e7bf827f9 Mon Sep 17 00:00:00 2001 +From: Praveenkumar I +Date: Thu, 6 Feb 2020 17:35:42 +0530 +Subject: [PATCH 4/8] clk: ipq8074: Support added for necessary clocks and + reset + +Change-Id: I21a76a44185f766e9b6dcba274392ea8e599718b +Signed-off-by: Praveenkumar I +Signed-off-by: Rajkumar Ayyasamy +--- + drivers/clk/qcom/gcc-ipq8074.c | 238 ++++++++++++++++++- + include/dt-bindings/clock/qcom,gcc-ipq8074.h | 35 ++- + 2 files changed, 258 insertions(+), 15 deletions(-) + +--- a/drivers/clk/qcom/gcc-ipq8074.c ++++ b/drivers/clk/qcom/gcc-ipq8074.c +@@ -49,6 +49,22 @@ enum { + P_UNIPHY2_TX, + }; + ++static const char * const gcc_xo_gpll4_gpll0_gpll6_gpll0_div2[] = { ++ "xo", ++ "gpll4", ++ "gpll0", ++ "gpll6", ++ "gpll0_out_main_div2", ++}; ++ ++static const struct parent_map gcc_xo_gpll4_gpll0_gpll6_gpll0_div2_map[] = { ++ { P_XO, 0 }, ++ { P_GPLL4, 1 }, ++ { P_GPLL0, 2 }, ++ { P_GPLL6, 3 }, ++ { P_GPLL0_DIV2, 4 }, ++}; ++ + static struct clk_alpha_pll gpll0_main = { + .offset = 0x21000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], +@@ -636,6 +652,12 @@ static const struct freq_tbl ftbl_pcie_a + { } + }; + ++struct freq_tbl ftbl_pcie_rchng_clk_src[] = { ++ F(19200000, P_XO, 1, 0, 0), ++ F(100000000, P_GPLL0, 8, 0, 0), ++ { } ++}; ++ + static struct clk_rcg2 pcie0_axi_clk_src = { + .cmd_rcgr = 0x75054, + .freq_tbl = ftbl_pcie_axi_clk_src, +@@ -2036,6 +2058,78 @@ static struct clk_rcg2 gp3_clk_src = { + }, + }; + ++struct freq_tbl ftbl_qdss_tsctr_clk_src[] = { ++ F(160000000, P_GPLL0_DIV2, 2.5, 0, 0), ++ F(320000000, P_GPLL0, 2.5, 0, 0), ++ F(600000000, P_GPLL6, 2, 0, 0), ++ { } ++}; ++ ++struct clk_rcg2 qdss_tsctr_clk_src = { ++ .cmd_rcgr = 0x29064, ++ .freq_tbl = ftbl_qdss_tsctr_clk_src, ++ .hid_width = 5, ++ .parent_map = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2_map, ++ .clkr.hw.init = &(struct clk_init_data){ ++ .name = "qdss_tsctr_clk_src", ++ .parent_names = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2, ++ .num_parents = 5, ++ .ops = &clk_rcg2_ops, ++ }, ++}; ++ ++static struct clk_fixed_factor qdss_dap_sync_clk_src = { ++ .mult = 1, ++ .div = 4, ++ .hw.init = &(struct clk_init_data){ ++ .name = "qdss_dap_sync_clk_src", ++ .parent_names = (const char *[]){ ++ "qdss_tsctr_clk_src" ++ }, ++ .num_parents = 1, ++ .ops = &clk_fixed_factor_ops, ++ }, ++}; ++ ++struct freq_tbl ftbl_qdss_at_clk_src[] = { ++ F(66670000, P_GPLL0_DIV2, 6, 0, 0), ++ F(240000000, P_GPLL6, 6, 0, 0), ++ { } ++}; ++ ++struct clk_rcg2 qdss_at_clk_src = { ++ .cmd_rcgr = 0x2900c, ++ .freq_tbl = ftbl_qdss_at_clk_src, ++ .hid_width = 5, ++ .parent_map = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2_map, ++ .clkr.hw.init = &(struct clk_init_data){ ++ .name = "qdss_at_clk_src", ++ .parent_names = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2, ++ .num_parents = 5, ++ .ops = &clk_rcg2_ops, ++ }, ++}; ++ ++ ++struct freq_tbl ftbl_adss_pwm_clk_src[] = { ++ F(19200000, P_XO, 1, 0, 0), ++ F(200000000, P_GPLL0, 4, 0, 0), ++ { } ++}; ++ ++struct clk_rcg2 adss_pwm_clk_src = { ++ .cmd_rcgr = 0x1c008, ++ .freq_tbl = ftbl_adss_pwm_clk_src, ++ .hid_width = 5, ++ .parent_map = gcc_xo_gpll0_map, ++ .clkr.hw.init = &(struct clk_init_data){ ++ .name = "adss_pwm_clk_src", ++ .parent_data = gcc_xo_gpll0, ++ .num_parents = 2, ++ .ops = &clk_rcg2_ops, ++ }, ++}; ++ + static struct clk_branch gcc_blsp1_ahb_clk = { + .halt_reg = 0x01008, + .clkr = { +@@ -4231,13 +4325,7 @@ static struct clk_branch gcc_gp3_clk = { + }, + }; + +-static const struct freq_tbl ftbl_pcie_rchng_clk_src[] = { +- F(19200000, P_XO, 1, 0, 0), +- F(100000000, P_GPLL0, 8, 0, 0), +- { } +-}; +- +-static struct clk_rcg2 pcie0_rchng_clk_src = { ++struct clk_rcg2 pcie0_rchng_clk_src = { + .cmd_rcgr = 0x75070, + .freq_tbl = ftbl_pcie_rchng_clk_src, + .hid_width = 5, +@@ -4329,6 +4417,114 @@ static const struct alpha_pll_config nss + .alpha_en_mask = BIT(24), + }; + ++static struct clk_branch gcc_snoc_bus_timeout2_ahb_clk = { ++ .halt_reg = 0x4700c, ++ .halt_bit = 31, ++ .clkr = { ++ .enable_reg = 0x4700c, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_snoc_bus_timeout2_ahb_clk", ++ .parent_names = (const char *[]){ ++ "usb0_master_clk_src" ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_snoc_bus_timeout3_ahb_clk = { ++ .halt_reg = 0x47014, ++ .halt_bit = 31, ++ .clkr = { ++ .enable_reg = 0x47014, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_snoc_bus_timeout3_ahb_clk", ++ .parent_names = (const char *[]){ ++ "usb1_master_clk_src" ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_dcc_clk = { ++ .halt_reg = 0x77004, ++ .halt_bit = 31, ++ .clkr = { ++ .enable_reg = 0x77004, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_dcc_clk", ++ .parent_names = (const char *[]){ ++ "pcnoc_clk_src" ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_qdss_at_clk = { ++ .halt_reg = 0x29024, ++ .halt_bit = 31, ++ .clkr = { ++ .enable_reg = 0x29024, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_qdss_at_clk", ++ .parent_names = (const char *[]){ ++ "qdss_at_clk_src" ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_qdss_dap_clk = { ++ .halt_reg = 0x29084, ++ .halt_bit = 31, ++ .clkr = { ++ .enable_reg = 0x29084, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_qdss_dap_clk", ++ .parent_names = (const char *[]){ ++ "qdss_dap_sync_clk_src" ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_adss_pwm_clk = { ++ .halt_reg = 0x1c020, ++ .halt_bit = 31, ++ .clkr = { ++ .enable_reg = 0x1c020, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_adss_pwm_clk", ++ .parent_names = (const char *[]){ ++ "adss_pwm_clk_src" ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ + static struct clk_hw *gcc_ipq8074_hws[] = { + &gpll0_out_main_div2.hw, + &gpll6_out_main_div2.hw, +@@ -4337,6 +4533,7 @@ static struct clk_hw *gcc_ipq8074_hws[] + &gcc_xo_div4_clk_src.hw, + &nss_noc_clk_src.hw, + &nss_ppe_cdiv_clk_src.hw, ++ &qdss_dap_sync_clk_src.hw, + }; + + static struct clk_regmap *gcc_ipq8074_clks[] = { +@@ -4568,6 +4765,15 @@ static struct clk_regmap *gcc_ipq8074_cl + [GCC_PCIE0_RCHNG_CLK] = &gcc_pcie0_rchng_clk.clkr, + [GCC_PCIE0_AXI_S_BRIDGE_CLK] = &gcc_pcie0_axi_s_bridge_clk.clkr, + [GCC_CRYPTO_PPE_CLK] = &gcc_crypto_ppe_clk.clkr, ++ [GCC_SNOC_BUS_TIMEOUT2_AHB_CLK] = &gcc_snoc_bus_timeout2_ahb_clk.clkr, ++ [GCC_SNOC_BUS_TIMEOUT3_AHB_CLK] = &gcc_snoc_bus_timeout3_ahb_clk.clkr, ++ [GCC_DCC_CLK] = &gcc_dcc_clk.clkr, ++ [QDSS_TSCTR_CLK_SRC] = &qdss_tsctr_clk_src.clkr, ++ [QDSS_AT_CLK_SRC] = &qdss_at_clk_src.clkr, ++ [GCC_QDSS_AT_CLK] = &gcc_qdss_at_clk.clkr, ++ [GCC_QDSS_DAP_CLK] = &gcc_qdss_dap_clk.clkr, ++ [ADSS_PWM_CLK_SRC] = &adss_pwm_clk_src.clkr, ++ [GCC_ADSS_PWM_CLK] = &gcc_adss_pwm_clk.clkr, + }; + + static const struct qcom_reset_map gcc_ipq8074_resets[] = { +--- a/include/dt-bindings/clock/qcom,gcc-ipq8074.h ++++ b/include/dt-bindings/clock/qcom,gcc-ipq8074.h +@@ -230,10 +230,19 @@ + #define GCC_GP1_CLK 221 + #define GCC_GP2_CLK 222 + #define GCC_GP3_CLK 223 +-#define GCC_PCIE0_AXI_S_BRIDGE_CLK 224 +-#define GCC_PCIE0_RCHNG_CLK_SRC 225 +-#define GCC_PCIE0_RCHNG_CLK 226 +-#define GCC_CRYPTO_PPE_CLK 227 ++#define GCC_CRYPTO_PPE_CLK 224 ++#define GCC_PCIE0_RCHNG_CLK_SRC 225 ++#define GCC_PCIE0_RCHNG_CLK 226 ++#define GCC_PCIE0_AXI_S_BRIDGE_CLK 227 ++#define GCC_SNOC_BUS_TIMEOUT2_AHB_CLK 228 ++#define GCC_SNOC_BUS_TIMEOUT3_AHB_CLK 229 ++#define GCC_DCC_CLK 230 ++#define ADSS_PWM_CLK_SRC 231 ++#define GCC_ADSS_PWM_CLK 232 ++#define QDSS_TSCTR_CLK_SRC 233 ++#define QDSS_AT_CLK_SRC 234 ++#define GCC_QDSS_AT_CLK 235 ++#define GCC_QDSS_DAP_CLK 236 + + #define GCC_BLSP1_BCR 0 + #define GCC_BLSP1_QUP1_BCR 1 diff --git a/target/linux/qualcommax/patches-6.1/0171-1-clk-qcom-ipq8074-Fix-gcc_snoc_bus_timeout_ahb_clk-offset.patch b/target/linux/qualcommax/patches-6.1/0171-1-clk-qcom-ipq8074-Fix-gcc_snoc_bus_timeout_ahb_clk-offset.patch new file mode 100644 index 00000000000000..ec0528f39db5cc --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0171-1-clk-qcom-ipq8074-Fix-gcc_snoc_bus_timeout_ahb_clk-offset.patch @@ -0,0 +1,44 @@ +From 462aa0c53397ec5bf78e3e7f68aa8a3ca300f4ba Mon Sep 17 00:00:00 2001 +From: Selvam Sathappan Periakaruppan +Date: Tue, 24 Mar 2020 19:09:38 +0530 +Subject: [PATCH 5/8] clk: qcom: ipq8074: Fix gcc_snoc_bus_timeout_ahb_clk + offset + +By default, the ipq8074 V2 clks are provided in the gcc driver. +Updating the gcc_snoc_bus_timeout_ahb_clk offsets also as needed +in ipq8074 V2. + +Change-Id: I5a6e98d002f5c3354a804e55dd9ebb1f83f7f974 +Signed-off-by: Selvam Sathappan Periakaruppan +--- + drivers/clk/qcom/gcc-ipq8074.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/clk/qcom/gcc-ipq8074.c ++++ b/drivers/clk/qcom/gcc-ipq8074.c +@@ -4418,10 +4418,10 @@ static const struct alpha_pll_config nss + }; + + static struct clk_branch gcc_snoc_bus_timeout2_ahb_clk = { +- .halt_reg = 0x4700c, ++ .halt_reg = 0x47014, + .halt_bit = 31, + .clkr = { +- .enable_reg = 0x4700c, ++ .enable_reg = 0x47014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_snoc_bus_timeout2_ahb_clk", +@@ -4436,10 +4436,10 @@ static struct clk_branch gcc_snoc_bus_ti + }; + + static struct clk_branch gcc_snoc_bus_timeout3_ahb_clk = { +- .halt_reg = 0x47014, ++ .halt_reg = 0x4701C, + .halt_bit = 31, + .clkr = { +- .enable_reg = 0x47014, ++ .enable_reg = 0x4701C, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_snoc_bus_timeout3_ahb_clk", diff --git a/target/linux/qualcommax/patches-6.1/0171-2-clk-qcom-ipq8074-Fix-gcc_blsp1_ahb_clk-properties.patch b/target/linux/qualcommax/patches-6.1/0171-2-clk-qcom-ipq8074-Fix-gcc_blsp1_ahb_clk-properties.patch new file mode 100644 index 00000000000000..be70e6418cf021 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0171-2-clk-qcom-ipq8074-Fix-gcc_blsp1_ahb_clk-properties.patch @@ -0,0 +1,41 @@ +From 52315bec6ed633b6a71f28b746029602f8bd70b9 Mon Sep 17 00:00:00 2001 +From: Balaji Prakash J +Date: Wed, 22 Apr 2020 20:35:30 +0530 +Subject: [PATCH] clk: ipq8074: fix gcc_blsp1_ahb_clk properties + +All the voting enabled clocks does not support the enable +from CBCR register. So, updated gcc_blsp1_ahb_clk enable +register and mask to enable bit in APCS_CLOCK_BRANCH_ENA_VOTE. + +Also, the voting controlled clocks are shared among multiple +components like APSS, RPM, NSS, TZ, etc. So, turning the +voting off from APSS does not make the clock off if it has +been voted from another component. Added the flag +BRANCH_HALT_VOTED in order to skip checking the clock +disable status. + +This change is referred from the below commits, +1. 246b4fb3af9bd65d8af794aac2f0e7b1ed9cc2dd +2. c8374157d5ae91d3b3e0d513d62808a798b32d3a + +Signed-off-by: Balaji Prakash J +Change-Id: I505cb560b31ad27a02c165fbe13bb33a2fc7d230 +--- + drivers/clk/qcom/gcc-ipq8074.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/clk/qcom/gcc-ipq8074.c ++++ b/drivers/clk/qcom/gcc-ipq8074.c +@@ -2132,9 +2132,10 @@ struct clk_rcg2 adss_pwm_clk_src = { + + static struct clk_branch gcc_blsp1_ahb_clk = { + .halt_reg = 0x01008, ++ .halt_check = BRANCH_HALT_VOTED, + .clkr = { +- .enable_reg = 0x01008, +- .enable_mask = BIT(0), ++ .enable_reg = 0x0b004, ++ .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ From f9a6ded4914c6ff1dcf3c1440726e2f1a40ad0d3 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 01:24:45 +0300 Subject: [PATCH 025/225] qualcommax: net: QCA NSS igs support Signed-off-by: bitthief --- .../include/uapi/linux/tc_act/tc_nss_mirred.h | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 target/linux/qualcommax/files/include/uapi/linux/tc_act/tc_nss_mirred.h diff --git a/target/linux/qualcommax/files/include/uapi/linux/tc_act/tc_nss_mirred.h b/target/linux/qualcommax/files/include/uapi/linux/tc_act/tc_nss_mirred.h new file mode 100644 index 00000000000000..3a368fcc8c17ee --- /dev/null +++ b/target/linux/qualcommax/files/include/uapi/linux/tc_act/tc_nss_mirred.h @@ -0,0 +1,36 @@ +#ifndef __LINUX_TC_NSS_MIRRED_H +#define __LINUX_TC_NSS_MIRRED_H + +#include + +/* + * Type of nss mirred action. + */ +#define TCA_ACT_MIRRED_NSS 17 + +/* + * Types of parameters for nss mirred action. + */ +enum { + TC_NSS_MIRRED_UNSPEC, + TC_NSS_MIRRED_TM, + TC_NSS_MIRRED_PARMS, + __TC_NSS_MIRRED_MAX +}; +#define TC_NSS_MIRRED_MAX (__TC_NSS_MIRRED_MAX - 1) + +/* + * tc_nss_mirred + * tc command structure for nss mirred action. + */ +struct tc_nss_mirred { + tc_gen; /* General tc structure. */ + __u32 from_ifindex; /* ifindex of the port from which traffic + * will be redirected. + */ + __u32 to_ifindex; /* ifindex of the port to which traffic + * will be redirected. + */ +}; + +#endif /* __LINUX_TC_NSS_MIRRED_H */ From 36eb411a74c79ab4ccdb471cbc91c9091e55d615 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 01:25:01 +0300 Subject: [PATCH 026/225] qualcommax: net: QCA NSS qdisc ifb support Signed-off-by: bitthief --- .../netfilter/nf_conntrack_dscpremark_ext.h | 95 +++++++++++++++++++ .../netfilter/nf_conntrack_dscpremark_ext.c | 61 ++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 target/linux/qualcommax/files/include/net/netfilter/nf_conntrack_dscpremark_ext.h create mode 100644 target/linux/qualcommax/files/net/netfilter/nf_conntrack_dscpremark_ext.c diff --git a/target/linux/qualcommax/files/include/net/netfilter/nf_conntrack_dscpremark_ext.h b/target/linux/qualcommax/files/include/net/netfilter/nf_conntrack_dscpremark_ext.h new file mode 100644 index 00000000000000..dc6a5004ef6d7a --- /dev/null +++ b/target/linux/qualcommax/files/include/net/netfilter/nf_conntrack_dscpremark_ext.h @@ -0,0 +1,95 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* DSCP remark conntrack extension APIs. */ + +#ifndef _NF_CONNTRACK_DSCPREMARK_H +#define _NF_CONNTRACK_DSCPREMARK_H + +#include +#include + +/* Rule flags */ +#define NF_CT_DSCPREMARK_EXT_DSCP_RULE_VALID 0x1 + +/* Rule validity */ +#define NF_CT_DSCPREMARK_EXT_RULE_VALID 0x1 +#define NF_CT_DSCPREMARK_EXT_RULE_NOT_VALID 0x0 + +/* Which QoS features are set flags */ +#define NF_CT_DSCPREMARK_EXT_PRIO 0x1 +#define NF_CT_DSCPREMARK_EXT_DSCP 0x2 +#define NF_CT_DSCPREMARK_EXT_IGS_QOS 0x4 +#define NF_CT_DSCPREMARK_EXT_MARK 0x8 + +/* + * DSCP remark conntrack extension structure. + */ +struct nf_ct_dscpremark_ext { + __u32 flow_priority; /* Original direction packet priority */ + __u32 reply_priority; /* Reply direction packet priority */ + __u32 flow_mark; /* Original direction packet mark */ + __u32 reply_mark; /* Reply direction packet mark */ + __u16 igs_flow_qos_tag; /* Original direction ingress packet priority */ + __u16 igs_reply_qos_tag; /* Reply direction ingress packet priority */ + __u8 flow_dscp; /* IP DSCP value for original direction */ + __u8 reply_dscp; /* IP DSCP value for reply direction */ + __u16 rule_flags; /* Rule Validity flags */ + __u16 flow_set_flags; /* Original direction set flags */ + __u16 return_set_flags; /* Reply direction set flags */ +}; + +/* + * nf_ct_dscpremark_ext_find() + * Finds the extension data of the conntrack entry if it exists. + */ +static inline struct nf_ct_dscpremark_ext * +nf_ct_dscpremark_ext_find(const struct nf_conn *ct) +{ +#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT + return nf_ct_ext_find(ct, NF_CT_EXT_DSCPREMARK); +#else + return NULL; +#endif +} + +/* + * nf_ct_dscpremark_ext_add() + * Adds the extension data to the conntrack entry. + */ +static inline +struct nf_ct_dscpremark_ext *nf_ct_dscpremark_ext_add(struct nf_conn *ct, + gfp_t gfp) +{ +#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT + struct nf_ct_dscpremark_ext *ncde; + + ncde = nf_ct_ext_add(ct, NF_CT_EXT_DSCPREMARK, gfp); + if (!ncde) + return NULL; + + return ncde; +#else + return NULL; +#endif +}; + +#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT +extern int nf_conntrack_dscpremark_ext_set_dscp_rule_valid(struct nf_conn *ct); +extern int nf_conntrack_dscpremark_ext_get_dscp_rule_validity(struct nf_conn *ct); +#endif /* CONFIG_NF_CONNTRACK_DSCPREMARK_EXT */ +#endif /* _NF_CONNTRACK_DSCPREMARK_H */ diff --git a/target/linux/qualcommax/files/net/netfilter/nf_conntrack_dscpremark_ext.c b/target/linux/qualcommax/files/net/netfilter/nf_conntrack_dscpremark_ext.c new file mode 100644 index 00000000000000..678d27ac9df9c2 --- /dev/null +++ b/target/linux/qualcommax/files/net/netfilter/nf_conntrack_dscpremark_ext.c @@ -0,0 +1,61 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* DSCP remark handling conntrack extension registration. */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +/* nf_conntrack_dscpremark_ext_set_dscp_rule_valid() + * Set DSCP rule validity flag in the extension + */ +int nf_conntrack_dscpremark_ext_set_dscp_rule_valid(struct nf_conn *ct) +{ + struct nf_ct_dscpremark_ext *ncde; + + ncde = nf_ct_dscpremark_ext_find(ct); + if (!ncde) + return -1; + + ncde->rule_flags = NF_CT_DSCPREMARK_EXT_DSCP_RULE_VALID; + return 0; +} +EXPORT_SYMBOL(nf_conntrack_dscpremark_ext_set_dscp_rule_valid); + +/* nf_conntrack_dscpremark_ext_get_dscp_rule_validity() + * Check if the DSCP rule flag is valid from the extension + */ +int nf_conntrack_dscpremark_ext_get_dscp_rule_validity(struct nf_conn *ct) +{ + struct nf_ct_dscpremark_ext *ncde; + + ncde = nf_ct_dscpremark_ext_find(ct); + if (!ncde) + return NF_CT_DSCPREMARK_EXT_RULE_NOT_VALID; + + if (ncde->rule_flags & NF_CT_DSCPREMARK_EXT_DSCP_RULE_VALID) + return NF_CT_DSCPREMARK_EXT_RULE_VALID; + + return NF_CT_DSCPREMARK_EXT_RULE_NOT_VALID; +} +EXPORT_SYMBOL(nf_conntrack_dscpremark_ext_get_dscp_rule_validity); From 44f91fcb69df0af5d55a098445634381bc53f123 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 02:16:38 +0300 Subject: [PATCH 027/225] qualcommax: net: QCA NSS ECM support Add patches required to support NSS ECM offload. Signed-off-by: bitthief --- .../0600-1-qca-nss-ecm-support-CORE.patch | 785 ++++++++++++++++++ ...-2-qca-nss-ecm-support-PPPOE-offload.patch | 590 +++++++++++++ ...00-3-qca-nss-ecm-support-net-bonding.patch | 81 ++ ...pport-net-bonding-over-LAG-interface.patch | 672 +++++++++++++++ .../0600-5-qca-nss-ecm-support-macvlan.patch | 96 +++ ...nss-ecm-support-netfilter-DSCPREMARK.patch | 69 ++ 6 files changed, 2293 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch create mode 100644 target/linux/qualcommax/patches-6.1/0600-2-qca-nss-ecm-support-PPPOE-offload.patch create mode 100644 target/linux/qualcommax/patches-6.1/0600-3-qca-nss-ecm-support-net-bonding.patch create mode 100644 target/linux/qualcommax/patches-6.1/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch create mode 100644 target/linux/qualcommax/patches-6.1/0600-5-qca-nss-ecm-support-macvlan.patch create mode 100644 target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch diff --git a/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch b/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch new file mode 100644 index 00000000000000..bbb1b97861fd8a --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch @@ -0,0 +1,785 @@ +--- a/include/linux/if_bridge.h ++++ b/include/linux/if_bridge.h +@@ -69,6 +69,9 @@ void brioctl_set(int (*hook)(struct net + void __user *uarg)); + int br_ioctl_call(struct net *net, struct net_bridge *br, unsigned int cmd, + struct ifreq *ifr, void __user *uarg); ++extern void br_dev_update_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *nlstats); ++extern bool br_is_hairpin_enabled(struct net_device *dev); + + #if IS_ENABLED(CONFIG_BRIDGE) && IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING) + int br_multicast_list_adjacent(struct net_device *dev, +@@ -211,4 +214,42 @@ static inline clock_t br_get_ageing_time + } + #endif + ++/* QCA NSS ECM support - Start */ ++extern struct net_device *br_port_dev_get(struct net_device *dev, ++ unsigned char *addr, ++ struct sk_buff *skb, ++ unsigned int cookie); ++extern void br_refresh_fdb_entry(struct net_device *dev, const char *addr); ++extern void br_fdb_entry_refresh(struct net_device *dev, const char *addr, __u16 vid); ++extern struct net_bridge_fdb_entry *br_fdb_has_entry(struct net_device *dev, ++ const char *addr, ++ __u16 vid); ++extern void br_fdb_update_register_notify(struct notifier_block *nb); ++extern void br_fdb_update_unregister_notify(struct notifier_block *nb); ++ ++typedef struct net_bridge_port *br_port_dev_get_hook_t(struct net_device *dev, ++ struct sk_buff *skb, ++ unsigned char *addr, ++ unsigned int cookie); ++extern br_port_dev_get_hook_t __rcu *br_port_dev_get_hook; ++ ++#define BR_FDB_EVENT_ADD 0x01 ++#define BR_FDB_EVENT_DEL 0x02 ++ ++struct br_fdb_event { ++ struct net_device *dev; ++ unsigned char addr[6]; ++ unsigned char is_local; ++ struct net_bridge *br; ++ struct net_device *orig_dev; ++}; ++extern void br_fdb_register_notify(struct notifier_block *nb); ++extern void br_fdb_unregister_notify(struct notifier_block *nb); ++ ++typedef struct net_bridge_port *br_get_dst_hook_t( ++ const struct net_bridge_port *src, ++ struct sk_buff **skb); ++extern br_get_dst_hook_t __rcu *br_get_dst_hook; ++/* QCA NSS ECM support - End */ ++ + #endif +--- a/include/linux/if_vlan.h ++++ b/include/linux/if_vlan.h +@@ -227,7 +227,28 @@ extern void vlan_vids_del_by_dev(struct + + extern bool vlan_uses_dev(const struct net_device *dev); + ++/* QCA NSS ECM support - Start */ ++extern void __vlan_dev_update_accel_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *stats); ++extern u16 vlan_dev_get_egress_prio(struct net_device *dev, u32 skb_prio); ++extern struct net_device *vlan_dev_next_dev(const struct net_device *dev); ++/* QCA NSS ECM support - End */ ++ + #else ++/* QCA NSS ECM support - Start */ ++static inline void __vlan_dev_update_accel_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *stats) ++{ ++ ++} ++ ++static inline u16 vlan_dev_get_egress_prio(struct net_device *dev, ++ u32 skb_prio) ++{ ++ return 0; ++} ++/* QCA NSS ECM support - End */ ++ + static inline struct net_device * + __vlan_find_dev_deep_rcu(struct net_device *real_dev, + __be16 vlan_proto, u16 vlan_id) +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -2830,6 +2830,10 @@ enum netdev_cmd { + NETDEV_OFFLOAD_XSTATS_DISABLE, + NETDEV_OFFLOAD_XSTATS_REPORT_USED, + NETDEV_OFFLOAD_XSTATS_REPORT_DELTA, ++ /* QCA NSS ECM Support - Start */ ++ NETDEV_BR_JOIN, ++ NETDEV_BR_LEAVE, ++ /* QCA NSS ECM Support - End */ + }; + const char *netdev_cmd_to_name(enum netdev_cmd cmd); + +--- a/include/net/addrconf.h ++++ b/include/net/addrconf.h +@@ -506,4 +506,9 @@ int if6_proc_init(void); + void if6_proc_exit(void); + #endif + ++/* QCA NSS ECM support - Start */ ++struct net_device *ipv6_dev_find_and_hold(struct net *net, struct in6_addr *addr, ++ int strict); ++/* QCA NSS ECM support - End */ ++ + #endif +--- a/include/net/ip6_route.h ++++ b/include/net/ip6_route.h +@@ -211,6 +211,11 @@ void rt6_multipath_rebalance(struct fib6 + void rt6_uncached_list_add(struct rt6_info *rt); + void rt6_uncached_list_del(struct rt6_info *rt); + ++/* QCA NSS ECM support - Start */ ++int rt6_register_notifier(struct notifier_block *nb); ++int rt6_unregister_notifier(struct notifier_block *nb); ++/* QCA NSS ECM support - End */ ++ + static inline const struct rt6_info *skb_rt6_info(const struct sk_buff *skb) + { + const struct dst_entry *dst = skb_dst(skb); +--- a/include/net/neighbour.h ++++ b/include/net/neighbour.h +@@ -604,4 +604,15 @@ static inline void neigh_update_is_route + *notify = 1; + } + } ++ ++/* QCA NSS ECM support - Start */ ++struct neigh_mac_update { ++ unsigned char old_mac[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; ++ unsigned char update_mac[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; ++}; ++ ++extern void neigh_mac_update_register_notify(struct notifier_block *nb); ++extern void neigh_mac_update_unregister_notify(struct notifier_block *nb); ++/* QCA NSS ECM support - End */ ++ + #endif +--- a/include/net/route.h ++++ b/include/net/route.h +@@ -243,6 +243,11 @@ struct rtable *rt_dst_alloc(struct net_d + unsigned int flags, u16 type, bool noxfrm); + struct rtable *rt_dst_clone(struct net_device *dev, struct rtable *rt); + ++/* QCA NSS ECM support - Start */ ++int ip_rt_register_notifier(struct notifier_block *nb); ++int ip_rt_unregister_notifier(struct notifier_block *nb); ++/* QCA NSS ECM support - End */ ++ + struct in_ifaddr; + void fib_add_ifaddr(struct in_ifaddr *); + void fib_del_ifaddr(struct in_ifaddr *, struct in_ifaddr *); +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -2172,4 +2172,9 @@ void br_do_proxy_suppress_arp(struct sk_ + void br_do_suppress_nd(struct sk_buff *skb, struct net_bridge *br, + u16 vid, struct net_bridge_port *p, struct nd_msg *msg); + struct nd_msg *br_is_nd_neigh_msg(struct sk_buff *skb, struct nd_msg *m); ++ ++/* QCA NSS ECM support - Start */ ++#define __br_get(__hook, __default, __args ...) \ ++ (__hook ? (__hook(__args)) : (__default)) ++/* QCA NSS ECM support - End */ + #endif +--- a/net/8021q/vlan_core.c ++++ b/net/8021q/vlan_core.c +@@ -548,4 +548,52 @@ static int __init vlan_offload_init(void + return 0; + } + ++/* QCA NSS ECM support - Start */ ++/* Update the VLAN device with statistics from network offload engines */ ++void __vlan_dev_update_accel_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *nlstats) ++{ ++ struct vlan_pcpu_stats *stats; ++ ++ if (!is_vlan_dev(dev)) ++ return; ++ ++ stats = per_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats, 0); ++ ++ u64_stats_update_begin(&stats->syncp); ++ u64_stats_add(&stats->rx_packets, nlstats->rx_packets); ++ u64_stats_add(&stats->rx_bytes, nlstats->rx_bytes); ++ u64_stats_add(&stats->tx_packets, nlstats->tx_packets); ++ u64_stats_add(&stats->tx_bytes, nlstats->tx_bytes); ++ u64_stats_update_end(&stats->syncp); ++} ++EXPORT_SYMBOL(__vlan_dev_update_accel_stats); ++ ++/* Lookup the 802.1p egress_map table and return the 802.1p value */ ++u16 vlan_dev_get_egress_prio(struct net_device *dev, u32 skb_prio) ++{ ++ struct vlan_priority_tci_mapping *mp; ++ ++ mp = vlan_dev_priv(dev)->egress_priority_map[(skb_prio & 0xf)]; ++ while (mp) { ++ if (mp->priority == skb_prio) { ++ /* This should already be shifted ++ * to mask correctly with the ++ * VLAN's TCI ++ */ ++ return mp->vlan_qos; ++ } ++ mp = mp->next; ++ } ++ return 0; ++} ++EXPORT_SYMBOL(vlan_dev_get_egress_prio); ++ ++struct net_device *vlan_dev_next_dev(const struct net_device *dev) ++{ ++ return vlan_dev_priv(dev)->real_dev; ++} ++EXPORT_SYMBOL(vlan_dev_next_dev); ++/* QCA NSS ECM support - End */ ++ + fs_initcall(vlan_offload_init); +--- a/net/bridge/br_fdb.c ++++ b/net/bridge/br_fdb.c +@@ -33,6 +33,35 @@ static const struct rhashtable_params br + + static struct kmem_cache *br_fdb_cache __read_mostly; + ++/* QCA NSS ECM support - Start */ ++ATOMIC_NOTIFIER_HEAD(br_fdb_notifier_list); ++ATOMIC_NOTIFIER_HEAD(br_fdb_update_notifier_list); ++ ++void br_fdb_register_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_register(&br_fdb_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(br_fdb_register_notify); ++ ++void br_fdb_unregister_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_unregister(&br_fdb_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(br_fdb_unregister_notify); ++ ++void br_fdb_update_register_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_register(&br_fdb_update_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(br_fdb_update_register_notify); ++ ++void br_fdb_update_unregister_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_unregister(&br_fdb_update_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(br_fdb_update_unregister_notify); ++/* QCA NSS ECM support - End */ ++ + int __init br_fdb_init(void) + { + br_fdb_cache = kmem_cache_create("bridge_fdb_cache", +@@ -185,7 +214,26 @@ static void fdb_notify(struct net_bridge + struct sk_buff *skb; + int err = -ENOBUFS; + +- if (swdev_notify) ++ /* QCA NSS ECM support - Start */ ++ if (fdb->dst) { ++ int event; ++ struct br_fdb_event fdb_event; ++ ++ if (type == RTM_NEWNEIGH) ++ event = BR_FDB_EVENT_ADD; ++ else ++ event = BR_FDB_EVENT_DEL; ++ ++ fdb_event.dev = fdb->dst->dev; ++ ether_addr_copy(fdb_event.addr, fdb->key.addr.addr); ++ fdb_event.is_local = test_bit(BR_FDB_LOCAL, &fdb->flags); ++ atomic_notifier_call_chain(&br_fdb_notifier_list, ++ event, ++ (void *)&fdb_event); ++ } ++ /* QCA NSS ECM support - End */ ++ ++ if (swdev_notify) + br_switchdev_fdb_notify(br, fdb, type); + + skb = nlmsg_new(fdb_nlmsg_size(), GFP_ATOMIC); +@@ -520,6 +568,7 @@ void br_fdb_cleanup(struct work_struct * + unsigned long delay = hold_time(br); + unsigned long work_delay = delay; + unsigned long now = jiffies; ++ u8 mac_addr[6]; /* QCA NSS ECM support */ + + /* this part is tricky, in order to avoid blocking learning and + * consequently forwarding, we rely on rcu to delete objects with +@@ -546,8 +595,15 @@ void br_fdb_cleanup(struct work_struct * + work_delay = min(work_delay, this_timer - now); + } else { + spin_lock_bh(&br->hash_lock); +- if (!hlist_unhashed(&f->fdb_node)) ++ if (!hlist_unhashed(&f->fdb_node)) { ++ ether_addr_copy(mac_addr, f->key.addr.addr); + fdb_delete(br, f, true); ++ /* QCA NSS ECM support - Start */ ++ atomic_notifier_call_chain( ++ &br_fdb_update_notifier_list, 0, ++ (void *)mac_addr); ++ /* QCA NSS ECM support - End */ ++ } + spin_unlock_bh(&br->hash_lock); + } + } +@@ -879,6 +935,12 @@ void br_fdb_update(struct net_bridge *br + &fdb->flags))) + clear_bit(BR_FDB_ADDED_BY_EXT_LEARN, + &fdb->flags); ++ ++ /* QCA NSS ECM support - Start */ ++ atomic_notifier_call_chain( ++ &br_fdb_update_notifier_list, ++ 0, (void *)addr); ++ /* QCA NSS ECM support - End */ + } + + if (unlikely(test_bit(BR_FDB_ADDED_BY_USER, &flags))) +@@ -1466,3 +1528,62 @@ void br_fdb_clear_offload(const struct n + spin_unlock_bh(&p->br->hash_lock); + } + EXPORT_SYMBOL_GPL(br_fdb_clear_offload); ++ ++/* QCA NSS ECM support - Start */ ++/* Refresh FDB entries for bridge packets being forwarded by offload engines */ ++void br_refresh_fdb_entry(struct net_device *dev, const char *addr) ++{ ++ struct net_bridge_port *p = br_port_get_rcu(dev); ++ ++ if (!p || p->state == BR_STATE_DISABLED) ++ return; ++ ++ if (!is_valid_ether_addr(addr)) { ++ pr_info("bridge: Attempt to refresh with invalid ether address %pM\n", ++ addr); ++ return; ++ } ++ ++ rcu_read_lock(); ++ br_fdb_update(p->br, p, addr, 0, true); ++ rcu_read_unlock(); ++} ++EXPORT_SYMBOL_GPL(br_refresh_fdb_entry); ++ ++/* Update timestamp of FDB entries for bridge packets being forwarded by offload engines */ ++void br_fdb_entry_refresh(struct net_device *dev, const char *addr, __u16 vid) ++{ ++ struct net_bridge_fdb_entry *fdb; ++ struct net_bridge_port *p = br_port_get_rcu(dev); ++ ++ if (!p || p->state == BR_STATE_DISABLED) ++ return; ++ ++ rcu_read_lock(); ++ fdb = fdb_find_rcu(&p->br->fdb_hash_tbl, addr, vid); ++ if (likely(fdb)) { ++ fdb->updated = jiffies; ++ } ++ rcu_read_unlock(); ++} ++EXPORT_SYMBOL_GPL(br_fdb_entry_refresh); ++ ++/* Look up the MAC address in the device's bridge fdb table */ ++struct net_bridge_fdb_entry *br_fdb_has_entry(struct net_device *dev, ++ const char *addr, __u16 vid) ++{ ++ struct net_bridge_port *p = br_port_get_rcu(dev); ++ struct net_bridge_fdb_entry *fdb; ++ ++ if (!p || p->state == BR_STATE_DISABLED) ++ return NULL; ++ ++ rcu_read_lock(); ++ fdb = fdb_find_rcu(&p->br->fdb_hash_tbl, addr, vid); ++ rcu_read_unlock(); ++ ++ return fdb; ++} ++EXPORT_SYMBOL_GPL(br_fdb_has_entry); ++/* QCA NSS ECM support - End */ ++ +--- a/net/bridge/br_if.c ++++ b/net/bridge/br_if.c +@@ -26,6 +26,12 @@ + + #include "br_private.h" + ++/* QCA NSS ECM support - Start */ ++/* Hook for external forwarding logic */ ++br_port_dev_get_hook_t __rcu *br_port_dev_get_hook __read_mostly; ++EXPORT_SYMBOL_GPL(br_port_dev_get_hook); ++/* QCA NSS ECM support - End */ ++ + /* + * Determine initial path cost based on speed. + * using recommendations from 802.1d standard +@@ -696,6 +702,8 @@ int br_add_if(struct net_bridge *br, str + + kobject_uevent(&p->kobj, KOBJ_ADD); + ++ call_netdevice_notifiers(NETDEV_BR_JOIN, dev); /* QCA NSS ECM support */ ++ + return 0; + + err6: +@@ -731,6 +739,8 @@ int br_del_if(struct net_bridge *br, str + if (!p || p->br != br) + return -EINVAL; + ++ call_netdevice_notifiers(NETDEV_BR_LEAVE, dev); /* QCA NSS ECM support */ ++ + /* Since more than one interface can be attached to a bridge, + * there still maybe an alternate path for netconsole to use; + * therefore there is no reason for a NETDEV_RELEASE event. +@@ -774,3 +784,96 @@ bool br_port_flag_is_set(const struct ne + return p->flags & flag; + } + EXPORT_SYMBOL_GPL(br_port_flag_is_set); ++ ++/* QCA NSS ECM support - Start */ ++/* API to know if hairpin feature is enabled/disabled on this bridge port */ ++bool br_is_hairpin_enabled(struct net_device *dev) ++{ ++ struct net_bridge_port *port = br_port_get_check_rcu(dev); ++ ++ if (likely(port)) ++ return port->flags & BR_HAIRPIN_MODE; ++ return false; ++} ++EXPORT_SYMBOL_GPL(br_is_hairpin_enabled); ++ ++/* br_port_dev_get() ++ * If a skb is provided, and the br_port_dev_get_hook_t hook exists, ++ * use that to try and determine the egress port for that skb. ++ * If not, or no egress port could be determined, use the given addr ++ * to identify the port to which it is reachable, ++ * returing a reference to the net device associated with that port. ++ * ++ * NOTE: Return NULL if given dev is not a bridge or the mac has no ++ * associated port. ++ */ ++struct net_device *br_port_dev_get(struct net_device *dev, unsigned char *addr, ++ struct sk_buff *skb, ++ unsigned int cookie) ++{ ++ struct net_bridge_fdb_entry *fdbe; ++ struct net_bridge *br; ++ struct net_device *netdev = NULL; ++ ++ /* Is this a bridge? */ ++ if (!(dev->priv_flags & IFF_EBRIDGE)) ++ return NULL; ++ ++ rcu_read_lock(); ++ ++ /* If the hook exists and the skb isn't NULL, try and get the port */ ++ if (skb) { ++ br_port_dev_get_hook_t *port_dev_get_hook; ++ ++ port_dev_get_hook = rcu_dereference(br_port_dev_get_hook); ++ if (port_dev_get_hook) { ++ struct net_bridge_port *pdst = ++ __br_get(port_dev_get_hook, NULL, dev, skb, ++ addr, cookie); ++ if (pdst) { ++ dev_hold(pdst->dev); ++ netdev = pdst->dev; ++ goto out; ++ } ++ } ++ } ++ ++ /* Either there is no hook, or can't ++ * determine the port to use - fall back to using FDB ++ */ ++ ++ br = netdev_priv(dev); ++ ++ /* Lookup the fdb entry and get reference to the port dev */ ++ fdbe = br_fdb_find_rcu(br, addr, 0); ++ if (fdbe && fdbe->dst) { ++ netdev = fdbe->dst->dev; /* port device */ ++ dev_hold(netdev); ++ } ++out: ++ rcu_read_unlock(); ++ return netdev; ++} ++EXPORT_SYMBOL_GPL(br_port_dev_get); ++ ++/* Update bridge statistics for bridge packets processed by offload engines */ ++void br_dev_update_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *nlstats) ++{ ++ struct pcpu_sw_netstats *tstats; ++ ++ /* Is this a bridge? */ ++ if (!(dev->priv_flags & IFF_EBRIDGE)) ++ return; ++ ++ tstats = this_cpu_ptr(dev->tstats); ++ ++ u64_stats_update_begin(&tstats->syncp); ++ u64_stats_add(&tstats->rx_packets, nlstats->rx_packets); ++ u64_stats_add(&tstats->rx_bytes, nlstats->rx_bytes); ++ u64_stats_add(&tstats->tx_packets, nlstats->tx_packets); ++ u64_stats_add(&tstats->tx_bytes, nlstats->tx_bytes); ++ u64_stats_update_end(&tstats->syncp); ++} ++EXPORT_SYMBOL_GPL(br_dev_update_stats); ++/* QCA NSS ECM support - End */ +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -1295,6 +1295,22 @@ static void neigh_update_hhs(struct neig + } + } + ++/* QCA NSS ECM support - Start */ ++ATOMIC_NOTIFIER_HEAD(neigh_mac_update_notifier_list); ++ ++void neigh_mac_update_register_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_register(&neigh_mac_update_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(neigh_mac_update_register_notify); ++ ++void neigh_mac_update_unregister_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_unregister(&neigh_mac_update_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(neigh_mac_update_unregister_notify); ++/* QCA NSS ECM support - End */ ++ + /* Generic update routine. + -- lladdr is new lladdr or NULL, if it is not supplied. + -- new is new state. +@@ -1323,6 +1339,7 @@ static int __neigh_update(struct neighbo + struct net_device *dev; + int err, notify = 0; + u8 old; ++ struct neigh_mac_update nmu; /* QCA NSS ECM support */ + + trace_neigh_update(neigh, lladdr, new, flags, nlmsg_pid); + +@@ -1337,7 +1354,10 @@ static int __neigh_update(struct neighbo + new = old; + goto out; + } +- if (!(flags & NEIGH_UPDATE_F_ADMIN) && ++ ++ memset(&nmu, 0, sizeof(struct neigh_mac_update)); /* QCA NSS ECM support */ ++ ++ if (!(flags & NEIGH_UPDATE_F_ADMIN) && + (old & (NUD_NOARP | NUD_PERMANENT))) + goto out; + +@@ -1374,7 +1394,12 @@ static int __neigh_update(struct neighbo + - compare new & old + - if they are different, check override flag + */ +- if ((old & NUD_VALID) && ++ /* QCA NSS ECM update - Start */ ++ memcpy(nmu.old_mac, neigh->ha, dev->addr_len); ++ memcpy(nmu.update_mac, lladdr, dev->addr_len); ++ /* QCA NSS ECM update - End */ ++ ++ if ((old & NUD_VALID) && + !memcmp(lladdr, neigh->ha, dev->addr_len)) + lladdr = neigh->ha; + } else { +@@ -1496,8 +1521,11 @@ out: + neigh_update_gc_list(neigh); + if (managed_update) + neigh_update_managed_list(neigh); +- if (notify) ++ if (notify) { + neigh_update_notify(neigh, nlmsg_pid); ++ atomic_notifier_call_chain(&neigh_mac_update_notifier_list, 0, ++ (struct neigh_mac_update *)&nmu); /* QCA NSS ECM support */ ++ } + trace_neigh_update_done(neigh, err); + return err; + } +--- a/net/ipv4/fib_trie.c ++++ b/net/ipv4/fib_trie.c +@@ -1211,6 +1211,9 @@ static bool fib_valid_key_len(u32 key, u + static void fib_remove_alias(struct trie *t, struct key_vector *tp, + struct key_vector *l, struct fib_alias *old); + ++/* Define route change notification chain. */ ++static BLOCKING_NOTIFIER_HEAD(iproute_chain); /* QCA NSS ECM support */ ++ + /* Caller must hold RTNL. */ + int fib_table_insert(struct net *net, struct fib_table *tb, + struct fib_config *cfg, struct netlink_ext_ack *extack) +@@ -1404,6 +1407,9 @@ int fib_table_insert(struct net *net, st + rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, new_fa->tb_id, + &cfg->fc_nlinfo, nlflags); + succeeded: ++ blocking_notifier_call_chain(&iproute_chain, ++ RTM_NEWROUTE, fi); ++ + return 0; + + out_remove_new_fa: +@@ -1774,6 +1780,9 @@ int fib_table_delete(struct net *net, st + if (fa_to_delete->fa_state & FA_S_ACCESSED) + rt_cache_flush(cfg->fc_nlinfo.nl_net); + ++ blocking_notifier_call_chain(&iproute_chain, ++ RTM_DELROUTE, fa_to_delete->fa_info); ++ + fib_release_info(fa_to_delete->fa_info); + alias_free_mem_rcu(fa_to_delete); + return 0; +@@ -2402,6 +2411,20 @@ void __init fib_trie_init(void) + 0, SLAB_PANIC | SLAB_ACCOUNT, NULL); + } + ++/* QCA NSS ECM support - Start */ ++int ip_rt_register_notifier(struct notifier_block *nb) ++{ ++ return blocking_notifier_chain_register(&iproute_chain, nb); ++} ++EXPORT_SYMBOL(ip_rt_register_notifier); ++ ++int ip_rt_unregister_notifier(struct notifier_block *nb) ++{ ++ return blocking_notifier_chain_unregister(&iproute_chain, nb); ++} ++EXPORT_SYMBOL(ip_rt_unregister_notifier); ++/* QCA NSS ECM support - End */ ++ + struct fib_table *fib_trie_table(u32 id, struct fib_table *alias) + { + struct fib_table *tb; +--- a/net/ipv6/ndisc.c ++++ b/net/ipv6/ndisc.c +@@ -665,6 +665,7 @@ void ndisc_send_ns(struct net_device *de + if (skb) + ndisc_send_skb(skb, daddr, saddr); + } ++EXPORT_SYMBOL(ndisc_send_ns); + + void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr, + const struct in6_addr *daddr) +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -3853,6 +3853,9 @@ out_free: + return ERR_PTR(err); + } + ++/* Define route change notification chain. */ ++ATOMIC_NOTIFIER_HEAD(ip6route_chain); /* QCA NSS ECM support */ ++ + int ip6_route_add(struct fib6_config *cfg, gfp_t gfp_flags, + struct netlink_ext_ack *extack) + { +@@ -3864,6 +3867,10 @@ int ip6_route_add(struct fib6_config *cf + return PTR_ERR(rt); + + err = __ip6_ins_rt(rt, &cfg->fc_nlinfo, extack); ++ if (!err) ++ atomic_notifier_call_chain(&ip6route_chain, ++ RTM_NEWROUTE, rt); ++ + fib6_info_release(rt); + + return err; +@@ -3885,6 +3892,9 @@ static int __ip6_del_rt(struct fib6_info + err = fib6_del(rt, info); + spin_unlock_bh(&table->tb6_lock); + ++ if (!err) ++ atomic_notifier_call_chain(&ip6route_chain, ++ RTM_DELROUTE, rt); + out: + fib6_info_release(rt); + return err; +@@ -6338,6 +6348,20 @@ static int ip6_route_dev_notify(struct n + return NOTIFY_OK; + } + ++/* QCA NSS ECM support - Start */ ++int rt6_register_notifier(struct notifier_block *nb) ++{ ++ return atomic_notifier_chain_register(&ip6route_chain, nb); ++} ++EXPORT_SYMBOL(rt6_register_notifier); ++ ++int rt6_unregister_notifier(struct notifier_block *nb) ++{ ++ return atomic_notifier_chain_unregister(&ip6route_chain, nb); ++} ++EXPORT_SYMBOL(rt6_unregister_notifier); ++/* QCA NSS ECM support - End */ ++ + /* + * /proc + */ +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -1629,6 +1629,7 @@ const char *netdev_cmd_to_name(enum netd + N(SVLAN_FILTER_PUSH_INFO) N(SVLAN_FILTER_DROP_INFO) + N(PRE_CHANGEADDR) N(OFFLOAD_XSTATS_ENABLE) N(OFFLOAD_XSTATS_DISABLE) + N(OFFLOAD_XSTATS_REPORT_USED) N(OFFLOAD_XSTATS_REPORT_DELTA) ++ N(BR_JOIN) N(BR_LEAVE) + } + #undef N + return "UNKNOWN_NETDEV_EVENT"; +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -986,6 +986,7 @@ void inet6_ifa_finish_destroy(struct ine + + kfree_rcu(ifp, rcu); + } ++EXPORT_SYMBOL(inet6_ifa_finish_destroy); + + static void + ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) +@@ -2044,6 +2045,36 @@ struct inet6_ifaddr *ipv6_get_ifaddr(str + + return result; + } ++EXPORT_SYMBOL(ipv6_get_ifaddr); ++ ++/* ipv6_dev_find_and_hold() ++ * Find (and hold) net device that has the given address. ++ * Or NULL on failure. ++ */ ++struct net_device *ipv6_dev_find_and_hold(struct net *net, struct in6_addr *addr, ++ int strict) ++{ ++ struct inet6_ifaddr *ifp; ++ struct net_device *dev; ++ ++ ifp = ipv6_get_ifaddr(net, addr, NULL, strict); ++ if (!ifp) ++ return NULL; ++ ++ if (!ifp->idev) { ++ in6_ifa_put(ifp); ++ return NULL; ++ } ++ ++ dev = ifp->idev->dev; ++ if (dev) ++ dev_hold(dev); ++ ++ in6_ifa_put(ifp); ++ ++ return dev; ++} ++EXPORT_SYMBOL(ipv6_dev_find_and_hold); + + /* Gets referenced address, destroys ifaddr */ + +--- a/include/net/vxlan.h ++++ b/include/net/vxlan.h +@@ -427,6 +427,15 @@ static inline __be32 vxlan_compute_rco(u + return vni_field; + } + ++/* ++ * vxlan_get_vni() ++ * Returns the vni corresponding to tunnel ++ */ ++static inline u32 vxlan_get_vni(struct vxlan_dev *vxlan_tun) ++{ ++ return be32_to_cpu(vxlan_tun->cfg.vni); ++} ++ + static inline unsigned short vxlan_get_sk_family(struct vxlan_sock *vs) + { + return vs->sock->sk->sk_family; diff --git a/target/linux/qualcommax/patches-6.1/0600-2-qca-nss-ecm-support-PPPOE-offload.patch b/target/linux/qualcommax/patches-6.1/0600-2-qca-nss-ecm-support-PPPOE-offload.patch new file mode 100644 index 00000000000000..4bb87f49612c32 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0600-2-qca-nss-ecm-support-PPPOE-offload.patch @@ -0,0 +1,590 @@ +--- a/drivers/net/ppp/ppp_generic.c ++++ b/drivers/net/ppp/ppp_generic.c +@@ -48,6 +48,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -254,6 +255,25 @@ struct ppp_net { + #define seq_before(a, b) ((s32)((a) - (b)) < 0) + #define seq_after(a, b) ((s32)((a) - (b)) > 0) + ++ ++/* ++ * Registration/Unregistration methods ++ * for PPP channel connect and disconnect event notifications. ++ */ ++RAW_NOTIFIER_HEAD(ppp_channel_connection_notifier_list); ++ ++void ppp_channel_connection_register_notify(struct notifier_block *nb) ++{ ++ raw_notifier_chain_register(&ppp_channel_connection_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(ppp_channel_connection_register_notify); ++ ++void ppp_channel_connection_unregister_notify(struct notifier_block *nb) ++{ ++ raw_notifier_chain_unregister(&ppp_channel_connection_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(ppp_channel_connection_unregister_notify); ++ + /* Prototypes. */ + static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf, + struct file *file, unsigned int cmd, unsigned long arg); +@@ -3453,7 +3473,10 @@ ppp_connect_channel(struct channel *pch, + struct ppp_net *pn; + int ret = -ENXIO; + int hdrlen; ++ int ppp_proto; ++ int version; + ++ int notify = 0; + pn = ppp_pernet(pch->chan_net); + + mutex_lock(&pn->all_ppp_mutex); +@@ -3485,13 +3508,40 @@ ppp_connect_channel(struct channel *pch, + ++ppp->n_channels; + pch->ppp = ppp; + refcount_inc(&ppp->file.refcnt); ++ ++ /* Set the netdev priv flag if the prototype ++ * is L2TP or PPTP. Return success in all cases ++ */ ++ if (!pch->chan) ++ goto out2; ++ ++ ppp_proto = ppp_channel_get_protocol(pch->chan); ++ if (ppp_proto == PX_PROTO_PPTP) { ++ ppp->dev->priv_flags_ext |= IFF_EXT_PPP_PPTP; ++ } else if (ppp_proto == PX_PROTO_OL2TP) { ++ version = ppp_channel_get_proto_version(pch->chan); ++ if (version == 2) ++ ppp->dev->priv_flags_ext |= IFF_EXT_PPP_L2TPV2; ++ else if (version == 3) ++ ppp->dev->priv_flags_ext |= IFF_EXT_PPP_L2TPV3; ++ } ++ notify = 1; ++ ++ out2: + ppp_unlock(ppp); + ret = 0; +- + outl: + write_unlock_bh(&pch->upl); + out: + mutex_unlock(&pn->all_ppp_mutex); ++ ++ if (notify && ppp && ppp->dev) { ++ dev_hold(ppp->dev); ++ raw_notifier_call_chain(&ppp_channel_connection_notifier_list, ++ PPP_CHANNEL_CONNECT, ppp->dev); ++ dev_put(ppp->dev); ++ } ++ + return ret; + } + +@@ -3509,6 +3559,13 @@ ppp_disconnect_channel(struct channel *p + pch->ppp = NULL; + write_unlock_bh(&pch->upl); + if (ppp) { ++ if (ppp->dev) { ++ dev_hold(ppp->dev); ++ raw_notifier_call_chain(&ppp_channel_connection_notifier_list, ++ PPP_CHANNEL_DISCONNECT, ppp->dev); ++ dev_put(ppp->dev); ++ } ++ + /* remove it from the ppp unit's list */ + ppp_lock(ppp); + list_del(&pch->clist); +@@ -3588,6 +3645,222 @@ static void *unit_find(struct idr *p, in + return idr_find(p, n); + } + ++/* Updates the PPP interface statistics. */ ++void ppp_update_stats(struct net_device *dev, unsigned long rx_packets, ++ unsigned long rx_bytes, unsigned long tx_packets, ++ unsigned long tx_bytes, unsigned long rx_errors, ++ unsigned long tx_errors, unsigned long rx_dropped, ++ unsigned long tx_dropped) ++{ ++ struct ppp *ppp; ++ ++ if (!dev) ++ return; ++ ++ if (dev->type != ARPHRD_PPP) ++ return; ++ ++ ppp = netdev_priv(dev); ++ ++ ppp_xmit_lock(ppp); ++ ppp->stats64.tx_packets += tx_packets; ++ ppp->stats64.tx_bytes += tx_bytes; ++ ppp->dev->stats.tx_errors += tx_errors; ++ ppp->dev->stats.tx_dropped += tx_dropped; ++ if (tx_packets) ++ ppp->last_xmit = jiffies; ++ ppp_xmit_unlock(ppp); ++ ++ ppp_recv_lock(ppp); ++ ppp->stats64.rx_packets += rx_packets; ++ ppp->stats64.rx_bytes += rx_bytes; ++ ppp->dev->stats.rx_errors += rx_errors; ++ ppp->dev->stats.rx_dropped += rx_dropped; ++ if (rx_packets) ++ ppp->last_recv = jiffies; ++ ppp_recv_unlock(ppp); ++} ++ ++/* Returns >0 if the device is a multilink PPP netdevice, 0 if not or < 0 if ++ * the device is not PPP. ++ */ ++int ppp_is_multilink(struct net_device *dev) ++{ ++ struct ppp *ppp; ++ unsigned int flags; ++ ++ if (!dev) ++ return -1; ++ ++ if (dev->type != ARPHRD_PPP) ++ return -1; ++ ++ ppp = netdev_priv(dev); ++ ppp_lock(ppp); ++ flags = ppp->flags; ++ ppp_unlock(ppp); ++ ++ if (flags & SC_MULTILINK) ++ return 1; ++ ++ return 0; ++} ++EXPORT_SYMBOL(ppp_is_multilink); ++ ++/* ppp_channel_get_protocol() ++ * Call this to obtain the underlying protocol of the PPP channel, ++ * e.g. PX_PROTO_OE ++ * ++ * NOTE: Some channels do not use PX sockets so the protocol value may be very ++ * different for them. ++ * NOTE: -1 indicates failure. ++ * NOTE: Once you know the channel protocol you may then either cast 'chan' to ++ * its sub-class or use the channel protocol specific API's as provided by that ++ * channel sub type. ++ */ ++int ppp_channel_get_protocol(struct ppp_channel *chan) ++{ ++ if (!chan->ops->get_channel_protocol) ++ return -1; ++ ++ return chan->ops->get_channel_protocol(chan); ++} ++EXPORT_SYMBOL(ppp_channel_get_protocol); ++ ++/* ppp_channel_get_proto_version() ++ * Call this to get channel protocol version ++ */ ++int ppp_channel_get_proto_version(struct ppp_channel *chan) ++{ ++ if (!chan->ops->get_channel_protocol_ver) ++ return -1; ++ ++ return chan->ops->get_channel_protocol_ver(chan); ++} ++EXPORT_SYMBOL(ppp_channel_get_proto_version); ++ ++/* ppp_channel_hold() ++ * Call this to hold a channel. ++ * ++ * Returns true on success or false if the hold could not happen. ++ * ++ * NOTE: chan must be protected against destruction during this call - ++ * either by correct locking etc. or because you already have an implicit ++ * or explicit hold to the channel already and this is an additional hold. ++ */ ++bool ppp_channel_hold(struct ppp_channel *chan) ++{ ++ if (!chan->ops->hold) ++ return false; ++ ++ chan->ops->hold(chan); ++ return true; ++} ++EXPORT_SYMBOL(ppp_channel_hold); ++ ++/* ppp_channel_release() ++ * Call this to release a hold you have upon a channel ++ */ ++void ppp_channel_release(struct ppp_channel *chan) ++{ ++ chan->ops->release(chan); ++} ++EXPORT_SYMBOL(ppp_channel_release); ++ ++/* Check if ppp xmit lock is on hold */ ++bool ppp_is_xmit_locked(struct net_device *dev) ++{ ++ struct ppp *ppp; ++ ++ if (!dev) ++ return false; ++ ++ if (dev->type != ARPHRD_PPP) ++ return false; ++ ++ ppp = netdev_priv(dev); ++ if (!ppp) ++ return false; ++ ++ if (spin_is_locked(&(ppp)->wlock)) ++ return true; ++ ++ return false; ++} ++EXPORT_SYMBOL(ppp_is_xmit_locked); ++ ++/* ppp_hold_channels() ++ * Returns the PPP channels of the PPP device, storing each one into ++ * channels[]. ++ * ++ * channels[] has chan_sz elements. ++ * This function returns the number of channels stored, up to chan_sz. ++ * It will return < 0 if the device is not PPP. ++ * ++ * You MUST release the channels using ppp_release_channels(). ++ */ ++int ppp_hold_channels(struct net_device *dev, struct ppp_channel *channels[], ++ unsigned int chan_sz) ++{ ++ struct ppp *ppp; ++ int c; ++ struct channel *pch; ++ ++ if (!dev) ++ return -1; ++ ++ if (dev->type != ARPHRD_PPP) ++ return -1; ++ ++ ppp = netdev_priv(dev); ++ ++ c = 0; ++ ppp_lock(ppp); ++ list_for_each_entry(pch, &ppp->channels, clist) { ++ struct ppp_channel *chan; ++ ++ if (!pch->chan) { ++ /* Channel is going / gone away */ ++ continue; ++ } ++ ++ if (c == chan_sz) { ++ /* No space to record channel */ ++ ppp_unlock(ppp); ++ return c; ++ } ++ ++ /* Hold the channel, if supported */ ++ chan = pch->chan; ++ if (!chan->ops->hold) ++ continue; ++ ++ chan->ops->hold(chan); ++ ++ /* Record the channel */ ++ channels[c++] = chan; ++ } ++ ppp_unlock(ppp); ++ return c; ++} ++EXPORT_SYMBOL(ppp_hold_channels); ++ ++/* ppp_release_channels() ++ * Releases channels ++ */ ++void ppp_release_channels(struct ppp_channel *channels[], unsigned int chan_sz) ++{ ++ unsigned int c; ++ ++ for (c = 0; c < chan_sz; ++c) { ++ struct ppp_channel *chan; ++ ++ chan = channels[c]; ++ chan->ops->release(chan); ++ } ++} ++EXPORT_SYMBOL(ppp_release_channels); ++ + /* Module/initialization stuff */ + + module_init(ppp_init); +@@ -3604,6 +3877,7 @@ EXPORT_SYMBOL(ppp_input_error); + EXPORT_SYMBOL(ppp_output_wakeup); + EXPORT_SYMBOL(ppp_register_compressor); + EXPORT_SYMBOL(ppp_unregister_compressor); ++EXPORT_SYMBOL(ppp_update_stats); + MODULE_LICENSE("GPL"); + MODULE_ALIAS_CHARDEV(PPP_MAJOR, 0); + MODULE_ALIAS_RTNL_LINK("ppp"); +--- a/drivers/net/ppp/pppoe.c ++++ b/drivers/net/ppp/pppoe.c +@@ -62,6 +62,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -87,7 +88,7 @@ + static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb); + + static const struct proto_ops pppoe_ops; +-static const struct ppp_channel_ops pppoe_chan_ops; ++static const struct pppoe_channel_ops pppoe_chan_ops; + + /* per-net private data for this module */ + static unsigned int pppoe_net_id __read_mostly; +@@ -692,7 +693,7 @@ static int pppoe_connect(struct socket * + + po->chan.mtu = dev->mtu - sizeof(struct pppoe_hdr) - 2; + po->chan.private = sk; +- po->chan.ops = &pppoe_chan_ops; ++ po->chan.ops = (struct ppp_channel_ops *)&pppoe_chan_ops; + + error = ppp_register_net_channel(dev_net(dev), &po->chan); + if (error) { +@@ -995,9 +996,80 @@ static int pppoe_fill_forward_path(struc + return 0; + } + +-static const struct ppp_channel_ops pppoe_chan_ops = { +- .start_xmit = pppoe_xmit, +- .fill_forward_path = pppoe_fill_forward_path, ++/************************************************************************ ++ * ++ * function called by generic PPP driver to hold channel ++ * ++ ***********************************************************************/ ++static void pppoe_hold_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_hold(sk); ++} ++ ++/************************************************************************ ++ * ++ * function called by generic PPP driver to release channel ++ * ++ ***********************************************************************/ ++static void pppoe_release_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_put(sk); ++} ++ ++/************************************************************************ ++ * ++ * function called to get the channel protocol type ++ * ++ ***********************************************************************/ ++static int pppoe_get_channel_protocol(struct ppp_channel *chan) ++{ ++ return PX_PROTO_OE; ++} ++ ++/************************************************************************ ++ * ++ * function called to get the PPPoE channel addressing ++ * NOTE: This function returns a HOLD to the netdevice ++ * ++ ***********************************************************************/ ++static int pppoe_get_addressing(struct ppp_channel *chan, ++ struct pppoe_opt *addressing) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ struct pppox_sock *po = pppox_sk(sk); ++ int err = 0; ++ ++ *addressing = po->proto.pppoe; ++ if (!addressing->dev) ++ return -ENODEV; ++ ++ dev_hold(addressing->dev); ++ return err; ++} ++ ++/* pppoe_channel_addressing_get() ++ * Return PPPoE channel specific addressing information. ++ */ ++int pppoe_channel_addressing_get(struct ppp_channel *chan, ++ struct pppoe_opt *addressing) ++{ ++ return pppoe_get_addressing(chan, addressing); ++} ++EXPORT_SYMBOL(pppoe_channel_addressing_get); ++ ++static const struct pppoe_channel_ops pppoe_chan_ops = { ++ /* PPPoE specific channel ops */ ++ .get_addressing = pppoe_get_addressing, ++ /* General ppp channel ops */ ++ .ops.start_xmit = pppoe_xmit, ++ .ops.get_channel_protocol = pppoe_get_channel_protocol, ++ .ops.hold = pppoe_hold_chan, ++ .ops.release = pppoe_release_chan, ++ .ops.fill_forward_path = pppoe_fill_forward_path, + }; + + static int pppoe_recvmsg(struct socket *sock, struct msghdr *m, +--- a/include/linux/if_pppox.h ++++ b/include/linux/if_pppox.h +@@ -91,4 +91,17 @@ enum { + PPPOX_DEAD = 16 /* dead, useless, please clean me up!*/ + }; + ++/* ++ * PPPoE Channel specific operations ++ */ ++struct pppoe_channel_ops { ++ /* Must be first - general to all PPP channels */ ++ struct ppp_channel_ops ops; ++ int (*get_addressing)(struct ppp_channel *, struct pppoe_opt *); ++}; ++ ++/* Return PPPoE channel specific addressing information */ ++extern int pppoe_channel_addressing_get(struct ppp_channel *chan, ++ struct pppoe_opt *addressing); ++ + #endif /* !(__LINUX_IF_PPPOX_H) */ +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -1707,6 +1707,24 @@ enum netdev_priv_flags { + IFF_NO_IP_ALIGN = BIT_ULL(33), + }; + ++ ++/** ++ * enum netdev_priv_flags_ext - &struct net_device priv_flags_ext ++ * ++ * These flags are used to check for device type and can be ++ * set and used by the drivers ++ * ++ */ ++enum netdev_priv_flags_ext { ++ IFF_EXT_TUN_TAP = 1<<0, ++ IFF_EXT_PPP_L2TPV2 = 1<<1, ++ IFF_EXT_PPP_L2TPV3 = 1<<2, ++ IFF_EXT_PPP_PPTP = 1<<3, ++ IFF_EXT_GRE_V4_TAP = 1<<4, ++ IFF_EXT_GRE_V6_TAP = 1<<5, ++ IFF_EXT_IFB = 1<<6, ++}; ++ + #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN + #define IFF_EBRIDGE IFF_EBRIDGE + #define IFF_BONDING IFF_BONDING +@@ -2050,7 +2068,8 @@ struct net_device { + /* Read-mostly cache-line for fast-path access */ + unsigned int flags; + unsigned long long priv_flags; +- const struct net_device_ops *netdev_ops; ++ unsigned int priv_flags_ext; ++ const struct net_device_ops *netdev_ops; + int ifindex; + unsigned short gflags; + unsigned short hard_header_len; +--- a/include/linux/ppp_channel.h ++++ b/include/linux/ppp_channel.h +@@ -19,6 +19,10 @@ + #include + #include + #include ++#include ++ ++#define PPP_CHANNEL_DISCONNECT 0 ++#define PPP_CHANNEL_CONNECT 1 + + struct net_device_path; + struct net_device_path_ctx; +@@ -30,9 +34,19 @@ struct ppp_channel_ops { + int (*start_xmit)(struct ppp_channel *, struct sk_buff *); + /* Handle an ioctl call that has come in via /dev/ppp. */ + int (*ioctl)(struct ppp_channel *, unsigned int, unsigned long); ++ /* Get channel protocol type, one of PX_PROTO_XYZ or specific to ++ * the channel subtype ++ */ ++ int (*get_channel_protocol)(struct ppp_channel *); ++ /* Get channel protocol version */ ++ int (*get_channel_protocol_ver)(struct ppp_channel *); ++ /* Hold the channel from being destroyed */ ++ void (*hold)(struct ppp_channel *); ++ /* Release hold on the channel */ ++ void (*release)(struct ppp_channel *); + int (*fill_forward_path)(struct net_device_path_ctx *, +- struct net_device_path *, +- const struct ppp_channel *); ++ struct net_device_path *, ++ const struct ppp_channel *); + }; + + struct ppp_channel { +@@ -76,6 +90,51 @@ extern int ppp_unit_number(struct ppp_ch + /* Get the device name associated with a channel, or NULL if none */ + extern char *ppp_dev_name(struct ppp_channel *); + ++/* Call this to obtain the underlying protocol of the PPP channel, ++ * e.g. PX_PROTO_OE ++ */ ++extern int ppp_channel_get_protocol(struct ppp_channel *); ++ ++/* Call this get protocol version */ ++extern int ppp_channel_get_proto_version(struct ppp_channel *); ++ ++/* Call this to hold a channel */ ++extern bool ppp_channel_hold(struct ppp_channel *); ++ ++/* Call this to release a hold you have upon a channel */ ++extern void ppp_channel_release(struct ppp_channel *); ++ ++/* Release hold on PPP channels */ ++extern void ppp_release_channels(struct ppp_channel *channels[], ++ unsigned int chan_sz); ++ ++/* Hold PPP channels for the PPP device */ ++extern int ppp_hold_channels(struct net_device *dev, ++ struct ppp_channel *channels[], ++ unsigned int chan_sz); ++ ++/* Test if ppp xmit lock is locked */ ++extern bool ppp_is_xmit_locked(struct net_device *dev); ++ ++/* Test if the ppp device is a multi-link ppp device */ ++extern int ppp_is_multilink(struct net_device *dev); ++ ++/* Register the PPP channel connect notifier */ ++extern void ppp_channel_connection_register_notify(struct notifier_block *nb); ++ ++/* Unregister the PPP channel connect notifier */ ++extern void ppp_channel_connection_unregister_notify(struct notifier_block *nb); ++ ++/* Update statistics of the PPP net_device by incrementing related ++ * statistics field value with corresponding parameter ++ */ ++extern void ppp_update_stats(struct net_device *dev, unsigned long rx_packets, ++ unsigned long rx_bytes, unsigned long tx_packets, ++ unsigned long tx_bytes, unsigned long rx_errors, ++ unsigned long tx_errors, unsigned long rx_dropped, ++ unsigned long tx_dropped); ++ ++ + /* + * SMP locking notes: + * The channel code must ensure that when it calls ppp_unregister_channel, diff --git a/target/linux/qualcommax/patches-6.1/0600-3-qca-nss-ecm-support-net-bonding.patch b/target/linux/qualcommax/patches-6.1/0600-3-qca-nss-ecm-support-net-bonding.patch new file mode 100644 index 00000000000000..304b2c471b820f --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0600-3-qca-nss-ecm-support-net-bonding.patch @@ -0,0 +1,81 @@ +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -252,6 +252,8 @@ static const struct flow_dissector_key f + }, + }; + ++static unsigned long bond_id_mask = 0xFFFFFFF0; /* QCA NSS ECM bonding support */ ++ + static struct flow_dissector flow_keys_bonding __read_mostly; + + /*-------------------------- Forward declarations ---------------------------*/ +@@ -4372,6 +4374,24 @@ static int bond_get_lowest_level_rcu(str + } + #endif + ++/* QCA NSS ECM bonding support */ ++int bond_get_id(struct net_device *bond_dev) ++{ ++ struct bonding *bond; ++ int bond_id = 0; ++ ++ if (!((bond_dev->priv_flags & IFF_BONDING) && ++ (bond_dev->flags & IFF_MASTER))) ++ return -EINVAL; ++ ++ bond = netdev_priv(bond_dev); ++ bond_id = bond->id; ++ ++ return bond_id; ++} ++EXPORT_SYMBOL(bond_get_id); ++/* QCA NSS ECM bonding support */ ++ + static void bond_get_stats(struct net_device *bond_dev, + struct rtnl_link_stats64 *stats) + { +@@ -5784,6 +5804,11 @@ static void bond_destructor(struct net_d + + if (bond->rr_tx_counter) + free_percpu(bond->rr_tx_counter); ++ ++ /* QCA NSS ECM bonding support */ ++ if (bond->id != (~0U)) ++ clear_bit(bond->id, &bond_id_mask); ++ /* QCA NSS ECM bonding support */ + } + + void bond_setup(struct net_device *bond_dev) +@@ -6345,6 +6370,14 @@ int bond_create(struct net *net, const c + + bond_work_init_all(bond); + ++ /* QCA NSS ECM bonding support - Start */ ++ bond->id = ~0U; ++ if (bond_id_mask != (~0UL)) { ++ bond->id = (u32)ffz(bond_id_mask); ++ set_bit(bond->id, &bond_id_mask); ++ } ++ /* QCA NSS ECM bonding support - End */ ++ + out: + rtnl_unlock(); + return res; +--- a/include/net/bonding.h ++++ b/include/net/bonding.h +@@ -265,6 +265,7 @@ struct bonding { + spinlock_t ipsec_lock; + #endif /* CONFIG_XFRM_OFFLOAD */ + struct bpf_prog *xdp_prog; ++ u32 id; /* QCA NSS ECM bonding support */ + }; + + #define bond_slave_get_rcu(dev) \ +@@ -658,6 +659,7 @@ struct bond_net { + + int bond_rcv_validate(const struct sk_buff *skb, struct bonding *bond, struct slave *slave); + netdev_tx_t bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); ++int bond_get_id(struct net_device *bond_dev); /* QCA NSS ECM bonding support */ + int bond_create(struct net *net, const char *name); + int bond_create_sysfs(struct bond_net *net); + void bond_destroy_sysfs(struct bond_net *net); diff --git a/target/linux/qualcommax/patches-6.1/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch b/target/linux/qualcommax/patches-6.1/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch new file mode 100644 index 00000000000000..d318ccb5353ab6 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch @@ -0,0 +1,672 @@ +--- a/drivers/net/bonding/bond_3ad.c ++++ b/drivers/net/bonding/bond_3ad.c +@@ -114,7 +114,40 @@ static void ad_marker_info_received(stru + static void ad_marker_response_received(struct bond_marker *marker, + struct port *port); + static void ad_update_actor_keys(struct port *port, bool reset); ++/* QCA NSS ECM bonding support - Start */ ++struct bond_cb __rcu *bond_cb; + ++int bond_register_cb(struct bond_cb *cb) ++{ ++ struct bond_cb *lag_cb; ++ ++ lag_cb = kzalloc(sizeof(*lag_cb), GFP_ATOMIC | __GFP_NOWARN); ++ if (!lag_cb) { ++ return -1; ++ } ++ ++ memcpy((void *)lag_cb, (void *)cb, sizeof(*cb)); ++ ++ rcu_read_lock(); ++ rcu_assign_pointer(bond_cb, lag_cb); ++ rcu_read_unlock(); ++ return 0; ++} ++EXPORT_SYMBOL(bond_register_cb); ++ ++void bond_unregister_cb(void) ++{ ++ struct bond_cb *lag_cb_main; ++ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ rcu_assign_pointer(bond_cb, NULL); ++ rcu_read_unlock(); ++ ++ kfree(lag_cb_main); ++} ++EXPORT_SYMBOL(bond_unregister_cb); ++/* QCA NSS ECM bonding support - End */ + + /* ================= api to bonding and kernel code ================== */ + +@@ -424,7 +457,6 @@ static u16 __ad_timer_to_ticks(u16 timer + return retval; + } + +- + /* ================= ad_rx_machine helper functions ================== */ + + /** +@@ -1064,7 +1096,30 @@ static void ad_mux_machine(struct port * + ad_disable_collecting_distributing(port, + update_slave_arr); + port->ntt = true; +- break; ++ ++ /* QCA NSS ECM bonding support - Start */ ++ /* Send a notificaton about change in state of this ++ * port. We only want to handle case where port moves ++ * from AD_MUX_COLLECTING_DISTRIBUTING -> ++ * AD_MUX_ATTACHED. ++ */ ++ if (bond_slave_is_up(port->slave) && ++ (last_state == AD_MUX_COLLECTING_DISTRIBUTING)) { ++ struct bond_cb *lag_cb_main; ++ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ if (lag_cb_main && ++ lag_cb_main->bond_cb_link_down) { ++ struct net_device *dev; ++ ++ dev = port->slave->dev; ++ lag_cb_main->bond_cb_link_down(dev); ++ } ++ rcu_read_unlock(); ++ } ++ ++ break; /* QCA NSS ECM bonding support - End */ + case AD_MUX_COLLECTING_DISTRIBUTING: + port->actor_oper_port_state |= LACP_STATE_COLLECTING; + port->actor_oper_port_state |= LACP_STATE_DISTRIBUTING; +@@ -1908,13 +1963,24 @@ static void ad_enable_collecting_distrib + bool *update_slave_arr) + { + if (port->aggregator->is_active) { +- slave_dbg(port->slave->bond->dev, port->slave->dev, ++ struct bond_cb *lag_cb_main; /* QCA NSS ECM bonding support */ ++ slave_dbg(port->slave->bond->dev, port->slave->dev, + "Enabling port %d (LAG %d)\n", + port->actor_port_number, + port->aggregator->aggregator_identifier); + __enable_port(port); + /* Slave array needs update */ + *update_slave_arr = true; ++ ++ /* QCA NSS ECM bonding support - Start */ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ ++ if (lag_cb_main && lag_cb_main->bond_cb_link_up) ++ lag_cb_main->bond_cb_link_up(port->slave->dev); ++ ++ rcu_read_unlock(); ++ /* QCA NSS ECM bonding support - End */ + } + } + +@@ -2674,6 +2740,104 @@ int bond_3ad_get_active_agg_info(struct + return ret; + } + ++/* QCA NSS ECM bonding support - Start */ ++/* bond_3ad_get_tx_dev - Calculate egress interface for a given packet, ++ * for a LAG that is configured in 802.3AD mode ++ * @skb: pointer to skb to be egressed ++ * @src_mac: pointer to source L2 address ++ * @dst_mac: pointer to destination L2 address ++ * @src: pointer to source L3 address ++ * @dst: pointer to destination L3 address ++ * @protocol: L3 protocol id from L2 header ++ * @bond_dev: pointer to bond master device ++ * ++ * If @skb is NULL, bond_xmit_hash is used to calculate hash using L2/L3 ++ * addresses. ++ * ++ * Returns: Either valid slave device, or NULL otherwise ++ */ ++struct net_device *bond_3ad_get_tx_dev(struct sk_buff *skb, u8 *src_mac, ++ u8 *dst_mac, void *src, ++ void *dst, u16 protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr) ++{ ++ struct bonding *bond = netdev_priv(bond_dev); ++ struct aggregator *agg; ++ struct ad_info ad_info; ++ struct list_head *iter; ++ struct slave *slave; ++ struct slave *first_ok_slave = NULL; ++ u32 hash = 0; ++ int slaves_in_agg; ++ int slave_agg_no = 0; ++ int agg_id; ++ ++ if (__bond_3ad_get_active_agg_info(bond, &ad_info)) { ++ pr_debug("%s: Error: __bond_3ad_get_active_agg_info failed\n", ++ bond_dev->name); ++ return NULL; ++ } ++ ++ slaves_in_agg = ad_info.ports; ++ agg_id = ad_info.aggregator_id; ++ ++ if (slaves_in_agg == 0) { ++ pr_debug("%s: Error: active aggregator is empty\n", ++ bond_dev->name); ++ return NULL; ++ } ++ ++ if (skb) { ++ hash = bond_xmit_hash(bond, skb); ++ slave_agg_no = hash % slaves_in_agg; ++ } else { ++ if (bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER23 && ++ bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER2 && ++ bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER34) { ++ pr_debug("%s: Error: Unsupported hash policy for 802.3AD fast path\n", ++ bond_dev->name); ++ return NULL; ++ } ++ ++ hash = bond_xmit_hash_without_skb(src_mac, dst_mac, ++ src, dst, protocol, ++ bond_dev, layer4hdr); ++ slave_agg_no = hash % slaves_in_agg; ++ } ++ ++ bond_for_each_slave_rcu(bond, slave, iter) { ++ agg = SLAVE_AD_INFO(slave)->port.aggregator; ++ if (!agg || agg->aggregator_identifier != agg_id) ++ continue; ++ ++ if (slave_agg_no >= 0) { ++ if (!first_ok_slave && bond_slave_can_tx(slave)) ++ first_ok_slave = slave; ++ slave_agg_no--; ++ continue; ++ } ++ ++ if (bond_slave_can_tx(slave)) ++ return slave->dev; ++ } ++ ++ if (slave_agg_no >= 0) { ++ pr_err("%s: Error: Couldn't find a slave to tx on for aggregator ID %d\n", ++ bond_dev->name, agg_id); ++ return NULL; ++ } ++ ++ /* we couldn't find any suitable slave after the agg_no, so use the ++ * first suitable found, if found. ++ */ ++ if (first_ok_slave) ++ return first_ok_slave->dev; ++ ++ return NULL; ++} ++/* QCA NSS ECM bonding support - End */ ++ + int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond, + struct slave *slave) + { +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1186,6 +1186,23 @@ void bond_change_active_slave(struct bon + if (BOND_MODE(bond) == BOND_MODE_8023AD) + bond_3ad_handle_link_change(new_active, BOND_LINK_UP); + ++ /* QCA NSS ECM bonding support - Start */ ++ if (bond->params.mode == BOND_MODE_XOR) { ++ struct bond_cb *lag_cb_main; ++ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ if (lag_cb_main && ++ lag_cb_main->bond_cb_link_up) { ++ struct net_device *dev; ++ ++ dev = new_active->dev; ++ lag_cb_main->bond_cb_link_up(dev); ++ } ++ rcu_read_unlock(); ++ } ++ /* QCA NSS ECM bonding support - End */ ++ + if (bond_is_lb(bond)) + bond_alb_handle_link_change(bond, new_active, BOND_LINK_UP); + } else { +@@ -1798,7 +1815,8 @@ int bond_enslave(struct net_device *bond + const struct net_device_ops *slave_ops = slave_dev->netdev_ops; + struct slave *new_slave = NULL, *prev_slave; + struct sockaddr_storage ss; +- int link_reporting; ++ struct bond_cb *lag_cb_main; /* QCA NSS ECM bonding support */ ++ int link_reporting; + int res = 0, i; + + if (slave_dev->flags & IFF_MASTER && +@@ -2241,6 +2259,15 @@ int bond_enslave(struct net_device *bond + bond_is_active_slave(new_slave) ? "an active" : "a backup", + new_slave->link != BOND_LINK_DOWN ? "an up" : "a down"); + ++ /* QCA NSS ECM bonding support - Start */ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ if (lag_cb_main && lag_cb_main->bond_cb_enslave) ++ lag_cb_main->bond_cb_enslave(slave_dev); ++ ++ rcu_read_unlock(); ++ /* QCA NSS ECM bonding support - End */ ++ + /* enslave is successful */ + bond_queue_slave_event(new_slave); + return 0; +@@ -2306,6 +2333,15 @@ err_undo_flags: + } + } + ++ /* QCA NSS ECM bonding support - Start */ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ if (lag_cb_main && lag_cb_main->bond_cb_enslave) ++ lag_cb_main->bond_cb_enslave(slave_dev); ++ ++ rcu_read_unlock(); ++ /* QCA NSS ECM bonding support - End */ ++ + return res; + } + +@@ -2328,7 +2364,8 @@ static int __bond_release_one(struct net + struct slave *slave, *oldcurrent; + struct sockaddr_storage ss; + int old_flags = bond_dev->flags; +- netdev_features_t old_features = bond_dev->features; ++ struct bond_cb *lag_cb_main; /* QCA NSS ECM bonding support */ ++ netdev_features_t old_features = bond_dev->features; + + /* slave is not a slave or master is not master of this slave */ + if (!(slave_dev->flags & IFF_SLAVE) || +@@ -2349,6 +2386,15 @@ static int __bond_release_one(struct net + + bond_set_slave_inactive_flags(slave, BOND_SLAVE_NOTIFY_NOW); + ++ /* QCA NSS ECM bonding support - Start */ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ if (lag_cb_main && lag_cb_main->bond_cb_release) ++ lag_cb_main->bond_cb_release(slave_dev); ++ ++ rcu_read_unlock(); ++ /* QCA NSS ECM bonding support - End */ ++ + bond_sysfs_slave_del(slave); + + /* recompute stats just before removing the slave */ +@@ -2668,6 +2714,8 @@ static void bond_miimon_commit(struct bo + struct slave *slave, *primary, *active; + bool do_failover = false; + struct list_head *iter; ++ struct net_device *slave_dev = NULL; /* QCA NSS ECM bonding support */ ++ struct bond_cb *lag_cb_main; /* QCA NSS ECM bonding support */ + + ASSERT_RTNL(); + +@@ -2707,6 +2755,12 @@ static void bond_miimon_commit(struct bo + bond_set_active_slave(slave); + } + ++ /* QCA NSS ECM bonding support - Start */ ++ if ((bond->params.mode == BOND_MODE_XOR) && ++ (!slave_dev)) ++ slave_dev = slave->dev; ++ /* QCA NSS ECM bonding support - End */ ++ + slave_info(bond->dev, slave->dev, "link status definitely up, %u Mbps %s duplex\n", + slave->speed == SPEED_UNKNOWN ? 0 : slave->speed, + slave->duplex ? "full" : "half"); +@@ -2755,6 +2809,16 @@ static void bond_miimon_commit(struct bo + unblock_netpoll_tx(); + } + ++ /* QCA NSS ECM bonding support - Start */ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ ++ if (slave_dev && lag_cb_main && lag_cb_main->bond_cb_link_up) ++ lag_cb_main->bond_cb_link_up(slave_dev); ++ ++ rcu_read_unlock(); ++ /* QCA NSS ECM bonding support - End */ ++ + bond_set_carrier(bond); + } + +@@ -4002,8 +4066,219 @@ static inline u32 bond_eth_hash(struct s + return 0; + + ep = (struct ethhdr *)(data + mhoff); +- return ep->h_dest[5] ^ ep->h_source[5] ^ be16_to_cpu(ep->h_proto); ++ return ep->h_dest[5] ^ ep->h_source[5]; /* QCA NSS ECM bonding support */ ++} ++ ++/* QCA NSS ECM bonding support - Start */ ++/* Extract the appropriate headers based on bond's xmit policy */ ++static bool bond_flow_dissect_without_skb(struct bonding *bond, ++ u8 *src_mac, u8 *dst_mac, ++ void *psrc, void *pdst, ++ u16 protocol, __be16 *layer4hdr, ++ struct flow_keys *fk) ++{ ++ u32 *src = NULL; ++ u32 *dst = NULL; ++ ++ fk->ports.ports = 0; ++ src = (uint32_t *)psrc; ++ dst = (uint32_t *)pdst; ++ ++ if (protocol == htons(ETH_P_IP)) { ++ /* V4 addresses and address type*/ ++ fk->addrs.v4addrs.src = src[0]; ++ fk->addrs.v4addrs.dst = dst[0]; ++ fk->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS; ++ } else if (protocol == htons(ETH_P_IPV6)) { ++ /* V6 addresses and address type*/ ++ memcpy(&fk->addrs.v6addrs.src, src, sizeof(struct in6_addr)); ++ memcpy(&fk->addrs.v6addrs.dst, dst, sizeof(struct in6_addr)); ++ fk->control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS; ++ } else { ++ return false; ++ } ++ if ((bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34) && ++ (layer4hdr)) ++ fk->ports.ports = *layer4hdr; ++ ++ return true; ++} ++ ++/* bond_xmit_hash_without_skb - Applies load balancing algorithm for a packet, ++ * to calculate hash for a given set of L2/L3 addresses. Does not ++ * calculate egress interface. ++ */ ++uint32_t bond_xmit_hash_without_skb(u8 *src_mac, u8 *dst_mac, ++ void *psrc, void *pdst, u16 protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr) ++{ ++ struct bonding *bond = netdev_priv(bond_dev); ++ struct flow_keys flow; ++ u32 hash = 0; ++ ++ if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER2 || ++ !bond_flow_dissect_without_skb(bond, src_mac, dst_mac, psrc, ++ pdst, protocol, layer4hdr, &flow)) ++ return (dst_mac[5] ^ src_mac[5]); ++ ++ if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER23) ++ hash = dst_mac[5] ^ src_mac[5]; ++ else if (layer4hdr) ++ hash = (__force u32)flow.ports.ports; ++ ++ hash ^= (__force u32)flow_get_u32_dst(&flow) ^ ++ (__force u32)flow_get_u32_src(&flow); ++ hash ^= (hash >> 16); ++ hash ^= (hash >> 8); ++ ++ return hash; ++} ++ ++/* bond_xor_get_tx_dev - Calculate egress interface for a given packet for a LAG ++ * that is configured in balance-xor mode ++ * @skb: pointer to skb to be egressed ++ * @src_mac: pointer to source L2 address ++ * @dst_mac: pointer to destination L2 address ++ * @src: pointer to source L3 address in network order ++ * @dst: pointer to destination L3 address in network order ++ * @protocol: L3 protocol ++ * @bond_dev: pointer to bond master device ++ * ++ * If @skb is NULL, bond_xmit_hash_without_skb is used to calculate hash using ++ * L2/L3 addresses. ++ * ++ * Returns: Either valid slave device, or NULL otherwise ++ */ ++static struct net_device *bond_xor_get_tx_dev(struct sk_buff *skb, ++ u8 *src_mac, u8 *dst_mac, ++ void *src, void *dst, ++ u16 protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr) ++{ ++ struct bonding *bond = netdev_priv(bond_dev); ++ int slave_cnt = READ_ONCE(bond->slave_cnt); ++ int slave_id = 0, i = 0; ++ u32 hash; ++ struct list_head *iter; ++ struct slave *slave; ++ ++ if (slave_cnt == 0) { ++ pr_debug("%s: Error: No slave is attached to the interface\n", ++ bond_dev->name); ++ return NULL; ++ } ++ ++ if (skb) { ++ hash = bond_xmit_hash(bond, skb); ++ slave_id = hash % slave_cnt; ++ } else { ++ if (bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER23 && ++ bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER2 && ++ bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER34) { ++ pr_debug("%s: Error: Unsupported hash policy for balance-XOR fast path\n", ++ bond_dev->name); ++ return NULL; ++ } ++ ++ hash = bond_xmit_hash_without_skb(src_mac, dst_mac, src, ++ dst, protocol, bond_dev, ++ layer4hdr); ++ slave_id = hash % slave_cnt; ++ } ++ ++ i = slave_id; ++ ++ /* Here we start from the slave with slave_id */ ++ bond_for_each_slave_rcu(bond, slave, iter) { ++ if (--i < 0) { ++ if (bond_slave_can_tx(slave)) ++ return slave->dev; ++ } ++ } ++ ++ /* Here we start from the first slave up to slave_id */ ++ i = slave_id; ++ bond_for_each_slave_rcu(bond, slave, iter) { ++ if (--i < 0) ++ break; ++ if (bond_slave_can_tx(slave)) ++ return slave->dev; ++ } ++ ++ return NULL; ++} ++ ++/* bond_get_tx_dev - Calculate egress interface for a given packet. ++ * ++ * Supports 802.3AD and balance-xor modes ++ * ++ * @skb: pointer to skb to be egressed, if valid ++ * @src_mac: pointer to source L2 address ++ * @dst_mac: pointer to destination L2 address ++ * @src: pointer to source L3 address in network order ++ * @dst: pointer to destination L3 address in network order ++ * @protocol: L3 protocol id from L2 header ++ * @bond_dev: pointer to bond master device ++ * ++ * Returns: Either valid slave device, or NULL for un-supported LAG modes ++ */ ++struct net_device *bond_get_tx_dev(struct sk_buff *skb, uint8_t *src_mac, ++ u8 *dst_mac, void *src, ++ void *dst, u16 protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr) ++{ ++ struct bonding *bond; ++ ++ if (!bond_dev) ++ return NULL; ++ ++ if (!((bond_dev->priv_flags & IFF_BONDING) && ++ (bond_dev->flags & IFF_MASTER))) ++ return NULL; ++ ++ bond = netdev_priv(bond_dev); ++ ++ switch (bond->params.mode) { ++ case BOND_MODE_XOR: ++ return bond_xor_get_tx_dev(skb, src_mac, dst_mac, ++ src, dst, protocol, ++ bond_dev, layer4hdr); ++ case BOND_MODE_8023AD: ++ return bond_3ad_get_tx_dev(skb, src_mac, dst_mac, ++ src, dst, protocol, ++ bond_dev, layer4hdr); ++ default: ++ return NULL; ++ } + } ++EXPORT_SYMBOL(bond_get_tx_dev); ++ ++/* In bond_xmit_xor() , we determine the output device by using a pre- ++ * determined xmit_hash_policy(), If the selected device is not enabled, ++ * find the next active slave. ++ */ ++static int bond_xmit_xor(struct sk_buff *skb, struct net_device *dev) ++{ ++ struct bonding *bond = netdev_priv(dev); ++ struct net_device *outdev; ++ ++ outdev = bond_xor_get_tx_dev(skb, NULL, NULL, NULL, ++ NULL, 0, dev, NULL); ++ if (!outdev) ++ goto out; ++ ++ bond_dev_queue_xmit(bond, skb, outdev); ++ goto final; ++out: ++ /* no suitable interface, frame not sent */ ++ dev_kfree_skb(skb); ++final: ++ return NETDEV_TX_OK; ++} ++/* QCA NSS ECM bonding support - End */ + + static bool bond_flow_ip(struct sk_buff *skb, struct flow_keys *fk, const void *data, + int hlen, __be16 l2_proto, int *nhoff, int *ip_proto, bool l34) +@@ -5200,15 +5475,23 @@ static netdev_tx_t bond_3ad_xor_xmit(str + struct net_device *dev) + { + struct bonding *bond = netdev_priv(dev); +- struct bond_up_slave *slaves; +- struct slave *slave; ++ /* QCA NSS ECM bonding support - Start */ ++ struct net_device *outdev = NULL; ++ outdev = bond_3ad_get_tx_dev(skb, NULL, NULL, NULL, ++ NULL, 0, dev, NULL); + +- slaves = rcu_dereference(bond->usable_slaves); +- slave = bond_xmit_3ad_xor_slave_get(bond, skb, slaves); +- if (likely(slave)) +- return bond_dev_queue_xmit(bond, skb, slave->dev); ++ if (!outdev) ++ goto out; + +- return bond_tx_drop(dev, skb); ++ bond_dev_queue_xmit(bond, skb, outdev); ++ goto final; ++ ++out: ++ dev_kfree_skb(skb); ++ ++final: ++ return NETDEV_TX_OK; ++/* QCA NSS ECM bonding support - End */ + } + + /* in broadcast mode, we send everything to all usable interfaces. */ +@@ -5458,8 +5741,9 @@ static netdev_tx_t __bond_start_xmit(str + return bond_xmit_roundrobin(skb, dev); + case BOND_MODE_ACTIVEBACKUP: + return bond_xmit_activebackup(skb, dev); +- case BOND_MODE_8023AD: + case BOND_MODE_XOR: ++ return bond_xmit_xor(skb, dev); /* QCA NSS ECM bonding support */ ++ case BOND_MODE_8023AD: + return bond_3ad_xor_xmit(skb, dev); + case BOND_MODE_BROADCAST: + return bond_xmit_broadcast(skb, dev); +--- a/include/net/bond_3ad.h ++++ b/include/net/bond_3ad.h +@@ -303,8 +303,15 @@ int bond_3ad_lacpdu_recv(const struct sk + int bond_3ad_set_carrier(struct bonding *bond); + void bond_3ad_update_lacp_active(struct bonding *bond); + void bond_3ad_update_lacp_rate(struct bonding *bond); ++/* QCA NSS ECM bonding support */ ++struct net_device *bond_3ad_get_tx_dev(struct sk_buff *skb, uint8_t *src_mac, ++ uint8_t *dst_mac, void *src, ++ void *dst, uint16_t protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr); ++/* QCA NSS ECM bonding support */ ++ + void bond_3ad_update_ad_actor_settings(struct bonding *bond); + int bond_3ad_stats_fill(struct sk_buff *skb, struct bond_3ad_stats *stats); + size_t bond_3ad_stats_size(void); + #endif /* _NET_BOND_3AD_H */ +- +--- a/include/net/bonding.h ++++ b/include/net/bonding.h +@@ -85,6 +85,8 @@ + #define bond_for_each_slave(bond, pos, iter) \ + netdev_for_each_lower_private((bond)->dev, pos, iter) + ++extern struct bond_cb __rcu *bond_cb; /* QCA NSS ECM bonding support */ ++ + /* Caller must have rcu_read_lock */ + #define bond_for_each_slave_rcu(bond, pos, iter) \ + netdev_for_each_lower_private_rcu((bond)->dev, pos, iter) +@@ -690,6 +692,12 @@ struct bond_vlan_tag *bond_verify_device + int level); + int bond_update_slave_arr(struct bonding *bond, struct slave *skipslave); + void bond_slave_arr_work_rearm(struct bonding *bond, unsigned long delay); ++/* QCA NSS ECM bonding support - Start */ ++uint32_t bond_xmit_hash_without_skb(uint8_t *src_mac, uint8_t *dst_mac, ++ void *psrc, void *pdst, uint16_t protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr); ++/* QCA NSS ECM bonding support - End */ + void bond_work_init_all(struct bonding *bond); + + #ifdef CONFIG_PROC_FS +@@ -803,4 +811,18 @@ static inline netdev_tx_t bond_tx_drop(s + return NET_XMIT_DROP; + } + ++/* QCA NSS ECM bonding support - Start */ ++struct bond_cb { ++ void (*bond_cb_link_up)(struct net_device *slave); ++ void (*bond_cb_link_down)(struct net_device *slave); ++ void (*bond_cb_enslave)(struct net_device *slave); ++ void (*bond_cb_release)(struct net_device *slave); ++ void (*bond_cb_delete_by_slave)(struct net_device *slave); ++ void (*bond_cb_delete_by_mac)(uint8_t *mac_addr); ++}; ++ ++extern int bond_register_cb(struct bond_cb *cb); ++extern void bond_unregister_cb(void); ++/* QCA NSS ECM bonding support - End */ ++ + #endif /* _NET_BONDING_H */ diff --git a/target/linux/qualcommax/patches-6.1/0600-5-qca-nss-ecm-support-macvlan.patch b/target/linux/qualcommax/patches-6.1/0600-5-qca-nss-ecm-support-macvlan.patch new file mode 100644 index 00000000000000..9bf8464ea063b0 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0600-5-qca-nss-ecm-support-macvlan.patch @@ -0,0 +1,96 @@ +--- a/include/linux/if_macvlan.h ++++ b/include/linux/if_macvlan.h +@@ -15,6 +15,13 @@ struct macvlan_port; + #define MACVLAN_MC_FILTER_BITS 8 + #define MACVLAN_MC_FILTER_SZ (1 << MACVLAN_MC_FILTER_BITS) + ++/* QCA NSS ECM Support - Start */ ++/* ++ * Callback for updating interface statistics for macvlan flows offloaded from host CPU. ++ */ ++typedef void (*macvlan_offload_stats_update_cb_t)(struct net_device *dev, struct rtnl_link_stats64 *stats, bool update_mcast_rx_stats); ++/* QCA NSS ECM Support - End */ ++ + struct macvlan_dev { + struct net_device *dev; + struct list_head list; +@@ -35,6 +42,7 @@ struct macvlan_dev { + #ifdef CONFIG_NET_POLL_CONTROLLER + struct netpoll *netpoll; + #endif ++ macvlan_offload_stats_update_cb_t offload_stats_update; /* QCA NSS ECM support */ + }; + + static inline void macvlan_count_rx(const struct macvlan_dev *vlan, +@@ -107,4 +115,26 @@ static inline int macvlan_release_l2fw_o + macvlan->accel_priv = NULL; + return dev_uc_add(macvlan->lowerdev, dev->dev_addr); + } ++ ++/* QCA NSS ECM Support - Start */ ++#if IS_ENABLED(CONFIG_MACVLAN) ++static inline void ++macvlan_offload_stats_update(struct net_device *dev, ++ struct rtnl_link_stats64 *stats, ++ bool update_mcast_rx_stats) ++{ ++ struct macvlan_dev *macvlan = netdev_priv(dev); ++ ++ macvlan->offload_stats_update(dev, stats, update_mcast_rx_stats); ++} ++ ++static inline enum ++macvlan_mode macvlan_get_mode(struct net_device *dev) ++{ ++ struct macvlan_dev *macvlan = netdev_priv(dev); ++ ++ return macvlan->mode; ++} ++#endif ++/* QCA NSS ECM Support - End */ + #endif /* _LINUX_IF_MACVLAN_H */ +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -933,6 +933,34 @@ static void macvlan_uninit(struct net_de + macvlan_port_destroy(port->dev); + } + ++/* QCA NSS ECM Support - Start */ ++/* Update macvlan statistics processed by offload engines */ ++static void macvlan_dev_update_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *offl_stats, ++ bool update_mcast_rx_stats) ++{ ++ struct vlan_pcpu_stats *stats; ++ struct macvlan_dev *macvlan; ++ ++ /* Is this a macvlan? */ ++ if (!netif_is_macvlan(dev)) ++ return; ++ ++ macvlan = netdev_priv(dev); ++ stats = this_cpu_ptr(macvlan->pcpu_stats); ++ u64_stats_update_begin(&stats->syncp); ++ u64_stats_add(&stats->rx_packets, offl_stats->rx_packets); ++ u64_stats_add(&stats->rx_bytes, offl_stats->rx_bytes); ++ u64_stats_add(&stats->tx_packets, offl_stats->tx_packets); ++ u64_stats_add(&stats->tx_bytes, offl_stats->tx_bytes); ++ /* Update multicast statistics */ ++ if (unlikely(update_mcast_rx_stats)) { ++ u64_stats_add(&stats->rx_multicast, offl_stats->rx_packets); ++ } ++ u64_stats_update_end(&stats->syncp); ++} ++/* QCA NSS ECM Support - End */ ++ + static void macvlan_dev_get_stats64(struct net_device *dev, + struct rtnl_link_stats64 *stats) + { +@@ -1477,6 +1505,7 @@ int macvlan_common_newlink(struct net *s + vlan->dev = dev; + vlan->port = port; + vlan->set_features = MACVLAN_FEATURES; ++ vlan->offload_stats_update = macvlan_dev_update_stats; /* QCA NSS ECM Support */ + + vlan->mode = MACVLAN_MODE_VEPA; + if (data && data[IFLA_MACVLAN_MODE]) diff --git a/target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch b/target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch new file mode 100644 index 00000000000000..fbe6a368796511 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch @@ -0,0 +1,69 @@ +--- a/net/netfilter/Kconfig ++++ b/net/netfilter/Kconfig +@@ -171,6 +171,13 @@ config NF_CONNTRACK_TIMEOUT + + If unsure, say `N'. + ++config NF_CONNTRACK_DSCPREMARK_EXT ++ bool 'Connection tracking extension for dscp remark target' ++ depends on NETFILTER_ADVANCED ++ help ++ This option enables support for connection tracking extension ++ for dscp remark. ++ + config NF_CONNTRACK_TIMESTAMP + bool 'Connection tracking timestamping' + depends on NETFILTER_ADVANCED +--- a/include/net/netfilter/nf_conntrack_extend.h ++++ b/include/net/netfilter/nf_conntrack_extend.h +@@ -31,6 +31,10 @@ enum nf_ct_ext_id { + #if IS_ENABLED(CONFIG_NET_ACT_CT) + NF_CT_EXT_ACT_CT, + #endif ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ NF_CT_EXT_DSCPREMARK, /* QCA NSS ECM support */ ++#endif ++ + NF_CT_EXT_NUM, + }; + +--- a/net/netfilter/nf_conntrack_extend.c ++++ b/net/netfilter/nf_conntrack_extend.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + + #define NF_CT_EXT_PREALLOC 128u /* conntrack events are on by default */ +@@ -54,6 +55,9 @@ static const u8 nf_ct_ext_type_len[NF_CT + #if IS_ENABLED(CONFIG_NET_ACT_CT) + [NF_CT_EXT_ACT_CT] = sizeof(struct nf_conn_act_ct_ext), + #endif ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ [NF_CT_EXT_DSCPREMARK] = sizeof(struct nf_ct_dscpremark_ext), ++#endif + }; + + static __always_inline unsigned int total_extension_size(void) +@@ -86,6 +90,9 @@ static __always_inline unsigned int tota + #if IS_ENABLED(CONFIG_NET_ACT_CT) + + sizeof(struct nf_conn_act_ct_ext) + #endif ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ + sizeof(struct nf_ct_dscpremark_ext) ++#endif + ; + } + +--- a/net/netfilter/Makefile ++++ b/net/netfilter/Makefile +@@ -14,6 +14,7 @@ nf_conntrack-$(CONFIG_NF_CONNTRACK_LABEL + nf_conntrack-$(CONFIG_NF_CT_PROTO_DCCP) += nf_conntrack_proto_dccp.o + nf_conntrack-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o + nf_conntrack-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o ++nf_conntrack-$(CONFIG_NF_CONNTRACK_DSCPREMARK_EXT) += nf_conntrack_dscpremark_ext.o + ifeq ($(CONFIG_NF_CONNTRACK),m) + nf_conntrack-$(CONFIG_DEBUG_INFO_BTF_MODULES) += nf_conntrack_bpf.o + else ifeq ($(CONFIG_NF_CONNTRACK),y) From 7392a37793c95a2e9c783fa0f00a32fe2fc39904 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 02:20:08 +0300 Subject: [PATCH 028/225] qualcommax: net: fix ECM BRK panic in nf_conntrack_ecache It seems WARN_ON_ONCE will generate a BRK instruction on arm64 since kernel 5.15, which leads to a kernel panic when loading the NSS ECM module. Reference: https: //github.com/bitthief/openwrt/issues/9 Signed-off-by: bitthief --- ...conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch diff --git a/target/linux/qualcommax/patches-6.1/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch b/target/linux/qualcommax/patches-6.1/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch new file mode 100644 index 00000000000000..4b9ee21f2f8545 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch @@ -0,0 +1,10 @@ +--- a/net/netfilter/nf_conntrack_ecache.c ++++ b/net/netfilter/nf_conntrack_ecache.c +@@ -266,7 +266,6 @@ void nf_conntrack_register_notifier(stru + mutex_lock(&nf_ct_ecache_mutex); + notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb, + lockdep_is_held(&nf_ct_ecache_mutex)); +- WARN_ON_ONCE(notify); + rcu_assign_pointer(net->ct.nf_conntrack_event_cb, new); + mutex_unlock(&nf_ct_ecache_mutex); + } From 8d6daf493cd9d7914f8998c51901b13e5585344e Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 02:21:02 +0300 Subject: [PATCH 029/225] qualcommax: net: QCA NSS bridge-mgr support Signed-off-by: bitthief --- .../0601-qca-add-nss-bridge-mgr-support.patch | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/0601-qca-add-nss-bridge-mgr-support.patch diff --git a/target/linux/qualcommax/patches-6.1/0601-qca-add-nss-bridge-mgr-support.patch b/target/linux/qualcommax/patches-6.1/0601-qca-add-nss-bridge-mgr-support.patch new file mode 100644 index 00000000000000..fbc76edef3cbf0 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0601-qca-add-nss-bridge-mgr-support.patch @@ -0,0 +1,94 @@ +From 3c17a0e1112be70071e98d5208da5b55dcec20a6 Mon Sep 17 00:00:00 2001 +From: Simon Casey +Date: Wed, 2 Feb 2022 19:37:29 +0100 +Subject: [PATCH] Update 607-qca-add-add-nss-bridge-mgr-support.patch for kernel 5.15 + +--- + include/linux/if_bridge.h | 4 ++++ + net/bridge/br_fdb.c | 25 +++++++++++++++++++++---- + 2 files changed, 25 insertions(+), 4 deletions(-) + +--- a/include/linux/if_bridge.h ++++ b/include/linux/if_bridge.h +@@ -252,4 +252,8 @@ typedef struct net_bridge_port *br_get_d + extern br_get_dst_hook_t __rcu *br_get_dst_hook; + /* QCA NSS ECM support - End */ + ++/* QCA NSS bridge-mgr support - Start */ ++extern struct net_device *br_fdb_bridge_dev_get_and_hold(struct net_bridge *br); ++/* QCA NSS bridge-mgr support - End */ ++ + #endif +--- a/net/bridge/br_fdb.c ++++ b/net/bridge/br_fdb.c +@@ -62,6 +62,15 @@ void br_fdb_update_unregister_notify(str + EXPORT_SYMBOL_GPL(br_fdb_update_unregister_notify); + /* QCA NSS ECM support - End */ + ++/* QCA NSS bridge-mgr support - Start */ ++struct net_device *br_fdb_bridge_dev_get_and_hold(struct net_bridge *br) ++{ ++ dev_hold(br->dev); ++ return br->dev; ++} ++EXPORT_SYMBOL_GPL(br_fdb_bridge_dev_get_and_hold); ++/* QCA NSS bridge-mgr support - End */ ++ + int __init br_fdb_init(void) + { + br_fdb_cache = kmem_cache_create("bridge_fdb_cache", +@@ -568,7 +577,7 @@ void br_fdb_cleanup(struct work_struct * + unsigned long delay = hold_time(br); + unsigned long work_delay = delay; + unsigned long now = jiffies; +- u8 mac_addr[6]; /* QCA NSS ECM support */ ++ struct br_fdb_event fdb_event; /* QCA NSS bridge-mgr support */ + + /* this part is tricky, in order to avoid blocking learning and + * consequently forwarding, we rely on rcu to delete objects with +@@ -596,12 +605,13 @@ void br_fdb_cleanup(struct work_struct * + } else { + spin_lock_bh(&br->hash_lock); + if (!hlist_unhashed(&f->fdb_node)) { +- ether_addr_copy(mac_addr, f->key.addr.addr); ++ memset(&fdb_event, 0, sizeof(fdb_event)); ++ ether_addr_copy(fdb_event.addr, f->key.addr.addr); + fdb_delete(br, f, true); + /* QCA NSS ECM support - Start */ + atomic_notifier_call_chain( + &br_fdb_update_notifier_list, 0, +- (void *)mac_addr); ++ (void *)&fdb_event); + /* QCA NSS ECM support - End */ + } + spin_unlock_bh(&br->hash_lock); +@@ -903,6 +913,7 @@ void br_fdb_update(struct net_bridge *br + const unsigned char *addr, u16 vid, unsigned long flags) + { + struct net_bridge_fdb_entry *fdb; ++ struct br_fdb_event fdb_event; /* QCA NSS bridge-mgr support */ + + /* some users want to always flood. */ + if (hold_time(br) == 0) +@@ -928,6 +939,12 @@ void br_fdb_update(struct net_bridge *br + if (unlikely(source != READ_ONCE(fdb->dst) && + !test_bit(BR_FDB_STICKY, &fdb->flags))) { + br_switchdev_fdb_notify(br, fdb, RTM_DELNEIGH); ++ /* QCA NSS bridge-mgr support - Start */ ++ ether_addr_copy(fdb_event.addr, addr); ++ fdb_event.br = br; ++ fdb_event.orig_dev = READ_ONCE(fdb->dst->dev); ++ fdb_event.dev = source->dev; ++ /* QCA NSS bridge-mgr support - End */ + WRITE_ONCE(fdb->dst, source); + fdb_modified = true; + /* Take over HW learned entry */ +@@ -939,7 +956,7 @@ void br_fdb_update(struct net_bridge *br + /* QCA NSS ECM support - Start */ + atomic_notifier_call_chain( + &br_fdb_update_notifier_list, +- 0, (void *)addr); ++ 0, (void *)&fdb_event); + /* QCA NSS ECM support - End */ + } + From c72ccebcddafa02890a479852dab83b084c0ea25 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 02:22:22 +0300 Subject: [PATCH 030/225] qualcommax: net: QCA NSS DRV qdisc support Signed-off-by: bitthief --- .../0602-qca-nss-drv-add-qdisc-support.patch | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/0602-qca-nss-drv-add-qdisc-support.patch diff --git a/target/linux/qualcommax/patches-6.1/0602-qca-nss-drv-add-qdisc-support.patch b/target/linux/qualcommax/patches-6.1/0602-qca-nss-drv-add-qdisc-support.patch new file mode 100644 index 00000000000000..a62fb5dd54a825 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0602-qca-nss-drv-add-qdisc-support.patch @@ -0,0 +1,44 @@ +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -765,6 +765,7 @@ typedef unsigned char *sk_buff_data_t; + * @offload_fwd_mark: Packet was L2-forwarded in hardware + * @offload_l3_fwd_mark: Packet was L3-forwarded in hardware + * @tc_skip_classify: do not classify packet. set by IFB device ++ * @tc_skip_classify_offload: do not classify packet set by offload IFB device + * @tc_at_ingress: used within tc_classify to distinguish in/egress + * @redirected: packet was redirected by packet classifier + * @from_ingress: packet was redirected from the ingress path +@@ -960,6 +961,8 @@ struct sk_buff { + #ifdef CONFIG_NET_CLS_ACT + __u8 tc_skip_classify:1; + __u8 tc_at_ingress:1; /* See TC_AT_INGRESS_MASK */ ++ __u8 tc_skip_classify_offload:1; ++ __u16 tc_verd_qca_nss; /* QCA NSS Qdisc Support */ + #endif + #ifdef CONFIG_IPV6_NDISC_NODETYPE + __u8 ndisc_nodetype:2; +--- a/include/uapi/linux/pkt_cls.h ++++ b/include/uapi/linux/pkt_cls.h +@@ -139,6 +139,7 @@ enum tca_id { + TCA_ID_MPLS, + TCA_ID_CT, + TCA_ID_GATE, ++ TCA_ID_MIRRED_NSS, /* QCA NSS Qdisc IGS Support */ + /* other actions go here */ + __TCA_ID_MAX = 255 + }; +@@ -801,4 +802,14 @@ enum { + TCF_EM_OPND_LT + }; + ++/* QCA NSS Qdisc Support - Start */ ++#define _TC_MAKE32(x) ((x)) ++#define _TC_MAKEMASK1(n) (_TC_MAKE32(1) << _TC_MAKE32(n)) ++ ++#define TC_NCLS _TC_MAKEMASK1(8) ++#define TC_NCLS_NSS _TC_MAKEMASK1(12) ++#define SET_TC_NCLS_NSS(v) ( TC_NCLS_NSS | ((v) & ~TC_NCLS_NSS)) ++#define CLR_TC_NCLS_NSS(v) ( (v) & ~TC_NCLS_NSS) ++/* QCA NSS Qdisc Support - End */ ++ + #endif From 36819420e8eddf328321309f57376169286b2f31 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 02:23:30 +0300 Subject: [PATCH 031/225] qualcommax: net: QCA NSS clients qdisc support Signed-off-by: bitthief --- ...-1-qca-nss-clients-add-qdisc-support.patch | 450 ++++++++++++++++++ 1 file changed, 450 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/0603-1-qca-nss-clients-add-qdisc-support.patch diff --git a/target/linux/qualcommax/patches-6.1/0603-1-qca-nss-clients-add-qdisc-support.patch b/target/linux/qualcommax/patches-6.1/0603-1-qca-nss-clients-add-qdisc-support.patch new file mode 100644 index 00000000000000..060edfd27f433e --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0603-1-qca-nss-clients-add-qdisc-support.patch @@ -0,0 +1,450 @@ +--- a/include/linux/timer.h ++++ b/include/linux/timer.h +@@ -17,6 +17,7 @@ struct timer_list { + unsigned long expires; + void (*function)(struct timer_list *); + u32 flags; ++ unsigned long cust_data; + + #ifdef CONFIG_LOCKDEP + struct lockdep_map lockdep_map; +--- a/drivers/net/ifb.c ++++ b/drivers/net/ifb.c +@@ -151,6 +151,31 @@ resched: + + } + ++void ifb_update_offload_stats(struct net_device *dev, struct pcpu_sw_netstats *offload_stats) ++{ ++ struct ifb_dev_private *dp; ++ struct ifb_q_private *txp; ++ ++ if (!dev || !offload_stats) { ++ return; ++ } ++ ++ if (!(dev->priv_flags_ext & IFF_EXT_IFB)) { ++ return; ++ } ++ ++ dp = netdev_priv(dev); ++ txp = dp->tx_private; ++ ++ u64_stats_update_begin(&txp->rx_stats.sync); ++ txp->rx_stats.packets += u64_stats_read(&offload_stats->rx_packets); ++ txp->rx_stats.bytes += u64_stats_read(&offload_stats->rx_bytes); ++ txp->tx_stats.packets += u64_stats_read(&offload_stats->tx_packets); ++ txp->tx_stats.bytes += u64_stats_read(&offload_stats->tx_bytes); ++ u64_stats_update_end(&txp->rx_stats.sync); ++} ++EXPORT_SYMBOL(ifb_update_offload_stats); ++ + static void ifb_stats64(struct net_device *dev, + struct rtnl_link_stats64 *stats) + { +@@ -326,6 +351,7 @@ static void ifb_setup(struct net_device + dev->flags |= IFF_NOARP; + dev->flags &= ~IFF_MULTICAST; + dev->priv_flags &= ~IFF_TX_SKB_SHARING; ++ dev->priv_flags_ext |= IFF_EXT_IFB; /* Mark the device as an IFB device. */ + netif_keep_dst(dev); + eth_hw_addr_random(dev); + dev->needs_free_netdev = true; +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -4587,6 +4587,15 @@ void dev_uc_flush(struct net_device *dev + void dev_uc_init(struct net_device *dev); + + /** ++ * ifb_update_offload_stats - Update the IFB interface stats ++ * @dev: IFB device to update the stats ++ * @offload_stats: per CPU stats structure ++ * ++ * Allows update of IFB stats when flows are offloaded to an accelerator. ++ **/ ++void ifb_update_offload_stats(struct net_device *dev, struct pcpu_sw_netstats *offload_stats); ++ ++/** + * __dev_uc_sync - Synchonize device's unicast list + * @dev: device to sync + * @sync: function to call if address should be added +@@ -5123,6 +5132,11 @@ static inline bool netif_is_failover_sla + return dev->priv_flags & IFF_FAILOVER_SLAVE; + } + ++static inline bool netif_is_ifb_dev(const struct net_device *dev) ++{ ++ return dev->priv_flags_ext & IFF_EXT_IFB; ++} ++ + /* This device needs to keep skb dst for qdisc enqueue or ndo_start_xmit() */ + static inline void netif_keep_dst(struct net_device *dev) + { +--- a/include/uapi/linux/pkt_sched.h ++++ b/include/uapi/linux/pkt_sched.h +@@ -1278,4 +1278,248 @@ enum { + + #define TCA_ETS_MAX (__TCA_ETS_MAX - 1) + ++/* QCA NSS Clients Support - Start */ ++enum { ++ TCA_NSS_ACCEL_MODE_NSS_FW, ++ TCA_NSS_ACCEL_MODE_PPE, ++ TCA_NSS_ACCEL_MODE_MAX ++}; ++ ++/* NSSFIFO section */ ++ ++enum { ++ TCA_NSSFIFO_UNSPEC, ++ TCA_NSSFIFO_PARMS, ++ __TCA_NSSFIFO_MAX ++}; ++ ++#define TCA_NSSFIFO_MAX (__TCA_NSSFIFO_MAX - 1) ++ ++struct tc_nssfifo_qopt { ++ __u32 limit; /* Queue length: bytes for bfifo, packets for pfifo */ ++ __u8 set_default; /* Sets qdisc to be the default qdisc for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSWRED section */ ++ ++enum { ++ TCA_NSSWRED_UNSPEC, ++ TCA_NSSWRED_PARMS, ++ __TCA_NSSWRED_MAX ++}; ++ ++#define TCA_NSSWRED_MAX (__TCA_NSSWRED_MAX - 1) ++#define NSSWRED_CLASS_MAX 6 ++struct tc_red_alg_parameter { ++ __u32 min; /* qlen_avg < min: pkts are all enqueued */ ++ __u32 max; /* qlen_avg > max: pkts are all dropped */ ++ __u32 probability;/* Drop probability at qlen_avg = max */ ++ __u32 exp_weight_factor;/* exp_weight_factor for calculate qlen_avg */ ++}; ++ ++struct tc_nsswred_traffic_class { ++ __u32 limit; /* Queue length */ ++ __u32 weight_mode_value; /* Weight mode value */ ++ struct tc_red_alg_parameter rap;/* Parameters for RED alg */ ++}; ++ ++/* ++ * Weight modes for WRED ++ */ ++enum tc_nsswred_weight_modes { ++ TC_NSSWRED_WEIGHT_MODE_DSCP = 0,/* Weight mode is DSCP */ ++ TC_NSSWRED_WEIGHT_MODES, /* Must be last */ ++}; ++ ++struct tc_nsswred_qopt { ++ __u32 limit; /* Queue length */ ++ enum tc_nsswred_weight_modes weight_mode; ++ /* Weight mode */ ++ __u32 traffic_classes; /* How many traffic classes: DPs */ ++ __u32 def_traffic_class; /* Default traffic if no match: def_DP */ ++ __u32 traffic_id; /* The traffic id to be configured: DP */ ++ __u32 weight_mode_value; /* Weight mode value */ ++ struct tc_red_alg_parameter rap;/* RED algorithm parameters */ ++ struct tc_nsswred_traffic_class tntc[NSSWRED_CLASS_MAX]; ++ /* Traffic settings for dumpping */ ++ __u8 ecn; /* Setting ECN bit or dropping */ ++ __u8 set_default; /* Sets qdisc to be the default for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSCODEL section */ ++ ++enum { ++ TCA_NSSCODEL_UNSPEC, ++ TCA_NSSCODEL_PARMS, ++ __TCA_NSSCODEL_MAX ++}; ++ ++#define TCA_NSSCODEL_MAX (__TCA_NSSCODEL_MAX - 1) ++ ++struct tc_nsscodel_qopt { ++ __u32 target; /* Acceptable queueing delay */ ++ __u32 limit; /* Max number of packets that can be held in the queue */ ++ __u32 interval; /* Monitoring interval */ ++ __u32 flows; /* Number of flow buckets */ ++ __u32 quantum; /* Weight (in bytes) used for DRR of flow buckets */ ++ __u8 ecn; /* 0 - disable ECN, 1 - enable ECN */ ++ __u8 set_default; /* Sets qdisc to be the default qdisc for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++struct tc_nsscodel_xstats { ++ __u32 peak_queue_delay; /* Peak delay experienced by a dequeued packet */ ++ __u32 peak_drop_delay; /* Peak delay experienced by a dropped packet */ ++}; ++ ++/* NSSFQ_CODEL section */ ++ ++struct tc_nssfq_codel_xstats { ++ __u32 new_flow_count; /* Total number of new flows seen */ ++ __u32 new_flows_len; /* Current number of new flows */ ++ __u32 old_flows_len; /* Current number of old flows */ ++ __u32 ecn_mark; /* Number of packets marked with ECN */ ++ __u32 drop_overlimit; /* Number of packets dropped due to overlimit */ ++ __u32 maxpacket; /* The largest packet seen so far in the queue */ ++}; ++ ++/* NSSTBL section */ ++ ++enum { ++ TCA_NSSTBL_UNSPEC, ++ TCA_NSSTBL_PARMS, ++ __TCA_NSSTBL_MAX ++}; ++ ++#define TCA_NSSTBL_MAX (__TCA_NSSTBL_MAX - 1) ++ ++struct tc_nsstbl_qopt { ++ __u32 burst; /* Maximum burst size */ ++ __u32 rate; /* Limiting rate of TBF */ ++ __u32 peakrate; /* Maximum rate at which TBF is allowed to send */ ++ __u32 mtu; /* Max size of packet, or minumim burst size */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSPRIO section */ ++ ++#define TCA_NSSPRIO_MAX_BANDS 256 ++ ++enum { ++ TCA_NSSPRIO_UNSPEC, ++ TCA_NSSPRIO_PARMS, ++ __TCA_NSSPRIO_MAX ++}; ++ ++#define TCA_NSSPRIO_MAX (__TCA_NSSPRIO_MAX - 1) ++ ++struct tc_nssprio_qopt { ++ __u32 bands; /* Number of bands */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSBF section */ ++ ++enum { ++ TCA_NSSBF_UNSPEC, ++ TCA_NSSBF_CLASS_PARMS, ++ TCA_NSSBF_QDISC_PARMS, ++ __TCA_NSSBF_MAX ++}; ++ ++#define TCA_NSSBF_MAX (__TCA_NSSBF_MAX - 1) ++ ++struct tc_nssbf_class_qopt { ++ __u32 burst; /* Maximum burst size */ ++ __u32 rate; /* Allowed bandwidth for this class */ ++ __u32 mtu; /* MTU of the associated interface */ ++ __u32 quantum; /* Quantum allocation for DRR */ ++}; ++ ++struct tc_nssbf_qopt { ++ __u16 defcls; /* Default class value */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSWRR section */ ++ ++enum { ++ TCA_NSSWRR_UNSPEC, ++ TCA_NSSWRR_CLASS_PARMS, ++ TCA_NSSWRR_QDISC_PARMS, ++ __TCA_NSSWRR_MAX ++}; ++ ++#define TCA_NSSWRR_MAX (__TCA_NSSWRR_MAX - 1) ++ ++struct tc_nsswrr_class_qopt { ++ __u32 quantum; /* Weight associated to this class */ ++}; ++ ++struct tc_nsswrr_qopt { ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSWFQ section */ ++ ++enum { ++ TCA_NSSWFQ_UNSPEC, ++ TCA_NSSWFQ_CLASS_PARMS, ++ TCA_NSSWFQ_QDISC_PARMS, ++ __TCA_NSSWFQ_MAX ++}; ++ ++#define TCA_NSSWFQ_MAX (__TCA_NSSWFQ_MAX - 1) ++ ++struct tc_nsswfq_class_qopt { ++ __u32 quantum; /* Weight associated to this class */ ++}; ++ ++struct tc_nsswfq_qopt { ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSHTB section */ ++ ++enum { ++ TCA_NSSHTB_UNSPEC, ++ TCA_NSSHTB_CLASS_PARMS, ++ TCA_NSSHTB_QDISC_PARMS, ++ __TCA_NSSHTB_MAX ++}; ++ ++#define TCA_NSSHTB_MAX (__TCA_NSSHTB_MAX - 1) ++ ++struct tc_nsshtb_class_qopt { ++ __u32 burst; /* Allowed burst size */ ++ __u32 rate; /* Allowed bandwidth for this class */ ++ __u32 cburst; /* Maximum burst size */ ++ __u32 crate; /* Maximum bandwidth for this class */ ++ __u32 quantum; /* Quantum allocation for DRR */ ++ __u32 priority; /* Priority value associated with this class */ ++ __u32 overhead; /* Overhead in bytes per packet */ ++}; ++ ++struct tc_nsshtb_qopt { ++ __u32 r2q; /* Rate to quantum ratio */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSBLACKHOLE section */ ++ ++enum { ++ TCA_NSSBLACKHOLE_UNSPEC, ++ TCA_NSSBLACKHOLE_PARMS, ++ __TCA_NSSBLACKHOLE_MAX ++}; ++ ++#define TCA_NSSBLACKHOLE_MAX (__TCA_NSSBLACKHOLE_MAX - 1) ++ ++struct tc_nssblackhole_qopt { ++ __u8 set_default; /* Sets qdisc to be the default qdisc for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++/* QCA NSS Clients Support - End */ + #endif +--- a/net/sched/sch_api.c ++++ b/net/sched/sch_api.c +@@ -313,6 +313,7 @@ struct Qdisc *qdisc_lookup(struct net_de + out: + return q; + } ++EXPORT_SYMBOL(qdisc_lookup); + + struct Qdisc *qdisc_lookup_rcu(struct net_device *dev, u32 handle) + { +@@ -2322,4 +2323,26 @@ static int __init pktsched_init(void) + return 0; + } + ++/* QCA NSS Qdisc Support - Start */ ++bool tcf_destroy(struct tcf_proto *tp, bool force) ++{ ++ tp->ops->destroy(tp, force, NULL); ++ module_put(tp->ops->owner); ++ kfree_rcu(tp, rcu); ++ ++ return true; ++} ++ ++void tcf_destroy_chain(struct tcf_proto __rcu **fl) ++{ ++ struct tcf_proto *tp; ++ ++ while ((tp = rtnl_dereference(*fl)) != NULL) { ++ RCU_INIT_POINTER(*fl, tp->next); ++ tcf_destroy(tp, true); ++ } ++} ++EXPORT_SYMBOL(tcf_destroy_chain); ++/* QCA NSS Qdisc Support - End */ ++ + subsys_initcall(pktsched_init); +--- a/net/sched/sch_generic.c ++++ b/net/sched/sch_generic.c +@@ -1046,7 +1046,7 @@ static void qdisc_free_cb(struct rcu_hea + qdisc_free(q); + } + +-static void qdisc_destroy(struct Qdisc *qdisc) ++void qdisc_destroy(struct Qdisc *qdisc) + { + const struct Qdisc_ops *ops = qdisc->ops; + +@@ -1069,6 +1069,7 @@ static void qdisc_destroy(struct Qdisc * + + call_rcu(&qdisc->rcu, qdisc_free_cb); + } ++EXPORT_SYMBOL(qdisc_destroy); + + void qdisc_put(struct Qdisc *qdisc) + { +--- a/include/net/sch_generic.h ++++ b/include/net/sch_generic.h +@@ -94,6 +94,7 @@ struct Qdisc { + #define TCQ_F_INVISIBLE 0x80 /* invisible by default in dump */ + #define TCQ_F_NOLOCK 0x100 /* qdisc does not require locking */ + #define TCQ_F_OFFLOADED 0x200 /* qdisc is offloaded to HW */ ++#define TCQ_F_NSS 0x1000 /* NSS qdisc flag. */ + u32 limit; + const struct Qdisc_ops *ops; + struct qdisc_size_table __rcu *stab; +@@ -711,6 +712,40 @@ static inline bool skb_skip_tc_classify( + return false; + } + ++/* ++ * Set skb classify bit field. ++ */ ++static inline void skb_set_tc_classify_offload(struct sk_buff *skb) ++{ ++#ifdef CONFIG_NET_CLS_ACT ++ skb->tc_skip_classify_offload = 1; ++#endif ++} ++ ++/* ++ * Clear skb classify bit field. ++ */ ++static inline void skb_clear_tc_classify_offload(struct sk_buff *skb) ++{ ++#ifdef CONFIG_NET_CLS_ACT ++ skb->tc_skip_classify_offload = 0; ++#endif ++} ++ ++/* ++ * Skip skb processing if sent from ifb dev. ++ */ ++static inline bool skb_skip_tc_classify_offload(struct sk_buff *skb) ++{ ++#ifdef CONFIG_NET_CLS_ACT ++ if (skb->tc_skip_classify_offload) { ++ skb_clear_tc_classify_offload(skb); ++ return true; ++ } ++#endif ++ return false; ++} ++ + /* Reset all TX qdiscs greater than index of a device. */ + static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i) + { +@@ -1295,4 +1330,9 @@ static inline void qdisc_synchronize(con + msleep(1); + } + ++/* QCA NSS Qdisc Support - Start */ ++void qdisc_destroy(struct Qdisc *qdisc); ++void tcf_destroy_chain(struct tcf_proto __rcu **fl); ++/* QCA NSS Qdisc Support - End */ ++ + #endif From 1059b1b1d5625698991737729aeac09bd2b1fb9b Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 02:23:39 +0300 Subject: [PATCH 032/225] qualcommax: net: QCA NSS clients L2TP support Signed-off-by: bitthief --- ...3-2-qca-nss-clients-add-l2tp-support.patch | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/0603-2-qca-nss-clients-add-l2tp-support.patch diff --git a/target/linux/qualcommax/patches-6.1/0603-2-qca-nss-clients-add-l2tp-support.patch b/target/linux/qualcommax/patches-6.1/0603-2-qca-nss-clients-add-l2tp-support.patch new file mode 100644 index 00000000000000..7fa9184df25155 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0603-2-qca-nss-clients-add-l2tp-support.patch @@ -0,0 +1,46 @@ +--- a/net/l2tp/l2tp_core.c ++++ b/net/l2tp/l2tp_core.c +@@ -398,6 +398,31 @@ err_tlock: + } + EXPORT_SYMBOL_GPL(l2tp_session_register); + ++void l2tp_stats_update(struct l2tp_tunnel *tunnel, ++ struct l2tp_session *session, ++ struct l2tp_stats *stats) ++{ ++ atomic_long_add(atomic_long_read(&stats->rx_packets), ++ &tunnel->stats.rx_packets); ++ atomic_long_add(atomic_long_read(&stats->rx_bytes), ++ &tunnel->stats.rx_bytes); ++ atomic_long_add(atomic_long_read(&stats->tx_packets), ++ &tunnel->stats.tx_packets); ++ atomic_long_add(atomic_long_read(&stats->tx_bytes), ++ &tunnel->stats.tx_bytes); ++ ++ atomic_long_add(atomic_long_read(&stats->rx_packets), ++ &session->stats.rx_packets); ++ atomic_long_add(atomic_long_read(&stats->rx_bytes), ++ &session->stats.rx_bytes); ++ atomic_long_add(atomic_long_read(&stats->tx_packets), ++ &session->stats.tx_packets); ++ atomic_long_add(atomic_long_read(&stats->tx_bytes), ++ &session->stats.tx_bytes); ++} ++EXPORT_SYMBOL_GPL(l2tp_stats_update); ++ ++ + /***************************************************************************** + * Receive data handling + *****************************************************************************/ +--- a/net/l2tp/l2tp_core.h ++++ b/net/l2tp/l2tp_core.h +@@ -232,6 +232,9 @@ struct l2tp_session *l2tp_session_get_nt + struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net, + const char *ifname); + ++void l2tp_stats_update(struct l2tp_tunnel *tunnel, struct l2tp_session *session, ++ struct l2tp_stats *stats); ++ + /* Tunnel and session lifetime management. + * Creation of a new instance is a two-step process: create, then register. + * Destruction is triggered using the *_delete functions, and completes asynchronously. From 7038f24e1a03605200bbd685ad41b1e8d08e057f Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 02:23:53 +0300 Subject: [PATCH 033/225] qualcommax: net: QCA NSS clients PPTP support Signed-off-by: bitthief --- ...3-3-qca-nss-clients-add-PPTP-support.patch | 488 ++++++++++++++++++ 1 file changed, 488 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/0603-3-qca-nss-clients-add-PPTP-support.patch diff --git a/target/linux/qualcommax/patches-6.1/0603-3-qca-nss-clients-add-PPTP-support.patch b/target/linux/qualcommax/patches-6.1/0603-3-qca-nss-clients-add-PPTP-support.patch new file mode 100644 index 00000000000000..75e8323045ac7e --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0603-3-qca-nss-clients-add-PPTP-support.patch @@ -0,0 +1,488 @@ +--- a/include/linux/if_pppox.h ++++ b/include/linux/if_pppox.h +@@ -36,6 +36,7 @@ struct pptp_opt { + u32 ack_sent, ack_recv; + u32 seq_sent, seq_recv; + int ppp_flags; ++ bool pptp_offload_mode; + }; + #include + +@@ -100,8 +101,40 @@ struct pppoe_channel_ops { + int (*get_addressing)(struct ppp_channel *, struct pppoe_opt *); + }; + ++/* PPTP client callback */ ++typedef int (*pptp_gre_seq_offload_callback_t)(struct sk_buff *skb, ++ struct net_device *pptp_dev); ++ + /* Return PPPoE channel specific addressing information */ + extern int pppoe_channel_addressing_get(struct ppp_channel *chan, + struct pppoe_opt *addressing); + ++/* Lookup PPTP session info and return PPTP session using sip, dip and local call id */ ++extern int pptp_session_find_by_src_callid(struct pptp_opt *opt, __be16 src_call_id, ++ __be32 daddr, __be32 saddr); ++ ++/* Lookup PPTP session info and return PPTP session using dip and peer call id */ ++extern int pptp_session_find(struct pptp_opt *opt, __be16 peer_call_id, ++ __be32 peer_ip_addr); ++ ++/* Return PPTP session information given the channel */ ++extern void pptp_channel_addressing_get(struct pptp_opt *opt, ++ struct ppp_channel *chan); ++ ++/* Enable the PPTP session offload flag */ ++extern int pptp_session_enable_offload_mode(__be16 peer_call_id, ++ __be32 peer_ip_addr); ++ ++/* Disable the PPTP session offload flag */ ++extern int pptp_session_disable_offload_mode(__be16 peer_call_id, ++ __be32 peer_ip_addr); ++ ++/* Register the PPTP GRE packets sequence number offload callback */ ++extern int ++pptp_register_gre_seq_offload_callback(pptp_gre_seq_offload_callback_t ++ pptp_client_cb); ++ ++/* Unregister the PPTP GRE packets sequence number offload callback */ ++extern void pptp_unregister_gre_seq_offload_callback(void); ++ + #endif /* !(__LINUX_IF_PPPOX_H) */ +--- a/drivers/net/ppp/ppp_generic.c ++++ b/drivers/net/ppp/ppp_generic.c +@@ -2973,6 +2973,20 @@ char *ppp_dev_name(struct ppp_channel *c + return name; + } + ++/* Return the PPP net device index */ ++int ppp_dev_index(struct ppp_channel *chan) ++{ ++ struct channel *pch = chan->ppp; ++ int ifindex = 0; ++ ++ if (pch) { ++ read_lock_bh(&pch->upl); ++ if (pch->ppp && pch->ppp->dev) ++ ifindex = pch->ppp->dev->ifindex; ++ read_unlock_bh(&pch->upl); ++ } ++ return ifindex; ++} + + /* + * Disconnect a channel from the generic layer. +@@ -3681,6 +3695,28 @@ void ppp_update_stats(struct net_device + ppp_recv_unlock(ppp); + } + ++/* Returns true if Compression is enabled on PPP device ++ */ ++bool ppp_is_cp_enabled(struct net_device *dev) ++{ ++ struct ppp *ppp; ++ bool flag = false; ++ ++ if (!dev) ++ return false; ++ ++ if (dev->type != ARPHRD_PPP) ++ return false; ++ ++ ppp = netdev_priv(dev); ++ ppp_lock(ppp); ++ flag = !!(ppp->xstate & SC_COMP_RUN) || !!(ppp->rstate & SC_DECOMP_RUN); ++ ppp_unlock(ppp); ++ ++ return flag; ++} ++EXPORT_SYMBOL(ppp_is_cp_enabled); ++ + /* Returns >0 if the device is a multilink PPP netdevice, 0 if not or < 0 if + * the device is not PPP. + */ +@@ -3872,6 +3908,7 @@ EXPORT_SYMBOL(ppp_unregister_channel); + EXPORT_SYMBOL(ppp_channel_index); + EXPORT_SYMBOL(ppp_unit_number); + EXPORT_SYMBOL(ppp_dev_name); ++EXPORT_SYMBOL(ppp_dev_index); + EXPORT_SYMBOL(ppp_input); + EXPORT_SYMBOL(ppp_input_error); + EXPORT_SYMBOL(ppp_output_wakeup); +--- a/include/linux/ppp_channel.h ++++ b/include/linux/ppp_channel.h +@@ -84,6 +84,9 @@ extern void ppp_unregister_channel(struc + /* Get the channel number for a channel */ + extern int ppp_channel_index(struct ppp_channel *); + ++/* Get the device index associated with a channel, or 0, if none */ ++extern int ppp_dev_index(struct ppp_channel *); ++ + /* Get the unit number associated with a channel, or -1 if none */ + extern int ppp_unit_number(struct ppp_channel *); + +@@ -116,6 +119,7 @@ extern int ppp_hold_channels(struct net_ + /* Test if ppp xmit lock is locked */ + extern bool ppp_is_xmit_locked(struct net_device *dev); + ++bool ppp_is_cp_enabled(struct net_device *dev); + /* Test if the ppp device is a multi-link ppp device */ + extern int ppp_is_multilink(struct net_device *dev); + +--- a/drivers/net/ppp/pptp.c ++++ b/drivers/net/ppp/pptp.c +@@ -49,6 +49,8 @@ static struct proto pptp_sk_proto __read + static const struct ppp_channel_ops pptp_chan_ops; + static const struct proto_ops pptp_ops; + ++static pptp_gre_seq_offload_callback_t __rcu pptp_gre_offload_xmit_cb; ++ + static struct pppox_sock *lookup_chan(u16 call_id, __be32 s_addr) + { + struct pppox_sock *sock; +@@ -90,6 +92,79 @@ static int lookup_chan_dst(u16 call_id, + return i < MAX_CALLID; + } + ++/* Search a pptp session based on local call id, local and remote ip address */ ++static int lookup_session_src(struct pptp_opt *opt, u16 call_id, __be32 daddr, __be32 saddr) ++{ ++ struct pppox_sock *sock; ++ int i = 1; ++ ++ rcu_read_lock(); ++ for_each_set_bit_from(i, callid_bitmap, MAX_CALLID) { ++ sock = rcu_dereference(callid_sock[i]); ++ if (!sock) ++ continue; ++ ++ if (sock->proto.pptp.src_addr.call_id == call_id && ++ sock->proto.pptp.dst_addr.sin_addr.s_addr == daddr && ++ sock->proto.pptp.src_addr.sin_addr.s_addr == saddr) { ++ sock_hold(sk_pppox(sock)); ++ memcpy(opt, &sock->proto.pptp, sizeof(struct pptp_opt)); ++ sock_put(sk_pppox(sock)); ++ rcu_read_unlock(); ++ return 0; ++ } ++ } ++ rcu_read_unlock(); ++ return -EINVAL; ++} ++ ++/* Search a pptp session based on peer call id and peer ip address */ ++static int lookup_session_dst(struct pptp_opt *opt, u16 call_id, __be32 d_addr) ++{ ++ struct pppox_sock *sock; ++ int i = 1; ++ ++ rcu_read_lock(); ++ for_each_set_bit_from(i, callid_bitmap, MAX_CALLID) { ++ sock = rcu_dereference(callid_sock[i]); ++ if (!sock) ++ continue; ++ ++ if (sock->proto.pptp.dst_addr.call_id == call_id && ++ sock->proto.pptp.dst_addr.sin_addr.s_addr == d_addr) { ++ sock_hold(sk_pppox(sock)); ++ memcpy(opt, &sock->proto.pptp, sizeof(struct pptp_opt)); ++ sock_put(sk_pppox(sock)); ++ rcu_read_unlock(); ++ return 0; ++ } ++ } ++ rcu_read_unlock(); ++ return -EINVAL; ++} ++ ++/* If offload mode set then this function sends all packets to ++ * offload module instead of network stack ++ */ ++static int pptp_client_skb_xmit(struct sk_buff *skb, ++ struct net_device *pptp_dev) ++{ ++ pptp_gre_seq_offload_callback_t pptp_gre_offload_cb_f; ++ int ret; ++ ++ rcu_read_lock(); ++ pptp_gre_offload_cb_f = rcu_dereference(pptp_gre_offload_xmit_cb); ++ ++ if (!pptp_gre_offload_cb_f) { ++ rcu_read_unlock(); ++ return -1; ++ } ++ ++ ret = pptp_gre_offload_cb_f(skb, pptp_dev); ++ rcu_read_unlock(); ++ return ret; ++} ++ + static int add_chan(struct pppox_sock *sock, + struct pptp_addr *sa) + { +@@ -145,8 +220,11 @@ static int pptp_xmit(struct ppp_channel + + struct rtable *rt; + struct net_device *tdev; ++ struct net_device *pptp_dev; + struct iphdr *iph; + int max_headroom; ++ int pptp_ifindex; ++ int ret; + + if (sk_pppox(po)->sk_state & PPPOX_DEAD) + goto tx_error; +@@ -155,7 +233,7 @@ static int pptp_xmit(struct ppp_channel + opt->dst_addr.sin_addr.s_addr, + opt->src_addr.sin_addr.s_addr, + 0, 0, IPPROTO_GRE, +- RT_TOS(0), sk->sk_bound_dev_if); ++ RT_TOS(0), 0); + if (IS_ERR(rt)) + goto tx_error; + +@@ -244,7 +322,32 @@ static int pptp_xmit(struct ppp_channel + ip_select_ident(net, skb, NULL); + ip_send_check(iph); + +- ip_local_out(net, skb->sk, skb); ++ pptp_ifindex = ppp_dev_index(chan); ++ ++ /* set incoming interface as the ppp interface */ ++ if (skb->skb_iif) ++ skb->skb_iif = pptp_ifindex; ++ ++ /* If the PPTP GRE seq number offload module is not enabled yet ++ * then sends all PPTP GRE packets through linux network stack ++ */ ++ if (!opt->pptp_offload_mode) { ++ ip_local_out(net, skb->sk, skb); ++ return 1; ++ } ++ ++ pptp_dev = dev_get_by_index(&init_net, pptp_ifindex); ++ if (!pptp_dev) ++ goto tx_error; ++ ++ /* If PPTP offload module is enabled then forward all PPTP GRE ++ * packets to PPTP GRE offload module ++ */ ++ ret = pptp_client_skb_xmit(skb, pptp_dev); ++ dev_put(pptp_dev); ++ if (ret < 0) ++ goto tx_error; ++ + return 1; + + tx_error: +@@ -300,6 +403,13 @@ static int pptp_rcv_core(struct sock *sk + goto drop; + + payload = skb->data + headersize; ++ ++ /* If offload is enabled, we expect the offload module ++ * to handle PPTP GRE sequence number checks ++ */ ++ if (opt->pptp_offload_mode) ++ goto allow_packet; ++ + /* check for expected sequence number */ + if (seq < opt->seq_recv + 1 || WRAPPED(opt->seq_recv, seq)) { + if ((payload[0] == PPP_ALLSTATIONS) && (payload[1] == PPP_UI) && +@@ -357,6 +467,7 @@ static int pptp_rcv(struct sk_buff *skb) + if (po) { + skb_dst_drop(skb); + nf_reset_ct(skb); ++ skb->skb_iif = ppp_dev_index(&po->chan); + return sk_receive_skb(sk_pppox(po), skb, 0); + } + drop: +@@ -442,8 +553,7 @@ static int pptp_connect(struct socket *s + opt->dst_addr.sin_addr.s_addr, + opt->src_addr.sin_addr.s_addr, + 0, 0, +- IPPROTO_GRE, RT_CONN_FLAGS(sk), +- sk->sk_bound_dev_if); ++ IPPROTO_GRE, RT_CONN_FLAGS(sk), 0); + if (IS_ERR(rt)) { + error = -EHOSTUNREACH; + goto end; +@@ -464,7 +574,7 @@ static int pptp_connect(struct socket *s + + opt->dst_addr = sp->sa_addr.pptp; + sk->sk_state |= PPPOX_CONNECTED; +- ++ opt->pptp_offload_mode = false; + end: + release_sock(sk); + return error; +@@ -594,9 +704,169 @@ static int pptp_ppp_ioctl(struct ppp_cha + return err; + } + ++/* pptp_channel_addressing_get() ++ * Return PPTP channel specific addressing information. ++ */ ++void pptp_channel_addressing_get(struct pptp_opt *opt, struct ppp_channel *chan) ++{ ++ struct sock *sk; ++ struct pppox_sock *po; ++ ++ if (!opt) ++ return; ++ ++ sk = (struct sock *)chan->private; ++ if (!sk) ++ return; ++ ++ sock_hold(sk); ++ ++ /* This is very unlikely, but check the socket is connected state */ ++ if (unlikely(sock_flag(sk, SOCK_DEAD) || ++ !(sk->sk_state & PPPOX_CONNECTED))) { ++ sock_put(sk); ++ return; ++ } ++ ++ po = pppox_sk(sk); ++ memcpy(opt, &po->proto.pptp, sizeof(struct pptp_opt)); ++ sock_put(sk); ++} ++EXPORT_SYMBOL(pptp_channel_addressing_get); ++ ++/* pptp_session_find() ++ * Search and return a PPTP session info based on peer callid and IP ++ * address. The function accepts the parameters in network byte order. ++ */ ++int pptp_session_find(struct pptp_opt *opt, __be16 peer_call_id, ++ __be32 peer_ip_addr) ++{ ++ if (!opt) ++ return -EINVAL; ++ ++ return lookup_session_dst(opt, ntohs(peer_call_id), peer_ip_addr); ++} ++EXPORT_SYMBOL(pptp_session_find); ++ ++/* pptp_session_find_by_src_callid() ++ * Search and return a PPTP session info based on src callid and IP ++ * address. The function accepts the parameters in network byte order. ++ */ ++int pptp_session_find_by_src_callid(struct pptp_opt *opt, __be16 src_call_id, ++ __be32 daddr, __be32 saddr) ++{ ++ if (!opt) ++ return -EINVAL; ++ ++ return lookup_session_src(opt, ntohs(src_call_id), daddr, saddr); ++} ++EXPORT_SYMBOL(pptp_session_find_by_src_callid); ++ ++ /* Function to change the offload mode true/false for a PPTP session */ ++static int pptp_set_offload_mode(bool accel_mode, ++ __be16 peer_call_id, __be32 peer_ip_addr) ++{ ++ struct pppox_sock *sock; ++ int i = 1; ++ ++ rcu_read_lock(); ++ for_each_set_bit_from(i, callid_bitmap, MAX_CALLID) { ++ sock = rcu_dereference(callid_sock[i]); ++ if (!sock) ++ continue; ++ ++ if (sock->proto.pptp.dst_addr.call_id == peer_call_id && ++ sock->proto.pptp.dst_addr.sin_addr.s_addr == peer_ip_addr) { ++ sock_hold(sk_pppox(sock)); ++ sock->proto.pptp.pptp_offload_mode = accel_mode; ++ sock_put(sk_pppox(sock)); ++ rcu_read_unlock(); ++ return 0; ++ } ++ } ++ rcu_read_unlock(); ++ return -EINVAL; ++} ++ ++/* Enable the PPTP session offload flag */ ++int pptp_session_enable_offload_mode(__be16 peer_call_id, __be32 peer_ip_addr) ++{ ++ return pptp_set_offload_mode(true, peer_call_id, peer_ip_addr); ++} ++EXPORT_SYMBOL(pptp_session_enable_offload_mode); ++ ++/* Disable the PPTP session offload flag */ ++int pptp_session_disable_offload_mode(__be16 peer_call_id, __be32 peer_ip_addr) ++{ ++ return pptp_set_offload_mode(false, peer_call_id, peer_ip_addr); ++} ++EXPORT_SYMBOL(pptp_session_disable_offload_mode); ++ ++/* Register the offload callback function on behalf of the module which ++ * will own the sequence and acknowledgment number updates for all ++ * PPTP GRE packets. All PPTP GRE packets are then transmitted to this ++ * module after encapsulation in order to ensure the correct seq/ack ++ * fields are set in the packets before transmission. This is required ++ * when PPTP flows are offloaded to acceleration engines, in-order to ++ * ensure consistency in sequence and ack numbers between PPTP control ++ * (PPP LCP) and data packets ++ */ ++int pptp_register_gre_seq_offload_callback(pptp_gre_seq_offload_callback_t ++ pptp_gre_offload_cb) ++{ ++ pptp_gre_seq_offload_callback_t pptp_gre_offload_cb_f; ++ ++ rcu_read_lock(); ++ pptp_gre_offload_cb_f = rcu_dereference(pptp_gre_offload_xmit_cb); ++ ++ if (pptp_gre_offload_cb_f) { ++ rcu_read_unlock(); ++ return -1; ++ } ++ ++ rcu_assign_pointer(pptp_gre_offload_xmit_cb, pptp_gre_offload_cb); ++ rcu_read_unlock(); ++ return 0; ++} ++EXPORT_SYMBOL(pptp_register_gre_seq_offload_callback); ++ ++/* Unregister the PPTP GRE packets sequence number offload callback */ ++void pptp_unregister_gre_seq_offload_callback(void) ++{ ++ rcu_assign_pointer(pptp_gre_offload_xmit_cb, NULL); ++} ++EXPORT_SYMBOL(pptp_unregister_gre_seq_offload_callback); ++ ++/* pptp_hold_chan() */ ++static void pptp_hold_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_hold(sk); ++} ++ ++/* pptp_release_chan() */ ++static void pptp_release_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_put(sk); ++} ++ ++/* pptp_get_channel_protocol() ++ * Return the protocol type of the PPTP over PPP protocol ++ */ ++static int pptp_get_channel_protocol(struct ppp_channel *chan) ++{ ++ return PX_PROTO_PPTP; ++} ++ + static const struct ppp_channel_ops pptp_chan_ops = { + .start_xmit = pptp_xmit, + .ioctl = pptp_ppp_ioctl, ++ .get_channel_protocol = pptp_get_channel_protocol, ++ .hold = pptp_hold_chan, ++ .release = pptp_release_chan, + }; + + static struct proto pptp_sk_proto __read_mostly = { From 274ac918dac21e8f9f678159f9c3ae45684f79b8 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 02:24:03 +0300 Subject: [PATCH 034/225] qualcommax: net: QCA NSS clients iptunnel support Signed-off-by: bitthief --- ...qca-nss-clients-add-iptunnel-support.patch | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-add-iptunnel-support.patch diff --git a/target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-add-iptunnel-support.patch b/target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-add-iptunnel-support.patch new file mode 100644 index 00000000000000..81da18bd796fa8 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-add-iptunnel-support.patch @@ -0,0 +1,77 @@ +--- a/include/net/ip6_tunnel.h ++++ b/include/net/ip6_tunnel.h +@@ -36,6 +36,7 @@ struct __ip6_tnl_parm { + __u8 proto; /* tunnel protocol */ + __u8 encap_limit; /* encapsulation limit for tunnel */ + __u8 hop_limit; /* hop limit for tunnel */ ++ __u8 draft03; /* FMR using draft03 of map-e - QCA NSS Clients Support */ + bool collect_md; + __be32 flowinfo; /* traffic class and flowlabel for tunnel */ + __u32 flags; /* tunnel flags */ +--- a/include/net/ip_tunnels.h ++++ b/include/net/ip_tunnels.h +@@ -554,4 +554,9 @@ static inline void ip_tunnel_info_opts_s + + #endif /* CONFIG_INET */ + ++/* QCA NSS Clients Support - Start */ ++void ipip6_update_offload_stats(struct net_device *dev, void *ptr); ++void ip6_update_offload_stats(struct net_device *dev, void *ptr); ++/* QCA NSS Clients Support - End */ ++ + #endif /* __NET_IP_TUNNELS_H */ +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -2398,6 +2398,26 @@ nla_put_failure: + return -EMSGSIZE; + } + ++/* QCA NSS Client Support - Start */ ++/* ++ * Update offload stats ++ */ ++void ip6_update_offload_stats(struct net_device *dev, void *ptr) ++{ ++ struct pcpu_sw_netstats *tstats = per_cpu_ptr(dev->tstats, 0); ++ const struct pcpu_sw_netstats *offload_stats = ++ (struct pcpu_sw_netstats *)ptr; ++ ++ u64_stats_update_begin(&tstats->syncp); ++ u64_stats_add(&tstats->tx_packets, u64_stats_read(&offload_stats->tx_packets)); ++ u64_stats_add(&tstats->tx_bytes, u64_stats_read(&offload_stats->tx_bytes)); ++ u64_stats_add(&tstats->rx_packets, u64_stats_read(&offload_stats->rx_packets)); ++ u64_stats_add(&tstats->rx_bytes, u64_stats_read(&offload_stats->rx_bytes)); ++ u64_stats_update_end(&tstats->syncp); ++} ++EXPORT_SYMBOL(ip6_update_offload_stats); ++/* QCA NSS Client Support - End */ ++ + struct net *ip6_tnl_get_link_net(const struct net_device *dev) + { + struct ip6_tnl *tunnel = netdev_priv(dev); +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -1733,6 +1733,23 @@ nla_put_failure: + return -EMSGSIZE; + } + ++/* QCA NSS Clients Support - Start */ ++void ipip6_update_offload_stats(struct net_device *dev, void *ptr) ++{ ++ struct pcpu_sw_netstats *tstats = per_cpu_ptr(dev->tstats, 0); ++ const struct pcpu_sw_netstats *offload_stats = ++ (struct pcpu_sw_netstats *)ptr; ++ ++ u64_stats_update_begin(&tstats->syncp); ++ u64_stats_add(&tstats->tx_packets, u64_stats_read(&offload_stats->tx_packets)); ++ u64_stats_add(&tstats->tx_bytes, u64_stats_read(&offload_stats->tx_bytes)); ++ u64_stats_add(&tstats->rx_packets, u64_stats_read(&offload_stats->rx_packets)); ++ u64_stats_add(&tstats->rx_bytes, u64_stats_read(&offload_stats->rx_bytes)); ++ u64_stats_update_end(&tstats->syncp); ++} ++EXPORT_SYMBOL(ipip6_update_offload_stats); ++/* QCA NSS Clients Support - End */ ++ + static const struct nla_policy ipip6_policy[IFLA_IPTUN_MAX + 1] = { + [IFLA_IPTUN_LINK] = { .type = NLA_U32 }, + [IFLA_IPTUN_LOCAL] = { .type = NLA_U32 }, From 46b1dae4f626280b30f8545d1ded19ea7c0c45ad Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 02:24:13 +0300 Subject: [PATCH 035/225] qualcommax: net: QCA NSS clients VXLAN support Signed-off-by: bitthief --- ...-5-qca-nss-clients-add-vxlan-support.patch | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/0603-5-qca-nss-clients-add-vxlan-support.patch diff --git a/target/linux/qualcommax/patches-6.1/0603-5-qca-nss-clients-add-vxlan-support.patch b/target/linux/qualcommax/patches-6.1/0603-5-qca-nss-clients-add-vxlan-support.patch new file mode 100644 index 00000000000000..8fdea03563b841 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0603-5-qca-nss-clients-add-vxlan-support.patch @@ -0,0 +1,107 @@ +--- a/drivers/net/vxlan/vxlan_core.c ++++ b/drivers/net/vxlan/vxlan_core.c +@@ -71,6 +71,20 @@ static inline bool vxlan_collect_metadat + ip_tunnel_collect_metadata(); + } + ++ATOMIC_NOTIFIER_HEAD(vxlan_fdb_notifier_list); ++ ++void vxlan_fdb_register_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_register(&vxlan_fdb_notifier_list, nb); ++} ++EXPORT_SYMBOL(vxlan_fdb_register_notify); ++ ++void vxlan_fdb_unregister_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_unregister(&vxlan_fdb_notifier_list, nb); ++} ++EXPORT_SYMBOL(vxlan_fdb_unregister_notify); ++ + #if IS_ENABLED(CONFIG_IPV6) + static int vxlan_nla_get_addr(union vxlan_addr *ip, struct nlattr *nla) + { +@@ -307,6 +321,7 @@ static void __vxlan_fdb_notify(struct vx + { + struct net *net = dev_net(vxlan->dev); + struct sk_buff *skb; ++ struct vxlan_fdb_event vfe; + int err = -ENOBUFS; + + skb = nlmsg_new(vxlan_nlmsg_size(), GFP_ATOMIC); +@@ -322,7 +337,11 @@ static void __vxlan_fdb_notify(struct vx + } + + rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); +- return; ++ vfe.dev = vxlan->dev; ++ vfe.rdst = rd; ++ ether_addr_copy(vfe.eth_addr, fdb->eth_addr); ++ atomic_notifier_call_chain(&vxlan_fdb_notifier_list, type, (void *)&vfe); ++ return; + errout: + if (err < 0) + rtnl_set_sk_err(net, RTNLGRP_NEIGH, err); +@@ -488,6 +507,18 @@ static struct vxlan_fdb *vxlan_find_mac( + return f; + } + ++/* Find and update age of fdb entry corresponding to MAC. */ ++void vxlan_fdb_update_mac(struct vxlan_dev *vxlan, const u8 *mac, uint32_t vni) ++{ ++ u32 hash_index; ++ ++ hash_index = fdb_head_index(vxlan, mac, vni); ++ spin_lock_bh(&vxlan->hash_lock[hash_index]); ++ vxlan_find_mac(vxlan, mac, vni); ++ spin_unlock_bh(&vxlan->hash_lock[hash_index]); ++} ++EXPORT_SYMBOL(vxlan_fdb_update_mac); ++ + /* caller should hold vxlan->hash_lock */ + static struct vxlan_rdst *vxlan_fdb_find_rdst(struct vxlan_fdb *f, + union vxlan_addr *ip, __be16 port, +@@ -2607,6 +2638,9 @@ static void vxlan_xmit_one(struct sk_buf + goto out_unlock; + } + ++ /* Reset the skb_iif to Tunnels interface index */ ++ skb->skb_iif = dev->ifindex; ++ + tos = ip_tunnel_ecn_encap(tos, old_iph, skb); + ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); + err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr), +@@ -2677,7 +2711,10 @@ static void vxlan_xmit_one(struct sk_buf + if (err < 0) + goto tx_error; + +- udp_tunnel6_xmit_skb(ndst, sock6->sock->sk, skb, dev, ++ /* Reset the skb_iif to Tunnels interface index */ ++ skb->skb_iif = dev->ifindex; ++ ++ udp_tunnel6_xmit_skb(ndst, sock6->sock->sk, skb, dev, + &local_ip.sin6.sin6_addr, + &dst->sin6.sin6_addr, tos, ttl, + label, src_port, dst_port, !udp_sum); +--- a/include/net/vxlan.h ++++ b/include/net/vxlan.h +@@ -344,6 +344,19 @@ struct vxlan_dev { + VXLAN_F_COLLECT_METADATA | \ + VXLAN_F_VNIFILTER) + ++/* ++ * Application data for fdb notifier event ++ */ ++struct vxlan_fdb_event { ++ struct net_device *dev; ++ struct vxlan_rdst *rdst; ++ u8 eth_addr[ETH_ALEN]; ++}; ++ ++extern void vxlan_fdb_register_notify(struct notifier_block *nb); ++extern void vxlan_fdb_unregister_notify(struct notifier_block *nb); ++extern void vxlan_fdb_update_mac(struct vxlan_dev *vxlan, const u8 *mac, uint32_t vni); ++ + struct net_device *vxlan_dev_create(struct net *net, const char *name, + u8 name_assign_type, struct vxlan_config *conf); + From 0f3d8da9ec6b18df6606cf7dd7da5f428bd13d4b Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 02:25:00 +0300 Subject: [PATCH 036/225] qualcommax: net: QCA NSS clients L2TP offloading support Signed-off-by: bitthief --- ...-clients-add-l2tp-offloading-support.patch | 368 ++++++++++++++++++ 1 file changed, 368 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/0603-6-qca-nss-clients-add-l2tp-offloading-support.patch diff --git a/target/linux/qualcommax/patches-6.1/0603-6-qca-nss-clients-add-l2tp-offloading-support.patch b/target/linux/qualcommax/patches-6.1/0603-6-qca-nss-clients-add-l2tp-offloading-support.patch new file mode 100644 index 00000000000000..4032eb3c227134 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0603-6-qca-nss-clients-add-l2tp-offloading-support.patch @@ -0,0 +1,368 @@ +--- a/include/linux/ppp_channel.h ++++ b/include/linux/ppp_channel.h +@@ -61,6 +61,51 @@ struct ppp_channel { + }; + + #ifdef __KERNEL__ ++/* Call this to obtain the underlying protocol of the PPP channel, ++ * e.g. PX_PROTO_OE ++ */ ++extern int ppp_channel_get_protocol(struct ppp_channel *); ++ ++/* Call this to hold a channel */ ++extern bool ppp_channel_hold(struct ppp_channel *); ++ ++/* Call this to release a hold you have upon a channel */ ++extern void ppp_channel_release(struct ppp_channel *); ++ ++/* Release hold on PPP channels */ ++extern void ppp_release_channels(struct ppp_channel *channels[], ++ unsigned int chan_sz); ++ ++/* Test if ppp xmit lock is locked */ ++extern bool ppp_is_xmit_locked(struct net_device *dev); ++ ++/* Call this get protocol version */ ++extern int ppp_channel_get_proto_version(struct ppp_channel *); ++ ++/* Get the device index associated with a channel, or 0, if none */ ++extern int ppp_dev_index(struct ppp_channel *); ++ ++/* Hold PPP channels for the PPP device */ ++extern int ppp_hold_channels(struct net_device *dev, ++ struct ppp_channel *channels[], ++ unsigned int chan_sz); ++extern int __ppp_hold_channels(struct net_device *dev, ++ struct ppp_channel *channels[], ++ unsigned int chan_sz); ++ ++/* Test if the ppp device is a multi-link ppp device */ ++extern int ppp_is_multilink(struct net_device *dev); ++extern int __ppp_is_multilink(struct net_device *dev); ++ ++/* Update statistics of the PPP net_device by incrementing related ++ * statistics field value with corresponding parameter ++ */ ++extern void ppp_update_stats(struct net_device *dev, unsigned long rx_packets, ++ unsigned long rx_bytes, unsigned long tx_packets, ++ unsigned long tx_bytes, unsigned long rx_errors, ++ unsigned long tx_errors, unsigned long rx_dropped, ++ unsigned long tx_dropped); ++ + /* Called by the channel when it can send some more data. */ + extern void ppp_output_wakeup(struct ppp_channel *); + +@@ -148,5 +193,17 @@ extern void ppp_update_stats(struct net_ + * that ppp_unregister_channel returns. + */ + ++/* QCA NSS Clients Support - Start */ ++/* PPP channel connection event types */ ++#define PPP_CHANNEL_DISCONNECT 0 ++#define PPP_CHANNEL_CONNECT 1 ++ ++/* Register the PPP channel connect notifier */ ++extern void ppp_channel_connection_register_notify(struct notifier_block *nb); ++ ++/* Unregister the PPP channel connect notifier */ ++extern void ppp_channel_connection_unregister_notify(struct notifier_block *nb); ++/* QCA NSS Clients Support - End */ ++ + #endif /* __KERNEL__ */ + #endif +--- a/include/linux/if_pppol2tp.h ++++ b/include/linux/if_pppol2tp.h +@@ -12,4 +12,30 @@ + #include + #include + ++/* QCA NSS ECM support - Start */ ++/* ++ * Holds L2TP channel info ++ */ ++struct pppol2tp_common_addr { ++ int tunnel_version; /* v2 or v3 */ ++ __u32 local_tunnel_id, remote_tunnel_id; /* tunnel id */ ++ __u32 local_session_id, remote_session_id; /* session id */ ++ struct sockaddr_in local_addr, remote_addr; /* ip address and port */ ++}; ++ ++/* ++ * L2TP channel operations ++ */ ++struct pppol2tp_channel_ops { ++ struct ppp_channel_ops ops; /* ppp channel ops */ ++}; ++ ++/* ++ * exported function which calls pppol2tp channel's get addressing ++ * function ++ */ ++extern int pppol2tp_channel_addressing_get(struct ppp_channel *, ++ struct pppol2tp_common_addr *); ++/* QCA NSS ECM support - End */ ++ + #endif +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -123,9 +123,17 @@ struct pppol2tp_session { + }; + + static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb); +- +-static const struct ppp_channel_ops pppol2tp_chan_ops = { +- .start_xmit = pppol2tp_xmit, ++static int pppol2tp_get_channel_protocol(struct ppp_channel *); ++static int pppol2tp_get_channel_protocol_ver(struct ppp_channel *); ++static void pppol2tp_hold_chan(struct ppp_channel *); ++static void pppol2tp_release_chan(struct ppp_channel *); ++ ++static const struct pppol2tp_channel_ops pppol2tp_chan_ops = { ++ .ops.start_xmit = pppol2tp_xmit, ++ .ops.get_channel_protocol = pppol2tp_get_channel_protocol, ++ .ops.get_channel_protocol_ver = pppol2tp_get_channel_protocol_ver, ++ .ops.hold = pppol2tp_hold_chan, ++ .ops.release = pppol2tp_release_chan, + }; + + static const struct proto_ops pppol2tp_ops; +@@ -373,6 +381,13 @@ static int pppol2tp_xmit(struct ppp_chan + skb->data[0] = PPP_ALLSTATIONS; + skb->data[1] = PPP_UI; + ++ /* QCA NSS ECM support - start */ ++ /* set incoming interface as the ppp interface */ ++ if ((skb->protocol == htons(ETH_P_IP)) || ++ (skb->protocol == htons(ETH_P_IPV6))) ++ skb->skb_iif = ppp_dev_index(chan); ++ /* QCA NSS ECM support - End */ ++ + local_bh_disable(); + l2tp_xmit_skb(session, skb); + local_bh_enable(); +@@ -818,7 +833,7 @@ static int pppol2tp_connect(struct socke + po->chan.hdrlen = PPPOL2TP_L2TP_HDR_SIZE_NOSEQ; + + po->chan.private = sk; +- po->chan.ops = &pppol2tp_chan_ops; ++ po->chan.ops = (struct ppp_channel_ops *)&pppol2tp_chan_ops.ops; + po->chan.mtu = pppol2tp_tunnel_mtu(tunnel); + + error = ppp_register_net_channel(sock_net(sk), &po->chan); +@@ -1732,6 +1747,109 @@ static void __exit pppol2tp_exit(void) + unregister_pernet_device(&pppol2tp_net_ops); + } + ++/* QCA NSS ECM support - Start */ ++/* pppol2tp_hold_chan() */ ++static void pppol2tp_hold_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_hold(sk); ++} ++ ++/* pppol2tp_release_chan() */ ++static void pppol2tp_release_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_put(sk); ++} ++ ++/* pppol2tp_get_channel_protocol() ++ * Return the protocol type of the L2TP over PPP protocol ++ */ ++static int pppol2tp_get_channel_protocol(struct ppp_channel *chan) ++{ ++ return PX_PROTO_OL2TP; ++} ++ ++/* pppol2tp_get_channel_protocol_ver() ++ * Return the protocol version of the L2TP over PPP protocol ++ */ ++static int pppol2tp_get_channel_protocol_ver(struct ppp_channel *chan) ++{ ++ struct sock *sk; ++ struct l2tp_session *session; ++ struct l2tp_tunnel *tunnel; ++ int version = 0; ++ ++ if (chan && chan->private) ++ sk = (struct sock *)chan->private; ++ else ++ return -1; ++ ++ /* Get session and tunnel contexts from the socket */ ++ session = pppol2tp_sock_to_session(sk); ++ if (!session) ++ return -1; ++ ++ tunnel = session->tunnel; ++ if (!tunnel) { ++ sock_put(sk); ++ return -1; ++ } ++ ++ version = tunnel->version; ++ ++ sock_put(sk); ++ ++ return version; ++} ++ ++/* pppol2tp_get_addressing() */ ++static int pppol2tp_get_addressing(struct ppp_channel *chan, ++ struct pppol2tp_common_addr *addr) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ struct l2tp_session *session; ++ struct l2tp_tunnel *tunnel; ++ struct inet_sock *isk = NULL; ++ int err = -ENXIO; ++ ++ /* Get session and tunnel contexts from the socket */ ++ session = pppol2tp_sock_to_session(sk); ++ if (!session) ++ return err; ++ ++ tunnel = session->tunnel; ++ if (!tunnel) { ++ sock_put(sk); ++ return err; ++ } ++ isk = inet_sk(tunnel->sock); ++ ++ addr->local_tunnel_id = tunnel->tunnel_id; ++ addr->remote_tunnel_id = tunnel->peer_tunnel_id; ++ addr->local_session_id = session->session_id; ++ addr->remote_session_id = session->peer_session_id; ++ ++ addr->local_addr.sin_port = isk->inet_sport; ++ addr->remote_addr.sin_port = isk->inet_dport; ++ addr->local_addr.sin_addr.s_addr = isk->inet_saddr; ++ addr->remote_addr.sin_addr.s_addr = isk->inet_daddr; ++ ++ sock_put(sk); ++ return 0; ++} ++ ++/* pppol2tp_channel_addressing_get() */ ++int pppol2tp_channel_addressing_get(struct ppp_channel *chan, ++ struct pppol2tp_common_addr *addr) ++{ ++ return pppol2tp_get_addressing(chan, addr); ++} ++EXPORT_SYMBOL(pppol2tp_channel_addressing_get); ++/* QCA NSS ECM support - End */ ++ + module_init(pppol2tp_init); + module_exit(pppol2tp_exit); + +--- a/drivers/net/ppp/ppp_generic.c ++++ b/drivers/net/ppp/ppp_generic.c +@@ -3743,6 +3743,32 @@ int ppp_is_multilink(struct net_device * + } + EXPORT_SYMBOL(ppp_is_multilink); + ++/* __ppp_is_multilink() ++ * Returns >0 if the device is a multilink PPP netdevice, 0 if not or < 0 ++ * if the device is not PPP. Caller should acquire ppp_lock before calling ++ * this function ++ */ ++int __ppp_is_multilink(struct net_device *dev) ++{ ++ struct ppp *ppp; ++ unsigned int flags; ++ ++ if (!dev) ++ return -1; ++ ++ if (dev->type != ARPHRD_PPP) ++ return -1; ++ ++ ppp = netdev_priv(dev); ++ flags = ppp->flags; ++ ++ if (flags & SC_MULTILINK) ++ return 1; ++ ++ return 0; ++} ++EXPORT_SYMBOL(__ppp_is_multilink); ++ + /* ppp_channel_get_protocol() + * Call this to obtain the underlying protocol of the PPP channel, + * e.g. PX_PROTO_OE +@@ -3881,6 +3907,59 @@ int ppp_hold_channels(struct net_device + } + EXPORT_SYMBOL(ppp_hold_channels); + ++/* __ppp_hold_channels() ++ * Returns the PPP channels of the PPP device, storing each one into ++ * channels[]. ++ * ++ * channels[] has chan_sz elements. ++ * This function returns the number of channels stored, up to chan_sz. ++ * It will return < 0 if the device is not PPP. ++ * ++ * You MUST release the channels using ppp_release_channels(). ++ */ ++int __ppp_hold_channels(struct net_device *dev, struct ppp_channel *channels[], ++ unsigned int chan_sz) ++{ ++ struct ppp *ppp; ++ int c; ++ struct channel *pch; ++ ++ if (!dev) ++ return -1; ++ ++ if (dev->type != ARPHRD_PPP) ++ return -1; ++ ++ ppp = netdev_priv(dev); ++ ++ c = 0; ++ list_for_each_entry(pch, &ppp->channels, clist) { ++ struct ppp_channel *chan; ++ ++ if (!pch->chan) { ++ /* Channel is going / gone away */ ++ continue; ++ } ++ ++ if (c == chan_sz) { ++ /* No space to record channel */ ++ return c; ++ } ++ ++ /* Hold the channel, if supported */ ++ chan = pch->chan; ++ if (!chan->ops->hold) ++ continue; ++ ++ chan->ops->hold(chan); ++ ++ /* Record the channel */ ++ channels[c++] = chan; ++ } ++ return c; ++} ++EXPORT_SYMBOL(__ppp_hold_channels); ++ + /* ppp_release_channels() + * Releases channels + */ +--- a/net/l2tp/l2tp_core.h ++++ b/net/l2tp/l2tp_core.h +@@ -235,6 +235,9 @@ struct l2tp_session *l2tp_session_get_by + void l2tp_stats_update(struct l2tp_tunnel *tunnel, struct l2tp_session *session, + struct l2tp_stats *stats); + ++void l2tp_stats_update(struct l2tp_tunnel *tunnel, struct l2tp_session *session, ++ struct l2tp_stats *stats); ++ + /* Tunnel and session lifetime management. + * Creation of a new instance is a two-step process: create, then register. + * Destruction is triggered using the *_delete functions, and completes asynchronously. From d8e906ab757a3b7dec2f9b959c235517156d0692 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 02:25:20 +0300 Subject: [PATCH 037/225] qualcommax: net: QCA NSS clients iptunnel support Signed-off-by: bitthief --- ...a-nss-clients-iptunnel-lock-this-cpu.patch | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch diff --git a/target/linux/qualcommax/patches-6.1/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch b/target/linux/qualcommax/patches-6.1/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch new file mode 100644 index 00000000000000..faba23d8630d8c --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch @@ -0,0 +1,22 @@ +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -2404,7 +2404,7 @@ nla_put_failure: + */ + void ip6_update_offload_stats(struct net_device *dev, void *ptr) + { +- struct pcpu_sw_netstats *tstats = per_cpu_ptr(dev->tstats, 0); ++ struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats); + const struct pcpu_sw_netstats *offload_stats = + (struct pcpu_sw_netstats *)ptr; + +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -1736,7 +1736,7 @@ nla_put_failure: + /* QCA NSS Clients Support - Start */ + void ipip6_update_offload_stats(struct net_device *dev, void *ptr) + { +- struct pcpu_sw_netstats *tstats = per_cpu_ptr(dev->tstats, 0); ++ struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats); + const struct pcpu_sw_netstats *offload_stats = + (struct pcpu_sw_netstats *)ptr; + From 5a5f050308f80a543a8dd64b92dd35b419c49e21 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 02:25:29 +0300 Subject: [PATCH 038/225] qualcommax: net: QCA NSS clients tlsmgr support Signed-off-by: bitthief --- ...-qca-nss-clients-add-tls-mgr-support.patch | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/0603-8-qca-nss-clients-add-tls-mgr-support.patch diff --git a/target/linux/qualcommax/patches-6.1/0603-8-qca-nss-clients-add-tls-mgr-support.patch b/target/linux/qualcommax/patches-6.1/0603-8-qca-nss-clients-add-tls-mgr-support.patch new file mode 100644 index 00000000000000..0499e237f6be88 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0603-8-qca-nss-clients-add-tls-mgr-support.patch @@ -0,0 +1,24 @@ +--- /dev/null ++++ b/include/uapi/linux/tlshdr.h +@@ -0,0 +1,21 @@ ++#ifndef _UAPI_LINUX_TLSHDR_H ++#define _UAPI_LINUX_TLSHDR_H ++ ++#include ++ ++struct tlshdr { ++ __u8 type; ++ __be16 version; ++ __be16 len; ++} __attribute__((packed)); ++ ++#define TLSHDR_REC_TYPE_CCS 20 /* TLS packet is change cipher specification */ ++#define TLSHDR_REC_TYPE_ALERT 21 /* TLS packet is Alert */ ++#define TLSHDR_REC_TYPE_HANDSHAKE 22 /* TLS packet is Handshake */ ++#define TLSHDR_REC_TYPE_DATA 23 /* TLS packet is Application data */ ++ ++#define TLSHDR_VERSION_1_1 0x0302 /* TLS Header Version(tls 1.1) */ ++#define TLSHDR_VERSION_1_2 0x0303 /* TLS Header Version(tls 1.2) */ ++#define TLSHDR_VERSION_1_3 0x0304 /* TLS Header Version(tls 1.3) */ ++ ++#endif /* _UAPI_LINUX_TLSHDR_H */ From eefb58408ed5afb8259bce5f18e6c305d623c6bd Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 02:25:49 +0300 Subject: [PATCH 039/225] qualcommax: net: QCA MCS support Signed-off-by: bitthief --- .../0604-qca-add-mcs-support.patch | 924 ++++++++++++++++++ 1 file changed, 924 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/0604-qca-add-mcs-support.patch diff --git a/target/linux/qualcommax/patches-6.1/0604-qca-add-mcs-support.patch b/target/linux/qualcommax/patches-6.1/0604-qca-add-mcs-support.patch new file mode 100644 index 00000000000000..6c4f44374471d4 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0604-qca-add-mcs-support.patch @@ -0,0 +1,924 @@ +--- a/include/linux/if_bridge.h ++++ b/include/linux/if_bridge.h +@@ -256,4 +256,17 @@ extern br_get_dst_hook_t __rcu *br_get_d + extern struct net_device *br_fdb_bridge_dev_get_and_hold(struct net_bridge *br); + /* QCA NSS bridge-mgr support - End */ + ++/* QCA qca-mcs support - Start */ ++typedef struct net_bridge_port *br_get_dst_hook_t(const struct net_bridge_port *src, ++ struct sk_buff **skb); ++extern br_get_dst_hook_t __rcu *br_get_dst_hook; ++ ++typedef int (br_multicast_handle_hook_t)(const struct net_bridge_port *src, ++ struct sk_buff *skb); ++extern br_multicast_handle_hook_t __rcu *br_multicast_handle_hook; ++ ++typedef void (br_notify_hook_t)(int group, int event, const void *ptr); ++extern br_notify_hook_t __rcu *br_notify_hook; ++/* QCA qca-mcs support - End */ ++ + #endif +--- a/net/bridge/br_fdb.c ++++ b/net/bridge/br_fdb.c +@@ -256,7 +256,8 @@ static void fdb_notify(struct net_bridge + kfree_skb(skb); + goto errout; + } +- rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); ++ __br_notify(RTNLGRP_NEIGH, type, fdb); /* QCA qca-mcs support */ ++ rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); + return; + errout: + rtnl_set_sk_err(net, RTNLGRP_NEIGH, err); +@@ -322,6 +323,7 @@ struct net_bridge_fdb_entry *br_fdb_find + { + return fdb_find_rcu(&br->fdb_hash_tbl, addr, vid); + } ++EXPORT_SYMBOL_GPL(br_fdb_find_rcu); /* QCA qca-mcs support */ + + /* When a static FDB entry is added, the mac address from the entry is + * added to the bridge private HW address list and all required ports +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -853,6 +853,7 @@ void br_manage_promisc(struct net_bridge + int nbp_backup_change(struct net_bridge_port *p, struct net_device *backup_dev); + + /* br_input.c */ ++int br_pass_frame_up(struct sk_buff *skb); /* QCA qca-mcs support */ + int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb); + rx_handler_func_t *br_get_rx_handler(const struct net_device *dev); + +@@ -2177,4 +2178,14 @@ struct nd_msg *br_is_nd_neigh_msg(struct + #define __br_get(__hook, __default, __args ...) \ + (__hook ? (__hook(__args)) : (__default)) + /* QCA NSS ECM support - End */ ++ ++/* QCA qca-mcs support - Start */ ++static inline void __br_notify(int group, int type, const void *data) ++{ ++ br_notify_hook_t *notify_hook = rcu_dereference(br_notify_hook); ++ ++ if (notify_hook) ++ notify_hook(group, type, data); ++} ++/* QCA qca-mcs support - End */ + #endif +--- a/net/bridge/br_netlink.c ++++ b/net/bridge/br_netlink.c +@@ -640,6 +640,7 @@ void br_info_notify(int event, const str + kfree_skb(skb); + goto errout; + } ++ __br_notify(RTNLGRP_LINK, event, port); /* QCA qca-mcs support */ + rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC); + return; + errout: +--- a/net/bridge/br.c ++++ b/net/bridge/br.c +@@ -463,6 +463,12 @@ static void __exit br_deinit(void) + br_fdb_fini(); + } + ++/* QCA qca-mcs support - Start */ ++/* Hook for bridge event notifications */ ++br_notify_hook_t __rcu *br_notify_hook __read_mostly; ++EXPORT_SYMBOL_GPL(br_notify_hook); ++/* QCA qca-mcs support - End */ ++ + module_init(br_init) + module_exit(br_deinit) + MODULE_LICENSE("GPL"); +--- a/net/bridge/br_device.c ++++ b/net/bridge/br_device.c +@@ -82,6 +82,12 @@ netdev_tx_t br_dev_xmit(struct sk_buff * + if (is_broadcast_ether_addr(dest)) { + br_flood(br, skb, BR_PKT_BROADCAST, false, true); + } else if (is_multicast_ether_addr(dest)) { ++ /* QCA qca-mcs support - Start */ ++ br_multicast_handle_hook_t *multicast_handle_hook = rcu_dereference(br_multicast_handle_hook); ++ if (!__br_get(multicast_handle_hook, true, NULL, skb)) ++ goto out; ++ /* QCA qca-mcs support - End */ ++ + if (unlikely(netpoll_tx_running(dev))) { + br_flood(br, skb, BR_PKT_MULTICAST, false, true); + goto out; +--- a/net/bridge/br_input.c ++++ b/net/bridge/br_input.c +@@ -23,6 +23,16 @@ + #include "br_private.h" + #include "br_private_tunnel.h" + ++/* QCA qca-mcs support - Start */ ++/* Hook for external Multicast handler */ ++br_multicast_handle_hook_t __rcu *br_multicast_handle_hook __read_mostly; ++EXPORT_SYMBOL_GPL(br_multicast_handle_hook); ++ ++/* Hook for external forwarding logic */ ++br_get_dst_hook_t __rcu *br_get_dst_hook __read_mostly; ++EXPORT_SYMBOL_GPL(br_get_dst_hook); ++/* QCA qca-mcs support - End */ ++ + static int + br_netif_receive_skb(struct net *net, struct sock *sk, struct sk_buff *skb) + { +@@ -30,7 +40,7 @@ br_netif_receive_skb(struct net *net, st + return netif_receive_skb(skb); + } + +-static int br_pass_frame_up(struct sk_buff *skb) ++int br_pass_frame_up(struct sk_buff *skb) + { + struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev; + struct net_bridge *br = netdev_priv(brdev); +@@ -69,6 +79,7 @@ static int br_pass_frame_up(struct sk_bu + dev_net(indev), NULL, skb, indev, NULL, + br_netif_receive_skb); + } ++EXPORT_SYMBOL_GPL(br_pass_frame_up); /* QCA qca-mcs support */ + + /* note: already called with rcu_read_lock */ + int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb) +@@ -84,6 +95,11 @@ int br_handle_frame_finish(struct net *n + struct net_bridge *br; + u16 vid = 0; + u8 state; ++ /* QCA qca-mcs support - Start */ ++ br_multicast_handle_hook_t *multicast_handle_hook; ++ struct net_bridge_port *pdst = NULL; ++ br_get_dst_hook_t *get_dst_hook = rcu_dereference(br_get_dst_hook); ++ /* QCA qca-mcs support - End */ + + if (!p) + goto drop; +@@ -158,6 +174,11 @@ int br_handle_frame_finish(struct net *n + + switch (pkt_type) { + case BR_PKT_MULTICAST: ++ /* QCA qca-mcs support - Start */ ++ multicast_handle_hook = rcu_dereference(br_multicast_handle_hook); ++ if (!__br_get(multicast_handle_hook, true, p, skb)) ++ goto out; ++ /* QCA qca-mcs support - End */ + mdst = br_mdb_get(brmctx, skb, vid); + if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) && + br_multicast_querier_exists(brmctx, eth_hdr(skb), mdst)) { +@@ -173,8 +194,15 @@ int br_handle_frame_finish(struct net *n + } + break; + case BR_PKT_UNICAST: +- dst = br_fdb_find_rcu(br, eth_hdr(skb)->h_dest, vid); +- break; ++ /* QCA qca-mcs support - Start */ ++ pdst = __br_get(get_dst_hook, NULL, p, &skb); ++ if (pdst) { ++ if (!skb) ++ goto out; ++ } else { ++ /* QCA qca-mcs support - End */ ++ dst = br_fdb_find_rcu(br, eth_hdr(skb)->h_dest, vid); ++ } + default: + break; + } +@@ -189,6 +217,12 @@ int br_handle_frame_finish(struct net *n + dst->used = now; + br_forward(dst->dst, skb, local_rcv, false); + } else { ++ /* QCA qca-mcs support - Start */ ++ if (pdst) { ++ br_forward(pdst, skb, local_rcv, false); ++ goto out; ++ } ++ /* QCA qca-mcs support - End */ + if (!mcast_hit) + br_flood(br, skb, pkt_type, local_rcv, false); + else +--- a/include/linux/mroute.h ++++ b/include/linux/mroute.h +@@ -85,4 +85,44 @@ struct rtmsg; + int ipmr_get_route(struct net *net, struct sk_buff *skb, + __be32 saddr, __be32 daddr, + struct rtmsg *rtm, u32 portid); ++ ++/* QCA ECM qca-mcs support - Start */ ++#define IPMR_MFC_EVENT_UPDATE 1 ++#define IPMR_MFC_EVENT_DELETE 2 ++ ++/* ++ * Callback to registered modules in the event of updates to a multicast group ++ */ ++typedef void (*ipmr_mfc_event_offload_callback_t)(__be32 origin, __be32 group, ++ u32 max_dest_dev, ++ u32 dest_dev_idx[], ++ u8 op); ++ ++/* ++ * Register the callback used to inform offload modules when updates occur to ++ * MFC. The callback is registered by offload modules ++ */ ++extern bool ipmr_register_mfc_event_offload_callback( ++ ipmr_mfc_event_offload_callback_t mfc_offload_cb); ++ ++/* ++ * De-Register the callback used to inform offload modules when updates occur ++ * to MFC ++ */ ++extern void ipmr_unregister_mfc_event_offload_callback(void); ++ ++/* ++ * Find the destination interface list, given a multicast group and source ++ */ ++extern int ipmr_find_mfc_entry(struct net *net, __be32 origin, __be32 group, ++ u32 max_dst_cnt, u32 dest_dev[]); ++ ++/* ++ * Out-of-band multicast statistics update for flows that are offloaded from ++ * Linux ++ */ ++extern int ipmr_mfc_stats_update(struct net *net, __be32 origin, __be32 group, ++ u64 pkts_in, u64 bytes_in, ++ u64 pkts_out, u64 bytes_out); ++/* QCA ECM qca-mcs support - End */ + #endif +--- a/include/linux/mroute6.h ++++ b/include/linux/mroute6.h +@@ -110,4 +110,47 @@ static inline int ip6mr_sk_done(struct s + return 0; + } + #endif ++ ++/* QCA qca-mcs support - Start */ ++#define IP6MR_MFC_EVENT_UPDATE 1 ++#define IP6MR_MFC_EVENT_DELETE 2 ++ ++/* ++ * Callback to registered modules in the event of updates to a multicast group ++ */ ++typedef void (*ip6mr_mfc_event_offload_callback_t)(struct in6_addr *origin, ++ struct in6_addr *group, ++ u32 max_dest_dev, ++ u32 dest_dev_idx[], ++ uint8_t op); ++ ++/* ++ * Register the callback used to inform offload modules when updates occur ++ * to MFC. The callback is registered by offload modules ++ */ ++extern bool ip6mr_register_mfc_event_offload_callback( ++ ip6mr_mfc_event_offload_callback_t mfc_offload_cb); ++ ++/* ++ * De-Register the callback used to inform offload modules when updates occur ++ * to MFC ++ */ ++extern void ip6mr_unregister_mfc_event_offload_callback(void); ++ ++/* ++ * Find the destination interface list given a multicast group and source ++ */ ++extern int ip6mr_find_mfc_entry(struct net *net, struct in6_addr *origin, ++ struct in6_addr *group, u32 max_dst_cnt, ++ u32 dest_dev[]); ++ ++/* ++ * Out-of-band multicast statistics update for flows that are offloaded from ++ * Linux ++ */ ++extern int ip6mr_mfc_stats_update(struct net *net, struct in6_addr *origin, ++ struct in6_addr *group, uint64_t pkts_in, ++ uint64_t bytes_in, uint64_t pkts_out, ++ uint64_t bytes_out); ++/* QCA qca-mcs support - End */ + #endif +--- a/net/ipv4/ipmr.c ++++ b/net/ipv4/ipmr.c +@@ -113,6 +113,15 @@ static void igmpmsg_netlink_event(const + static void mroute_clean_tables(struct mr_table *mrt, int flags); + static void ipmr_expire_process(struct timer_list *t); + ++/* QCA ECM qca-mcs support - Start */ ++/* spinlock for offload */ ++static DEFINE_SPINLOCK(lock); ++ ++static struct mfc_cache *ipmr_cache_find(struct mr_table *mrt, __be32 origin, ++ __be32 mcastgrp); ++static ipmr_mfc_event_offload_callback_t __rcu ipmr_mfc_event_offload_callback; ++/* QCA ECM qca-mcs support - End */ ++ + #ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES + #define ipmr_for_each_table(mrt, net) \ + list_for_each_entry_rcu(mrt, &net->ipv4.mr_tables, list, \ +@@ -223,6 +232,228 @@ static int ipmr_rule_fill(struct fib_rul + return 0; + } + ++/* QCA ECM qca-mcs support - Start */ ++/* ipmr_sync_entry_update() ++ * Call the registered offload callback to report an update to a multicast ++ * route entry. The callback receives the list of destination interfaces and ++ * the interface count ++ */ ++static void ipmr_sync_entry_update(struct mr_table *mrt, ++ struct mfc_cache *cache) ++{ ++ int vifi, dest_if_count = 0; ++ u32 dest_dev[MAXVIFS]; ++ __be32 origin; ++ __be32 group; ++ ipmr_mfc_event_offload_callback_t offload_update_cb_f; ++ ++ memset(dest_dev, 0, sizeof(dest_dev)); ++ ++ origin = cache->mfc_origin; ++ group = cache->mfc_mcastgrp; ++ ++ spin_lock(&mrt_lock); ++ for (vifi = 0; vifi < cache->_c.mfc_un.res.maxvif; vifi++) { ++ if (!((cache->_c.mfc_un.res.ttls[vifi] > 0) && ++ (cache->_c.mfc_un.res.ttls[vifi] < 255))) { ++ continue; ++ } ++ if (dest_if_count == MAXVIFS) { ++ spin_unlock(&mrt_lock); ++ return; ++ } ++ ++ if (!VIF_EXISTS(mrt, vifi)) { ++ spin_unlock(&mrt_lock); ++ return; ++ } ++ dest_dev[dest_if_count] = mrt->vif_table[vifi].dev->ifindex; ++ dest_if_count++; ++ } ++ spin_unlock(&mrt_lock); ++ ++ rcu_read_lock(); ++ offload_update_cb_f = rcu_dereference(ipmr_mfc_event_offload_callback); ++ ++ if (!offload_update_cb_f) { ++ rcu_read_unlock(); ++ return; ++ } ++ ++ offload_update_cb_f(group, origin, dest_if_count, dest_dev, ++ IPMR_MFC_EVENT_UPDATE); ++ rcu_read_unlock(); ++} ++ ++/* ipmr_sync_entry_delete() ++ * Call the registered offload callback to inform of a multicast route entry ++ * delete event ++ */ ++static void ipmr_sync_entry_delete(u32 origin, u32 group) ++{ ++ ipmr_mfc_event_offload_callback_t offload_update_cb_f; ++ ++ rcu_read_lock(); ++ offload_update_cb_f = rcu_dereference(ipmr_mfc_event_offload_callback); ++ ++ if (!offload_update_cb_f) { ++ rcu_read_unlock(); ++ return; ++ } ++ ++ offload_update_cb_f(group, origin, 0, NULL, IPMR_MFC_EVENT_DELETE); ++ rcu_read_unlock(); ++} ++ ++/* ipmr_register_mfc_event_offload_callback() ++ * Register the IPv4 Multicast update offload callback with IPMR ++ */ ++bool ipmr_register_mfc_event_offload_callback( ++ ipmr_mfc_event_offload_callback_t mfc_offload_cb) ++{ ++ ipmr_mfc_event_offload_callback_t offload_update_cb_f; ++ ++ rcu_read_lock(); ++ offload_update_cb_f = rcu_dereference(ipmr_mfc_event_offload_callback); ++ ++ if (offload_update_cb_f) { ++ rcu_read_unlock(); ++ return false; ++ } ++ rcu_read_unlock(); ++ ++ spin_lock(&lock); ++ rcu_assign_pointer(ipmr_mfc_event_offload_callback, mfc_offload_cb); ++ spin_unlock(&lock); ++ synchronize_rcu(); ++ return true; ++} ++EXPORT_SYMBOL(ipmr_register_mfc_event_offload_callback); ++ ++/* ipmr_unregister_mfc_event_offload_callback() ++ * De-register the IPv4 Multicast update offload callback with IPMR ++ */ ++void ipmr_unregister_mfc_event_offload_callback(void) ++{ ++ spin_lock(&lock); ++ rcu_assign_pointer(ipmr_mfc_event_offload_callback, NULL); ++ spin_unlock(&lock); ++ synchronize_rcu(); ++} ++EXPORT_SYMBOL(ipmr_unregister_mfc_event_offload_callback); ++ ++/* ipmr_find_mfc_entry() ++ * Returns destination interface list for a particular multicast flow, and ++ * the number of interfaces in the list ++ */ ++int ipmr_find_mfc_entry(struct net *net, __be32 origin, __be32 group, ++ u32 max_dest_cnt, u32 dest_dev[]) ++{ ++ int vifi, dest_if_count = 0; ++ struct mr_table *mrt; ++ struct mfc_cache *cache; ++ ++ mrt = ipmr_get_table(net, RT_TABLE_DEFAULT); ++ if (!mrt) ++ return -ENOENT; ++ ++ rcu_read_lock(); ++ cache = ipmr_cache_find(mrt, origin, group); ++ if (!cache) { ++ rcu_read_unlock(); ++ return -ENOENT; ++ } ++ ++ spin_lock(&mrt_lock); ++ for (vifi = 0; vifi < cache->_c.mfc_un.res.maxvif; vifi++) { ++ if (!((cache->_c.mfc_un.res.ttls[vifi] > 0) && ++ (cache->_c.mfc_un.res.ttls[vifi] < 255))) { ++ continue; ++ } ++ ++ /* We have another valid destination interface entry. Check if ++ * the number of the destination interfaces for the route is ++ * exceeding the size of the array given to us ++ */ ++ if (dest_if_count == max_dest_cnt) { ++ spin_unlock(&mrt_lock); ++ rcu_read_unlock(); ++ return -EINVAL; ++ } ++ ++ if (!VIF_EXISTS(mrt, vifi)) { ++ spin_unlock(&mrt_lock); ++ rcu_read_unlock(); ++ return -EINVAL; ++ } ++ ++ dest_dev[dest_if_count] = mrt->vif_table[vifi].dev->ifindex; ++ dest_if_count++; ++ } ++ spin_unlock(&mrt_lock); ++ rcu_read_unlock(); ++ ++ return dest_if_count; ++} ++EXPORT_SYMBOL(ipmr_find_mfc_entry); ++ ++/* ipmr_mfc_stats_update() ++ * Update the MFC/VIF statistics for offloaded flows ++ */ ++int ipmr_mfc_stats_update(struct net *net, __be32 origin, __be32 group, ++ u64 pkts_in, u64 bytes_in, ++ u64 pkts_out, u64 bytes_out) ++{ ++ int vif, vifi; ++ struct mr_table *mrt; ++ struct mfc_cache *cache; ++ ++ mrt = ipmr_get_table(net, RT_TABLE_DEFAULT); ++ if (!mrt) ++ return -ENOENT; ++ ++ rcu_read_lock(); ++ cache = ipmr_cache_find(mrt, origin, group); ++ if (!cache) { ++ rcu_read_unlock(); ++ return -ENOENT; ++ } ++ ++ vif = cache->_c.mfc_parent; ++ ++ spin_lock(&mrt_lock); ++ if (!VIF_EXISTS(mrt, vif)) { ++ spin_unlock(&mrt_lock); ++ rcu_read_unlock(); ++ return -EINVAL; ++ } ++ ++ mrt->vif_table[vif].pkt_in += pkts_in; ++ mrt->vif_table[vif].bytes_in += bytes_in; ++ cache->_c.mfc_un.res.pkt += pkts_out; ++ cache->_c.mfc_un.res.bytes += bytes_out; ++ ++ for (vifi = cache->_c.mfc_un.res.minvif; ++ vifi < cache->_c.mfc_un.res.maxvif; vifi++) { ++ if ((cache->_c.mfc_un.res.ttls[vifi] > 0) && ++ (cache->_c.mfc_un.res.ttls[vifi] < 255)) { ++ if (!VIF_EXISTS(mrt, vifi)) { ++ spin_unlock(&mrt_lock); ++ rcu_read_unlock(); ++ return -EINVAL; ++ } ++ mrt->vif_table[vifi].pkt_out += pkts_out; ++ mrt->vif_table[vifi].bytes_out += bytes_out; ++ } ++ } ++ spin_unlock(&mrt_lock); ++ rcu_read_unlock(); ++ ++ return 0; ++} ++EXPORT_SYMBOL(ipmr_mfc_stats_update); ++/* QCA ECM qca-mcs support - End */ ++ + static const struct fib_rules_ops __net_initconst ipmr_rules_ops_template = { + .family = RTNL_FAMILY_IPMR, + .rule_size = sizeof(struct ipmr_rule), +@@ -1193,6 +1424,11 @@ static int ipmr_mfc_delete(struct mr_tab + mroute_netlink_event(mrt, c, RTM_DELROUTE); + mr_cache_put(&c->_c); + ++ /* QCA ECM qca-mcs support - Start */ ++ /* Inform offload modules of the delete event */ ++ ipmr_sync_entry_delete(c->mfc_origin, c->mfc_mcastgrp); ++ /* QCA ECM qca-mcs support - End */ ++ + return 0; + } + +@@ -1222,6 +1458,12 @@ static int ipmr_mfc_add(struct net *net, + call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_REPLACE, c, + mrt->id); + mroute_netlink_event(mrt, c, RTM_NEWROUTE); ++ ++ /* QCA ECM qca-mcs support - Start */ ++ /* Inform offload modules of the update event */ ++ ipmr_sync_entry_update(mrt, c); ++ /* QCA ECM qca-mcs support - End */ ++ + return 0; + } + +@@ -1282,6 +1524,7 @@ static void mroute_clean_tables(struct m + struct net *net = read_pnet(&mrt->net); + struct mr_mfc *c, *tmp; + struct mfc_cache *cache; ++ u32 origin, group; /* QCA ECM qca-mcs support */ + LIST_HEAD(list); + int i; + +@@ -1306,10 +1549,19 @@ static void mroute_clean_tables(struct m + rhltable_remove(&mrt->mfc_hash, &c->mnode, ipmr_rht_params); + list_del_rcu(&c->list); + cache = (struct mfc_cache *)c; ++ /* QCA ECM qca-mcs support - Start */ ++ origin = cache->mfc_origin; ++ group = cache->mfc_mcastgrp; ++ /* QCA ECM qca-mcs support - End */ + call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, cache, + mrt->id); + mroute_netlink_event(mrt, cache, RTM_DELROUTE); + mr_cache_put(c); ++ ++ /* QCA ECM qca-mcs support - Start */ ++ /* Inform offload modules of the delete event */ ++ ipmr_sync_entry_delete(origin, group); ++ /* QCA ECM qca-mcs support - End */ + } + } + +--- a/net/ipv6/ip6mr.c ++++ b/net/ipv6/ip6mr.c +@@ -102,6 +102,17 @@ static int ip6mr_rtm_dumproute(struct sk + static void mroute_clean_tables(struct mr_table *mrt, int flags); + static void ipmr_expire_process(struct timer_list *t); + ++/* QCA qca-mcs support - Start */ ++/* Spinlock for offload */ ++static DEFINE_SPINLOCK(lock); ++ ++static struct mfc6_cache *ip6mr_cache_find(struct mr_table *mrt, ++ const struct in6_addr *origin, ++ const struct in6_addr *mcastgrp); ++static ip6mr_mfc_event_offload_callback_t __rcu ++ ip6mr_mfc_event_offload_callback; ++/* QCA qca-mcs support - End */ ++ + #ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES + #define ip6mr_for_each_table(mrt, net) \ + list_for_each_entry_rcu(mrt, &net->ipv6.mr6_tables, list, \ +@@ -380,6 +391,227 @@ static struct mr_table_ops ip6mr_mr_tabl + .cmparg_any = &ip6mr_mr_table_ops_cmparg_any, + }; + ++/* QCA qca-mcs support - Start */ ++/* ip6mr_sync_entry_update() ++ * Call the registered offload callback to report an update to a multicast ++ * route entry. The callback receives the list of destination interfaces and ++ * the interface count ++ */ ++static void ip6mr_sync_entry_update(struct mr_table *mrt, ++ struct mfc6_cache *cache) ++{ ++ int vifi, dest_if_count = 0; ++ u32 dest_dev[MAXMIFS]; ++ struct in6_addr mc_origin, mc_group; ++ ip6mr_mfc_event_offload_callback_t offload_update_cb_f; ++ ++ memset(dest_dev, 0, sizeof(dest_dev)); ++ ++ spin_lock(&mrt_lock); ++ ++ for (vifi = 0; vifi < cache->_c.mfc_un.res.maxvif; vifi++) { ++ if (!((cache->_c.mfc_un.res.ttls[vifi] > 0) && ++ (cache->_c.mfc_un.res.ttls[vifi] < 255))) { ++ continue; ++ } ++ ++ if (dest_if_count == MAXMIFS) { ++ spin_unlock(&mrt_lock); ++ return; ++ } ++ ++ if (!VIF_EXISTS(mrt, vifi)) { ++ spin_unlock(&mrt_lock); ++ return; ++ } ++ ++ dest_dev[dest_if_count] = mrt->vif_table[vifi].dev->ifindex; ++ dest_if_count++; ++ } ++ ++ memcpy(&mc_origin, &cache->mf6c_origin, sizeof(struct in6_addr)); ++ memcpy(&mc_group, &cache->mf6c_mcastgrp, sizeof(struct in6_addr)); ++ spin_unlock(&mrt_lock); ++ ++ rcu_read_lock(); ++ offload_update_cb_f = rcu_dereference(ip6mr_mfc_event_offload_callback); ++ ++ if (!offload_update_cb_f) { ++ rcu_read_unlock(); ++ return; ++ } ++ ++ offload_update_cb_f(&mc_group, &mc_origin, dest_if_count, dest_dev, ++ IP6MR_MFC_EVENT_UPDATE); ++ rcu_read_unlock(); ++} ++ ++/* ip6mr_sync_entry_delete() ++ * Call the registered offload callback to inform of a multicast route entry ++ * delete event ++ */ ++static void ip6mr_sync_entry_delete(struct in6_addr *mc_origin, ++ struct in6_addr *mc_group) ++{ ++ ip6mr_mfc_event_offload_callback_t offload_update_cb_f; ++ ++ rcu_read_lock(); ++ offload_update_cb_f = rcu_dereference(ip6mr_mfc_event_offload_callback); ++ ++ if (!offload_update_cb_f) { ++ rcu_read_unlock(); ++ return; ++ } ++ ++ offload_update_cb_f(mc_group, mc_origin, 0, NULL, ++ IP6MR_MFC_EVENT_DELETE); ++ rcu_read_unlock(); ++} ++ ++/* ip6mr_register_mfc_event_offload_callback() ++ * Register the IPv6 multicast update callback for offload modules ++ */ ++bool ip6mr_register_mfc_event_offload_callback( ++ ip6mr_mfc_event_offload_callback_t mfc_offload_cb) ++{ ++ ip6mr_mfc_event_offload_callback_t offload_update_cb_f; ++ ++ rcu_read_lock(); ++ offload_update_cb_f = rcu_dereference(ip6mr_mfc_event_offload_callback); ++ ++ if (offload_update_cb_f) { ++ rcu_read_unlock(); ++ return false; ++ } ++ rcu_read_unlock(); ++ ++ spin_lock(&lock); ++ rcu_assign_pointer(ip6mr_mfc_event_offload_callback, mfc_offload_cb); ++ spin_unlock(&lock); ++ synchronize_rcu(); ++ return true; ++} ++EXPORT_SYMBOL(ip6mr_register_mfc_event_offload_callback); ++ ++/* ip6mr_unregister_mfc_event_offload_callback() ++ * De-register the IPv6 multicast update callback for offload modules ++ */ ++void ip6mr_unregister_mfc_event_offload_callback(void) ++{ ++ spin_lock(&lock); ++ rcu_assign_pointer(ip6mr_mfc_event_offload_callback, NULL); ++ spin_unlock(&lock); ++ synchronize_rcu(); ++} ++EXPORT_SYMBOL(ip6mr_unregister_mfc_event_offload_callback); ++ ++/* ip6mr_find_mfc_entry() ++ * Return the destination interface list for a particular multicast flow, and ++ * the number of interfaces in the list ++ */ ++int ip6mr_find_mfc_entry(struct net *net, struct in6_addr *origin, ++ struct in6_addr *group, u32 max_dest_cnt, ++ u32 dest_dev[]) ++{ ++ int vifi, dest_if_count = 0; ++ struct mr_table *mrt; ++ struct mfc6_cache *cache; ++ ++ mrt = ip6mr_get_table(net, RT6_TABLE_DFLT); ++ if (!mrt) ++ return -ENOENT; ++ ++ spin_lock(&mrt_lock); ++ cache = ip6mr_cache_find(mrt, origin, group); ++ if (!cache) { ++ spin_unlock(&mrt_lock); ++ return -ENOENT; ++ } ++ ++ for (vifi = 0; vifi < cache->_c.mfc_un.res.maxvif; vifi++) { ++ if (!((cache->_c.mfc_un.res.ttls[vifi] > 0) && ++ (cache->_c.mfc_un.res.ttls[vifi] < 255))) { ++ continue; ++ } ++ ++ /* We have another valid destination interface entry. Check if ++ * the number of the destination interfaces for the route is ++ * exceeding the size of the array given to us ++ */ ++ if (dest_if_count == max_dest_cnt) { ++ spin_unlock(&mrt_lock); ++ return -EINVAL; ++ } ++ ++ if (!VIF_EXISTS(mrt, vifi)) { ++ spin_unlock(&mrt_lock); ++ return -EINVAL; ++ } ++ ++ dest_dev[dest_if_count] = mrt->vif_table[vifi].dev->ifindex; ++ dest_if_count++; ++ } ++ spin_unlock(&mrt_lock); ++ ++ return dest_if_count; ++} ++EXPORT_SYMBOL(ip6mr_find_mfc_entry); ++ ++/* ip6mr_mfc_stats_update() ++ * Update the MFC/VIF statistics for offloaded flows ++ */ ++int ip6mr_mfc_stats_update(struct net *net, struct in6_addr *origin, ++ struct in6_addr *group, u64 pkts_in, ++ u64 bytes_in, uint64_t pkts_out, ++ u64 bytes_out) ++{ ++ int vif, vifi; ++ struct mr_table *mrt; ++ struct mfc6_cache *cache; ++ ++ mrt = ip6mr_get_table(net, RT6_TABLE_DFLT); ++ ++ if (!mrt) ++ return -ENOENT; ++ ++ spin_lock(&mrt_lock); ++ cache = ip6mr_cache_find(mrt, origin, group); ++ if (!cache) { ++ spin_unlock(&mrt_lock); ++ return -ENOENT; ++ } ++ ++ vif = cache->_c.mfc_parent; ++ ++ if (!VIF_EXISTS(mrt, vif)) { ++ spin_unlock(&mrt_lock); ++ return -EINVAL; ++ } ++ ++ mrt->vif_table[vif].pkt_in += pkts_in; ++ mrt->vif_table[vif].bytes_in += bytes_in; ++ cache->_c.mfc_un.res.pkt += pkts_out; ++ cache->_c.mfc_un.res.bytes += bytes_out; ++ ++ for (vifi = cache->_c.mfc_un.res.minvif; ++ vifi < cache->_c.mfc_un.res.maxvif; vifi++) { ++ if ((cache->_c.mfc_un.res.ttls[vifi] > 0) && ++ (cache->_c.mfc_un.res.ttls[vifi] < 255)) { ++ if (!VIF_EXISTS(mrt, vifi)) { ++ spin_unlock(&mrt_lock); ++ return -EINVAL; ++ } ++ mrt->vif_table[vifi].pkt_out += pkts_out; ++ mrt->vif_table[vifi].bytes_out += bytes_out; ++ } ++ } ++ ++ spin_unlock(&mrt_lock); ++ return 0; ++} ++EXPORT_SYMBOL(ip6mr_mfc_stats_update); ++/* QCA qca-mcs support - End */ ++ + static struct mr_table *ip6mr_new_table(struct net *net, u32 id) + { + struct mr_table *mrt; +@@ -1221,6 +1453,7 @@ static int ip6mr_mfc_delete(struct mr_ta + int parent) + { + struct mfc6_cache *c; ++ struct in6_addr mc_origin, mc_group; /* QCA qca-mcs support */ + + /* The entries are added/deleted only under RTNL */ + rcu_read_lock(); +@@ -1229,6 +1462,12 @@ static int ip6mr_mfc_delete(struct mr_ta + rcu_read_unlock(); + if (!c) + return -ENOENT; ++ ++ /* QCA qca-mcs support - Start */ ++ memcpy(&mc_origin, &c->mf6c_origin, sizeof(struct in6_addr)); ++ memcpy(&mc_group, &c->mf6c_mcastgrp, sizeof(struct in6_addr)); ++ /* QCA qca-mcs support - End */ ++ + rhltable_remove(&mrt->mfc_hash, &c->_c.mnode, ip6mr_rht_params); + list_del_rcu(&c->_c.list); + +@@ -1236,6 +1475,12 @@ static int ip6mr_mfc_delete(struct mr_ta + FIB_EVENT_ENTRY_DEL, c, mrt->id); + mr6_netlink_event(mrt, c, RTM_DELROUTE); + mr_cache_put(&c->_c); ++ ++ /* QCA qca-mcs support - Start */ ++ /* Inform offload modules of the delete event */ ++ ip6mr_sync_entry_delete(&mc_origin, &mc_group); ++ /* QCA qca-mcs support - End */ ++ + return 0; + } + +@@ -1457,6 +1702,12 @@ static int ip6mr_mfc_add(struct net *net + call_ip6mr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_REPLACE, + c, mrt->id); + mr6_netlink_event(mrt, c, RTM_NEWROUTE); ++ ++ /* QCA qca-mcs support - Start */ ++ /* Inform offload modules of the update event */ ++ ip6mr_sync_entry_update(mrt, c); ++ /* QCA qca-mcs support - End */ ++ + return 0; + } + +@@ -1519,6 +1770,10 @@ static int ip6mr_mfc_add(struct net *net + + static void mroute_clean_tables(struct mr_table *mrt, int flags) + { ++ /* QCA qca-mcs support - Start */ ++ struct mfc6_cache *cache; ++ struct in6_addr mc_origin, mc_group; ++ /* QCA qca-mcs support - End */ + struct mr_mfc *c, *tmp; + LIST_HEAD(list); + int i; +@@ -1541,13 +1796,23 @@ static void mroute_clean_tables(struct m + if (((c->mfc_flags & MFC_STATIC) && !(flags & MRT6_FLUSH_MFC_STATIC)) || + (!(c->mfc_flags & MFC_STATIC) && !(flags & MRT6_FLUSH_MFC))) + continue; ++ /* QCA qca-mcs support - Start */ ++ cache = (struct mfc6_cache *)c; ++ memcpy(&mc_origin, &cache->mf6c_origin, sizeof(struct in6_addr)); ++ memcpy(&mc_group, &cache->mf6c_mcastgrp, sizeof(struct in6_addr)); ++ /* QCA qca-mcs support - End */ + rhltable_remove(&mrt->mfc_hash, &c->mnode, ip6mr_rht_params); + list_del_rcu(&c->list); + call_ip6mr_mfc_entry_notifiers(read_pnet(&mrt->net), + FIB_EVENT_ENTRY_DEL, +- (struct mfc6_cache *)c, mrt->id); +- mr6_netlink_event(mrt, (struct mfc6_cache *)c, RTM_DELROUTE); ++ cache, mrt->id); ++ mr6_netlink_event(mrt, cache, RTM_DELROUTE); + mr_cache_put(c); ++ ++ /* QCA qca-mcs support - Start */ ++ /* Inform offload modules of the delete event */ ++ ip6mr_sync_entry_delete(&mc_origin, &mc_group); ++ /* QCA qca-mcs support - End */ + } + } From 03c1fca02582ebc111f8c13dbe246d99ff7bf039 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 02:26:34 +0300 Subject: [PATCH 040/225] qualcommax: crypto: net: QCA NSS CFI and NSS CRYPTO support Signed-off-by: bitthief --- .../0605-qca-nss-cfi-support.patch | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/0605-qca-nss-cfi-support.patch diff --git a/target/linux/qualcommax/patches-6.1/0605-qca-nss-cfi-support.patch b/target/linux/qualcommax/patches-6.1/0605-qca-nss-cfi-support.patch new file mode 100644 index 00000000000000..a92092d601bdbc --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0605-qca-nss-cfi-support.patch @@ -0,0 +1,111 @@ +--- a/crypto/authenc.c ++++ b/crypto/authenc.c +@@ -417,6 +417,8 @@ static int crypto_authenc_create(struct + enc->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME) + goto err_free_inst; + ++ inst->alg.base.cra_flags |= (auth_base->cra_flags | ++ enc->base.cra_flags) & CRYPTO_ALG_NOSUPP_SG; + inst->alg.base.cra_priority = enc->base.cra_priority * 10 + + auth_base->cra_priority; + inst->alg.base.cra_blocksize = enc->base.cra_blocksize; +--- a/include/linux/crypto.h ++++ b/include/linux/crypto.h +@@ -101,6 +101,11 @@ + #define CRYPTO_NOLOAD 0x00008000 + + /* ++ * Set this flag if algorithm does not support SG list transforms ++ */ ++#define CRYPTO_ALG_NOSUPP_SG 0x0000c000 ++ ++/* + * The algorithm may allocate memory during request processing, i.e. during + * encryption, decryption, or hashing. Users can request an algorithm with this + * flag unset if they can't handle memory allocation failures. +--- a/net/ipv4/esp4.c ++++ b/net/ipv4/esp4.c +@@ -658,6 +658,7 @@ static int esp_output(struct xfrm_state + struct ip_esp_hdr *esph; + struct crypto_aead *aead; + struct esp_info esp; ++ bool nosupp_sg; + + esp.inplace = true; + +@@ -669,6 +670,11 @@ static int esp_output(struct xfrm_state + aead = x->data; + alen = crypto_aead_authsize(aead); + ++ nosupp_sg = crypto_tfm_alg_type(&aead->base) & CRYPTO_ALG_NOSUPP_SG; ++ if (nosupp_sg && skb_linearize(skb)) { ++ return -ENOMEM; ++ } ++ + esp.tfclen = 0; + if (x->tfcpad) { + struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb); +@@ -888,6 +894,7 @@ static int esp_input(struct xfrm_state * + u8 *iv; + struct scatterlist *sg; + int err = -EINVAL; ++ bool nosupp_sg; + + if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr) + ivlen)) + goto out; +@@ -895,6 +902,12 @@ static int esp_input(struct xfrm_state * + if (elen <= 0) + goto out; + ++ nosupp_sg = crypto_tfm_alg_type(&aead->base) & CRYPTO_ALG_NOSUPP_SG; ++ if (nosupp_sg && skb_linearize(skb)) { ++ err = -ENOMEM; ++ goto out; ++ } ++ + assoclen = sizeof(struct ip_esp_hdr); + seqhilen = 0; + +--- a/net/ipv6/esp6.c ++++ b/net/ipv6/esp6.c +@@ -696,6 +696,7 @@ static int esp6_output(struct xfrm_state + struct ip_esp_hdr *esph; + struct crypto_aead *aead; + struct esp_info esp; ++ bool nosupp_sg; + + esp.inplace = true; + +@@ -707,6 +708,11 @@ static int esp6_output(struct xfrm_state + aead = x->data; + alen = crypto_aead_authsize(aead); + ++ nosupp_sg = crypto_tfm_alg_type(&aead->base) & CRYPTO_ALG_NOSUPP_SG; ++ if (nosupp_sg && skb_linearize(skb)) { ++ return -ENOMEM; ++ } ++ + esp.tfclen = 0; + if (x->tfcpad) { + struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb); +@@ -932,6 +938,7 @@ static int esp6_input(struct xfrm_state + __be32 *seqhi; + u8 *iv; + struct scatterlist *sg; ++ bool nosupp_sg; + + if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr) + ivlen)) { + ret = -EINVAL; +@@ -943,6 +950,12 @@ static int esp6_input(struct xfrm_state + goto out; + } + ++ nosupp_sg = crypto_tfm_alg_type(&aead->base) & CRYPTO_ALG_NOSUPP_SG; ++ if (nosupp_sg && skb_linearize(skb)) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ + assoclen = sizeof(struct ip_esp_hdr); + seqhilen = 0; + From 60e54b2db6cc79e574a0ab9dbf1add87f4cdf4ee Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 02:28:27 +0300 Subject: [PATCH 041/225] qualcommax: net: fix NULL pointer reference in ipv6_output Signed-off-by: bitthief --- ...l-pointer-dereference-in-ipv6-output.patch | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/0611-ipv6-Fix-null-pointer-dereference-in-ipv6-output.patch diff --git a/target/linux/qualcommax/patches-6.1/0611-ipv6-Fix-null-pointer-dereference-in-ipv6-output.patch b/target/linux/qualcommax/patches-6.1/0611-ipv6-Fix-null-pointer-dereference-in-ipv6-output.patch new file mode 100644 index 00000000000000..608ab7f2b33675 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0611-ipv6-Fix-null-pointer-dereference-in-ipv6-output.patch @@ -0,0 +1,80 @@ +From eee3a7956b943dd3e23a74fbb5bfe89405eb0782 Mon Sep 17 00:00:00 2001 +From: Andrea Righi +Date: Mon, 6 Dec 2021 17:34:47 +0100 +Subject: UBUNTU: SAUCE: ipv6: fix NULL pointer dereference in ip6_output() + +It is possible to trigger a NULL pointer dereference by running the srv6 +net kselftest (tools/testing/selftests/net/srv6_end_dt46_l3vpn_test.sh): + +[ 249.051216] BUG: kernel NULL pointer dereference, address: 0000000000000378 +[ 249.052331] #PF: supervisor read access in kernel mode +[ 249.053137] #PF: error_code(0x0000) - not-present page +[ 249.053960] PGD 0 P4D 0 +[ 249.054376] Oops: 0000 [#1] PREEMPT SMP NOPTI +[ 249.055083] CPU: 1 PID: 21 Comm: ksoftirqd/1 Tainted: G E 5.16.0-rc4 #2 +[ 249.056328] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 +[ 249.057632] RIP: 0010:ip6_forward+0x53c/0xab0 +[ 249.058354] Code: 49 c7 44 24 20 00 00 00 00 48 83 e0 fe 48 8b 40 30 48 3d 70 b2 b5 81 0f 85 b5 04 00 00 e8 7c f2 ff ff 41 89 c5 e9 17 01 00 00 <44> 8b 93 78 03 00 00 45 85 d2 0f 85 92 fb ff ff 49 8b 54 24 10 48 +[ 249.061274] RSP: 0018:ffffc900000cbb30 EFLAGS: 00010246 +[ 249.062042] RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffff8881051d3400 +[ 249.063141] RDX: ffff888104bda000 RSI: 00000000000002c0 RDI: 0000000000000000 +[ 249.064264] RBP: ffffc900000cbbc8 R08: 0000000000000000 R09: 0000000000000000 +[ 249.065376] R10: 0000000000000040 R11: 0000000000000000 R12: ffff888103409800 +[ 249.066498] R13: ffff8881051d3410 R14: ffff888102725280 R15: ffff888103525000 +[ 249.067619] FS: 0000000000000000(0000) GS:ffff88813bc80000(0000) knlGS:0000000000000000 +[ 249.068881] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 249.069777] CR2: 0000000000000378 CR3: 0000000104980000 CR4: 0000000000750ee0 +[ 249.070907] PKRU: 55555554 +[ 249.071337] Call Trace: +[ 249.071730] +[ 249.072070] ? debug_smp_processor_id+0x17/0x20 +[ 249.072807] seg6_input_core+0x2bb/0x2d0 +[ 249.073436] ? _raw_spin_unlock_irqrestore+0x29/0x40 +[ 249.074225] seg6_input+0x3b/0x130 +[ 249.074768] lwtunnel_input+0x5e/0xa0 +[ 249.075357] ip_rcv+0x17b/0x190 +[ 249.075867] ? update_load_avg+0x82/0x600 +[ 249.076514] __netif_receive_skb_one_core+0x86/0xa0 +[ 249.077231] __netif_receive_skb+0x15/0x60 +[ 249.077843] process_backlog+0x97/0x160 +[ 249.078389] __napi_poll+0x31/0x170 +[ 249.078912] net_rx_action+0x229/0x270 +[ 249.079506] __do_softirq+0xef/0x2ed +[ 249.080085] run_ksoftirqd+0x37/0x50 +[ 249.080663] smpboot_thread_fn+0x193/0x230 +[ 249.081312] kthread+0x17a/0x1a0 +[ 249.081847] ? smpboot_register_percpu_thread+0xe0/0xe0 +[ 249.082677] ? set_kthread_struct+0x50/0x50 +[ 249.083340] ret_from_fork+0x22/0x30 +[ 249.083926] +[ 249.090295] ---[ end trace 1998d7ba5965a365 ]--- + +It looks like commit 0857d6f8c759 ("ipv6: When forwarding count rx stats +on the orig netdev") tries to determine the right netdev to account the +rx stats, but in this particular case it's failing and the netdev is +NULL. + +Fallback to the previous method of determining the netdev interface (via +skb->dev) to account the rx stats when the orig netdev can't be +determined. + +Fixes: 0857d6f8c759 ("ipv6: When forwarding count rx stats on the orig netdev") +Signed-off-by: Andrea Righi +(cherry picked from https://lore.kernel.org/lkml/20211206163447.991402-1-andrea.righi@canonical.com/T/#u) +Signed-off-by: Andrea Righi +--- + net/ipv6/ip6_output.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -492,6 +492,9 @@ int ip6_forward(struct sk_buff *skb) + u32 mtu; + + idev = __in6_dev_get_safely(dev_get_by_index_rcu(net, IP6CB(skb)->iif)); ++ if (unlikely(!idev)) ++ idev = __in6_dev_get_safely(skb->dev); ++ + if (net->ipv6.devconf_all->forwarding == 0) + goto error; + From 415d7e3131954b32b65938b8e03e2a547eef54de Mon Sep 17 00:00:00 2001 From: bitthief Date: Thu, 27 Jul 2023 08:04:54 +0300 Subject: [PATCH 042/225] kernel: qualcommax: nss: bump 6.1 to 6.1.62 Signed-off-by: bitthief --- ...ts-ipq8074-add-reserved-memory-nodes.patch | 4 +- ...added-for-necessary-clocks-and-reset.patch | 12 +- ...-gcc_snoc_bus_timeout_ahb_clk-offset.patch | 4 +- ...074-Fix-gcc_blsp1_ahb_clk-properties.patch | 2 +- .../0600-1-qca-nss-ecm-support-CORE.patch | 126 +++++++++--------- ...-2-qca-nss-ecm-support-PPPOE-offload.patch | 40 +++--- ...00-3-qca-nss-ecm-support-net-bonding.patch | 6 +- ...pport-net-bonding-over-LAG-interface.patch | 24 ++-- .../0600-5-qca-nss-ecm-support-macvlan.patch | 8 +- ...nss-ecm-support-netfilter-DSCPREMARK.patch | 12 +- .../0602-qca-nss-drv-add-qdisc-support.patch | 4 +- ...-1-qca-nss-clients-add-qdisc-support.patch | 49 +++---- ...3-3-qca-nss-clients-add-PPTP-support.patch | 44 +++--- ...qca-nss-clients-add-iptunnel-support.patch | 10 +- ...-5-qca-nss-clients-add-vxlan-support.patch | 4 +- .../0604-qca-add-mcs-support.patch | 49 +++---- .../0605-qca-nss-cfi-support.patch | 8 +- 17 files changed, 194 insertions(+), 212 deletions(-) diff --git a/target/linux/qualcommax/patches-6.1/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch b/target/linux/qualcommax/patches-6.1/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch index 90c3acfb811410..b57b66635892f1 100644 --- a/target/linux/qualcommax/patches-6.1/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch +++ b/target/linux/qualcommax/patches-6.1/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch @@ -22,7 +22,7 @@ Signed-off-by: Robert Marko @@ -85,6 +85,26 @@ #size-cells = <2>; ranges; - + + nss_region: nss@40000000 { + no-map; + reg = <0x0 0x40000000 0x0 0x01000000>; @@ -66,5 +66,5 @@ Signed-off-by: Robert Marko + reg = <0x0 0x51000000 0x0 0x100000>; + }; }; - + firmware { diff --git a/target/linux/qualcommax/patches-6.1/0170-clk-qcom-ipq8074-Support-added-for-necessary-clocks-and-reset.patch b/target/linux/qualcommax/patches-6.1/0170-clk-qcom-ipq8074-Support-added-for-necessary-clocks-and-reset.patch index 478de529563e52..85430f888cb4bd 100644 --- a/target/linux/qualcommax/patches-6.1/0170-clk-qcom-ipq8074-Support-added-for-necessary-clocks-and-reset.patch +++ b/target/linux/qualcommax/patches-6.1/0170-clk-qcom-ipq8074-Support-added-for-necessary-clocks-and-reset.patch @@ -37,7 +37,7 @@ Signed-off-by: Rajkumar Ayyasamy static struct clk_alpha_pll gpll0_main = { .offset = 0x21000, .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], -@@ -636,6 +652,12 @@ static const struct freq_tbl ftbl_pcie_a +@@ -630,6 +646,12 @@ static const struct freq_tbl ftbl_pcie_a { } }; @@ -50,7 +50,7 @@ Signed-off-by: Rajkumar Ayyasamy static struct clk_rcg2 pcie0_axi_clk_src = { .cmd_rcgr = 0x75054, .freq_tbl = ftbl_pcie_axi_clk_src, -@@ -2036,6 +2058,78 @@ static struct clk_rcg2 gp3_clk_src = { +@@ -2030,6 +2052,78 @@ static struct clk_rcg2 gp3_clk_src = { }, }; @@ -129,7 +129,7 @@ Signed-off-by: Rajkumar Ayyasamy static struct clk_branch gcc_blsp1_ahb_clk = { .halt_reg = 0x01008, .clkr = { -@@ -4231,13 +4325,7 @@ static struct clk_branch gcc_gp3_clk = { +@@ -4225,13 +4319,7 @@ static struct clk_branch gcc_gp3_clk = { }, }; @@ -144,7 +144,7 @@ Signed-off-by: Rajkumar Ayyasamy .cmd_rcgr = 0x75070, .freq_tbl = ftbl_pcie_rchng_clk_src, .hid_width = 5, -@@ -4329,6 +4417,114 @@ static const struct alpha_pll_config nss +@@ -4323,6 +4411,114 @@ static const struct alpha_pll_config nss .alpha_en_mask = BIT(24), }; @@ -259,7 +259,7 @@ Signed-off-by: Rajkumar Ayyasamy static struct clk_hw *gcc_ipq8074_hws[] = { &gpll0_out_main_div2.hw, &gpll6_out_main_div2.hw, -@@ -4337,6 +4533,7 @@ static struct clk_hw *gcc_ipq8074_hws[] +@@ -4331,6 +4527,7 @@ static struct clk_hw *gcc_ipq8074_hws[] &gcc_xo_div4_clk_src.hw, &nss_noc_clk_src.hw, &nss_ppe_cdiv_clk_src.hw, @@ -267,7 +267,7 @@ Signed-off-by: Rajkumar Ayyasamy }; static struct clk_regmap *gcc_ipq8074_clks[] = { -@@ -4568,6 +4765,15 @@ static struct clk_regmap *gcc_ipq8074_cl +@@ -4562,6 +4759,15 @@ static struct clk_regmap *gcc_ipq8074_cl [GCC_PCIE0_RCHNG_CLK] = &gcc_pcie0_rchng_clk.clkr, [GCC_PCIE0_AXI_S_BRIDGE_CLK] = &gcc_pcie0_axi_s_bridge_clk.clkr, [GCC_CRYPTO_PPE_CLK] = &gcc_crypto_ppe_clk.clkr, diff --git a/target/linux/qualcommax/patches-6.1/0171-1-clk-qcom-ipq8074-Fix-gcc_snoc_bus_timeout_ahb_clk-offset.patch b/target/linux/qualcommax/patches-6.1/0171-1-clk-qcom-ipq8074-Fix-gcc_snoc_bus_timeout_ahb_clk-offset.patch index ec0528f39db5cc..7aae767ee3ac2d 100644 --- a/target/linux/qualcommax/patches-6.1/0171-1-clk-qcom-ipq8074-Fix-gcc_snoc_bus_timeout_ahb_clk-offset.patch +++ b/target/linux/qualcommax/patches-6.1/0171-1-clk-qcom-ipq8074-Fix-gcc_snoc_bus_timeout_ahb_clk-offset.patch @@ -16,7 +16,7 @@ Signed-off-by: Selvam Sathappan Periakaruppan --- a/drivers/clk/qcom/gcc-ipq8074.c +++ b/drivers/clk/qcom/gcc-ipq8074.c -@@ -4418,10 +4418,10 @@ static const struct alpha_pll_config nss +@@ -4412,10 +4412,10 @@ static const struct alpha_pll_config nss }; static struct clk_branch gcc_snoc_bus_timeout2_ahb_clk = { @@ -29,7 +29,7 @@ Signed-off-by: Selvam Sathappan Periakaruppan .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_snoc_bus_timeout2_ahb_clk", -@@ -4436,10 +4436,10 @@ static struct clk_branch gcc_snoc_bus_ti +@@ -4430,10 +4430,10 @@ static struct clk_branch gcc_snoc_bus_ti }; static struct clk_branch gcc_snoc_bus_timeout3_ahb_clk = { diff --git a/target/linux/qualcommax/patches-6.1/0171-2-clk-qcom-ipq8074-Fix-gcc_blsp1_ahb_clk-properties.patch b/target/linux/qualcommax/patches-6.1/0171-2-clk-qcom-ipq8074-Fix-gcc_blsp1_ahb_clk-properties.patch index be70e6418cf021..3c7be347815cdb 100644 --- a/target/linux/qualcommax/patches-6.1/0171-2-clk-qcom-ipq8074-Fix-gcc_blsp1_ahb_clk-properties.patch +++ b/target/linux/qualcommax/patches-6.1/0171-2-clk-qcom-ipq8074-Fix-gcc_blsp1_ahb_clk-properties.patch @@ -26,7 +26,7 @@ Change-Id: I505cb560b31ad27a02c165fbe13bb33a2fc7d230 --- a/drivers/clk/qcom/gcc-ipq8074.c +++ b/drivers/clk/qcom/gcc-ipq8074.c -@@ -2132,9 +2132,10 @@ struct clk_rcg2 adss_pwm_clk_src = { +@@ -2126,9 +2126,10 @@ struct clk_rcg2 adss_pwm_clk_src = { static struct clk_branch gcc_blsp1_ahb_clk = { .halt_reg = 0x01008, diff --git a/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch b/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch index bbb1b97861fd8a..9f71b49166ca95 100644 --- a/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch +++ b/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch @@ -7,13 +7,13 @@ +extern void br_dev_update_stats(struct net_device *dev, + struct rtnl_link_stats64 *nlstats); +extern bool br_is_hairpin_enabled(struct net_device *dev); - + #if IS_ENABLED(CONFIG_BRIDGE) && IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING) int br_multicast_list_adjacent(struct net_device *dev, @@ -211,4 +214,42 @@ static inline clock_t br_get_ageing_time } #endif - + +/* QCA NSS ECM support - Start */ +extern struct net_device *br_port_dev_get(struct net_device *dev, + unsigned char *addr, @@ -56,9 +56,9 @@ --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -227,7 +227,28 @@ extern void vlan_vids_del_by_dev(struct - + extern bool vlan_uses_dev(const struct net_device *dev); - + +/* QCA NSS ECM support - Start */ +extern void __vlan_dev_update_accel_stats(struct net_device *dev, + struct rtnl_link_stats64 *stats); @@ -86,7 +86,7 @@ __be16 vlan_proto, u16 vlan_id) --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h -@@ -2830,6 +2830,10 @@ enum netdev_cmd { +@@ -2831,6 +2831,10 @@ enum netdev_cmd { NETDEV_OFFLOAD_XSTATS_DISABLE, NETDEV_OFFLOAD_XSTATS_REPORT_USED, NETDEV_OFFLOAD_XSTATS_REPORT_DELTA, @@ -96,13 +96,13 @@ + /* QCA NSS ECM Support - End */ }; const char *netdev_cmd_to_name(enum netdev_cmd cmd); - + --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -506,4 +506,9 @@ int if6_proc_init(void); void if6_proc_exit(void); #endif - + +/* QCA NSS ECM support - Start */ +struct net_device *ipv6_dev_find_and_hold(struct net *net, struct in6_addr *addr, + int strict); @@ -114,7 +114,7 @@ @@ -211,6 +211,11 @@ void rt6_multipath_rebalance(struct fib6 void rt6_uncached_list_add(struct rt6_info *rt); void rt6_uncached_list_del(struct rt6_info *rt); - + +/* QCA NSS ECM support - Start */ +int rt6_register_notifier(struct notifier_block *nb); +int rt6_unregister_notifier(struct notifier_block *nb); @@ -125,7 +125,7 @@ const struct dst_entry *dst = skb_dst(skb); --- a/include/net/neighbour.h +++ b/include/net/neighbour.h -@@ -604,4 +604,15 @@ static inline void neigh_update_is_route +@@ -602,4 +602,15 @@ static inline void neigh_update_is_route *notify = 1; } } @@ -143,10 +143,10 @@ #endif --- a/include/net/route.h +++ b/include/net/route.h -@@ -243,6 +243,11 @@ struct rtable *rt_dst_alloc(struct net_d +@@ -240,6 +240,11 @@ struct rtable *rt_dst_alloc(struct net_d unsigned int flags, u16 type, bool noxfrm); struct rtable *rt_dst_clone(struct net_device *dev, struct rtable *rt); - + +/* QCA NSS ECM support - Start */ +int ip_rt_register_notifier(struct notifier_block *nb); +int ip_rt_unregister_notifier(struct notifier_block *nb); @@ -172,7 +172,7 @@ @@ -548,4 +548,52 @@ static int __init vlan_offload_init(void return 0; } - + +/* QCA NSS ECM support - Start */ +/* Update the VLAN device with statistics from network offload engines */ +void __vlan_dev_update_accel_stats(struct net_device *dev, @@ -225,9 +225,9 @@ --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c @@ -33,6 +33,35 @@ static const struct rhashtable_params br - + static struct kmem_cache *br_fdb_cache __read_mostly; - + +/* QCA NSS ECM support - Start */ +ATOMIC_NOTIFIER_HEAD(br_fdb_notifier_list); +ATOMIC_NOTIFIER_HEAD(br_fdb_update_notifier_list); @@ -263,7 +263,7 @@ @@ -185,7 +214,26 @@ static void fdb_notify(struct net_bridge struct sk_buff *skb; int err = -ENOBUFS; - + - if (swdev_notify) + /* QCA NSS ECM support - Start */ + if (fdb->dst) { @@ -286,14 +286,14 @@ + + if (swdev_notify) br_switchdev_fdb_notify(br, fdb, type); - + skb = nlmsg_new(fdb_nlmsg_size(), GFP_ATOMIC); @@ -520,6 +568,7 @@ void br_fdb_cleanup(struct work_struct * unsigned long delay = hold_time(br); unsigned long work_delay = delay; unsigned long now = jiffies; + u8 mac_addr[6]; /* QCA NSS ECM support */ - + /* this part is tricky, in order to avoid blocking learning and * consequently forwarding, we rely on rcu to delete objects with @@ -546,8 +595,15 @@ void br_fdb_cleanup(struct work_struct * @@ -324,7 +324,7 @@ + 0, (void *)addr); + /* QCA NSS ECM support - End */ } - + if (unlikely(test_bit(BR_FDB_ADDED_BY_USER, &flags))) @@ -1466,3 +1528,62 @@ void br_fdb_clear_offload(const struct n spin_unlock_bh(&p->br->hash_lock); @@ -392,9 +392,9 @@ --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -26,6 +26,12 @@ - + #include "br_private.h" - + +/* QCA NSS ECM support - Start */ +/* Hook for external forwarding logic */ +br_port_dev_get_hook_t __rcu *br_port_dev_get_hook __read_mostly; @@ -404,25 +404,25 @@ /* * Determine initial path cost based on speed. * using recommendations from 802.1d standard -@@ -696,6 +702,8 @@ int br_add_if(struct net_bridge *br, str - +@@ -697,6 +703,8 @@ int br_add_if(struct net_bridge *br, str + kobject_uevent(&p->kobj, KOBJ_ADD); - + + call_netdevice_notifiers(NETDEV_BR_JOIN, dev); /* QCA NSS ECM support */ + return 0; - + err6: -@@ -731,6 +739,8 @@ int br_del_if(struct net_bridge *br, str +@@ -732,6 +740,8 @@ int br_del_if(struct net_bridge *br, str if (!p || p->br != br) return -EINVAL; - + + call_netdevice_notifiers(NETDEV_BR_LEAVE, dev); /* QCA NSS ECM support */ + /* Since more than one interface can be attached to a bridge, * there still maybe an alternate path for netconsole to use; * therefore there is no reason for a NETDEV_RELEASE event. -@@ -774,3 +784,96 @@ bool br_port_flag_is_set(const struct ne +@@ -775,3 +785,96 @@ bool br_port_flag_is_set(const struct ne return p->flags & flag; } EXPORT_SYMBOL_GPL(br_port_flag_is_set); @@ -521,10 +521,10 @@ +/* QCA NSS ECM support - End */ --- a/net/core/neighbour.c +++ b/net/core/neighbour.c -@@ -1295,6 +1295,22 @@ static void neigh_update_hhs(struct neig +@@ -1268,6 +1268,22 @@ static void neigh_update_hhs(struct neig } } - + +/* QCA NSS ECM support - Start */ +ATOMIC_NOTIFIER_HEAD(neigh_mac_update_notifier_list); + @@ -544,15 +544,15 @@ /* Generic update routine. -- lladdr is new lladdr or NULL, if it is not supplied. -- new is new state. -@@ -1323,6 +1339,7 @@ static int __neigh_update(struct neighbo +@@ -1296,6 +1312,7 @@ static int __neigh_update(struct neighbo struct net_device *dev; int err, notify = 0; u8 old; + struct neigh_mac_update nmu; /* QCA NSS ECM support */ - + trace_neigh_update(neigh, lladdr, new, flags, nlmsg_pid); - -@@ -1337,7 +1354,10 @@ static int __neigh_update(struct neighbo + +@@ -1310,7 +1327,10 @@ static int __neigh_update(struct neighbo new = old; goto out; } @@ -563,8 +563,8 @@ + if (!(flags & NEIGH_UPDATE_F_ADMIN) && (old & (NUD_NOARP | NUD_PERMANENT))) goto out; - -@@ -1374,7 +1394,12 @@ static int __neigh_update(struct neighbo + +@@ -1347,7 +1367,12 @@ static int __neigh_update(struct neighbo - compare new & old - if they are different, check override flag */ @@ -578,7 +578,7 @@ !memcmp(lladdr, neigh->ha, dev->addr_len)) lladdr = neigh->ha; } else { -@@ -1496,8 +1521,11 @@ out: +@@ -1469,8 +1494,11 @@ out: neigh_update_gc_list(neigh); if (managed_update) neigh_update_managed_list(neigh); @@ -596,7 +596,7 @@ @@ -1211,6 +1211,9 @@ static bool fib_valid_key_len(u32 key, u static void fib_remove_alias(struct trie *t, struct key_vector *tp, struct key_vector *l, struct fib_alias *old); - + +/* Define route change notification chain. */ +static BLOCKING_NOTIFIER_HEAD(iproute_chain); /* QCA NSS ECM support */ + @@ -611,22 +611,22 @@ + RTM_NEWROUTE, fi); + return 0; - + out_remove_new_fa: -@@ -1774,6 +1780,9 @@ int fib_table_delete(struct net *net, st +@@ -1775,6 +1781,9 @@ int fib_table_delete(struct net *net, st if (fa_to_delete->fa_state & FA_S_ACCESSED) rt_cache_flush(cfg->fc_nlinfo.nl_net); - + + blocking_notifier_call_chain(&iproute_chain, + RTM_DELROUTE, fa_to_delete->fa_info); + fib_release_info(fa_to_delete->fa_info); alias_free_mem_rcu(fa_to_delete); return 0; -@@ -2402,6 +2411,20 @@ void __init fib_trie_init(void) +@@ -2407,6 +2416,20 @@ void __init fib_trie_init(void) 0, SLAB_PANIC | SLAB_ACCOUNT, NULL); } - + +/* QCA NSS ECM support - Start */ +int ip_rt_register_notifier(struct notifier_block *nb) +{ @@ -646,51 +646,51 @@ struct fib_table *tb; --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c -@@ -665,6 +665,7 @@ void ndisc_send_ns(struct net_device *de +@@ -666,6 +666,7 @@ void ndisc_send_ns(struct net_device *de if (skb) ndisc_send_skb(skb, daddr, saddr); } +EXPORT_SYMBOL(ndisc_send_ns); - + void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr, const struct in6_addr *daddr) --- a/net/ipv6/route.c +++ b/net/ipv6/route.c -@@ -3853,6 +3853,9 @@ out_free: +@@ -3857,6 +3857,9 @@ out_free: return ERR_PTR(err); } - + +/* Define route change notification chain. */ +ATOMIC_NOTIFIER_HEAD(ip6route_chain); /* QCA NSS ECM support */ + int ip6_route_add(struct fib6_config *cfg, gfp_t gfp_flags, struct netlink_ext_ack *extack) { -@@ -3864,6 +3867,10 @@ int ip6_route_add(struct fib6_config *cf +@@ -3868,6 +3871,10 @@ int ip6_route_add(struct fib6_config *cf return PTR_ERR(rt); - + err = __ip6_ins_rt(rt, &cfg->fc_nlinfo, extack); + if (!err) + atomic_notifier_call_chain(&ip6route_chain, + RTM_NEWROUTE, rt); + fib6_info_release(rt); - + return err; -@@ -3885,6 +3892,9 @@ static int __ip6_del_rt(struct fib6_info +@@ -3889,6 +3896,9 @@ static int __ip6_del_rt(struct fib6_info err = fib6_del(rt, info); spin_unlock_bh(&table->tb6_lock); - + + if (!err) + atomic_notifier_call_chain(&ip6route_chain, + RTM_DELROUTE, rt); out: fib6_info_release(rt); return err; -@@ -6338,6 +6348,20 @@ static int ip6_route_dev_notify(struct n +@@ -6342,6 +6352,20 @@ static int ip6_route_dev_notify(struct n return NOTIFY_OK; } - + +/* QCA NSS ECM support - Start */ +int rt6_register_notifier(struct notifier_block *nb) +{ @@ -710,7 +710,7 @@ */ --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -1629,6 +1629,7 @@ const char *netdev_cmd_to_name(enum netd +@@ -1639,6 +1639,7 @@ const char *netdev_cmd_to_name(enum netd N(SVLAN_FILTER_PUSH_INFO) N(SVLAN_FILTER_DROP_INFO) N(PRE_CHANGEADDR) N(OFFLOAD_XSTATS_ENABLE) N(OFFLOAD_XSTATS_DISABLE) N(OFFLOAD_XSTATS_REPORT_USED) N(OFFLOAD_XSTATS_REPORT_DELTA) @@ -720,16 +720,16 @@ return "UNKNOWN_NETDEV_EVENT"; --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c -@@ -986,6 +986,7 @@ void inet6_ifa_finish_destroy(struct ine - +@@ -987,6 +987,7 @@ void inet6_ifa_finish_destroy(struct ine + kfree_rcu(ifp, rcu); } +EXPORT_SYMBOL(inet6_ifa_finish_destroy); - + static void ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) -@@ -2044,6 +2045,36 @@ struct inet6_ifaddr *ipv6_get_ifaddr(str - +@@ -2045,6 +2046,36 @@ struct inet6_ifaddr *ipv6_get_ifaddr(str + return result; } +EXPORT_SYMBOL(ipv6_get_ifaddr); @@ -762,15 +762,15 @@ + return dev; +} +EXPORT_SYMBOL(ipv6_dev_find_and_hold); - + /* Gets referenced address, destroys ifaddr */ - + --- a/include/net/vxlan.h +++ b/include/net/vxlan.h -@@ -427,6 +427,15 @@ static inline __be32 vxlan_compute_rco(u +@@ -432,6 +432,15 @@ static inline __be32 vxlan_compute_rco(u return vni_field; } - + +/* + * vxlan_get_vni() + * Returns the vni corresponding to tunnel diff --git a/target/linux/qualcommax/patches-6.1/0600-2-qca-nss-ecm-support-PPPOE-offload.patch b/target/linux/qualcommax/patches-6.1/0600-2-qca-nss-ecm-support-PPPOE-offload.patch index 4bb87f49612c32..25e21bc09183ff 100644 --- a/target/linux/qualcommax/patches-6.1/0600-2-qca-nss-ecm-support-PPPOE-offload.patch +++ b/target/linux/qualcommax/patches-6.1/0600-2-qca-nss-ecm-support-PPPOE-offload.patch @@ -5,13 +5,13 @@ #include #include +#include - + #include #include @@ -254,6 +255,25 @@ struct ppp_net { #define seq_before(a, b) ((s32)((a) - (b)) < 0) #define seq_after(a, b) ((s32)((a) - (b)) > 0) - + + +/* + * Registration/Unregistration methods @@ -40,10 +40,10 @@ int hdrlen; + int ppp_proto; + int version; - + + int notify = 0; pn = ppp_pernet(pch->chan_net); - + mutex_lock(&pn->all_ppp_mutex); @@ -3485,13 +3508,40 @@ ppp_connect_channel(struct channel *pch, ++ppp->n_channels; @@ -86,7 +86,7 @@ + return ret; } - + @@ -3509,6 +3559,13 @@ ppp_disconnect_channel(struct channel *p pch->ppp = NULL; write_unlock_bh(&pch->upl); @@ -104,7 +104,7 @@ @@ -3588,6 +3645,222 @@ static void *unit_find(struct idr *p, in return idr_find(p, n); } - + +/* Updates the PPP interface statistics. */ +void ppp_update_stats(struct net_device *dev, unsigned long rx_packets, + unsigned long rx_bytes, unsigned long tx_packets, @@ -322,7 +322,7 @@ +EXPORT_SYMBOL(ppp_release_channels); + /* Module/initialization stuff */ - + module_init(ppp_init); @@ -3604,6 +3877,7 @@ EXPORT_SYMBOL(ppp_input_error); EXPORT_SYMBOL(ppp_output_wakeup); @@ -344,26 +344,26 @@ #include @@ -87,7 +88,7 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb); - + static const struct proto_ops pppoe_ops; -static const struct ppp_channel_ops pppoe_chan_ops; +static const struct pppoe_channel_ops pppoe_chan_ops; - + /* per-net private data for this module */ static unsigned int pppoe_net_id __read_mostly; @@ -692,7 +693,7 @@ static int pppoe_connect(struct socket * - + po->chan.mtu = dev->mtu - sizeof(struct pppoe_hdr) - 2; po->chan.private = sk; - po->chan.ops = &pppoe_chan_ops; + po->chan.ops = (struct ppp_channel_ops *)&pppoe_chan_ops; - + error = ppp_register_net_channel(dev_net(dev), &po->chan); if (error) { @@ -995,9 +996,80 @@ static int pppoe_fill_forward_path(struc return 0; } - + -static const struct ppp_channel_ops pppoe_chan_ops = { - .start_xmit = pppoe_xmit, - .fill_forward_path = pppoe_fill_forward_path, @@ -442,14 +442,14 @@ + .ops.release = pppoe_release_chan, + .ops.fill_forward_path = pppoe_fill_forward_path, }; - + static int pppoe_recvmsg(struct socket *sock, struct msghdr *m, --- a/include/linux/if_pppox.h +++ b/include/linux/if_pppox.h @@ -91,4 +91,17 @@ enum { PPPOX_DEAD = 16 /* dead, useless, please clean me up!*/ }; - + +/* + * PPPoE Channel specific operations + */ @@ -466,10 +466,10 @@ #endif /* !(__LINUX_IF_PPPOX_H) */ --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h -@@ -1707,6 +1707,24 @@ enum netdev_priv_flags { +@@ -1709,6 +1709,24 @@ enum netdev_priv_flags { IFF_NO_IP_ALIGN = BIT_ULL(33), }; - + + +/** + * enum netdev_priv_flags_ext - &struct net_device priv_flags_ext @@ -491,7 +491,7 @@ #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN #define IFF_EBRIDGE IFF_EBRIDGE #define IFF_BONDING IFF_BONDING -@@ -2050,7 +2068,8 @@ struct net_device { +@@ -2051,7 +2069,8 @@ struct net_device { /* Read-mostly cache-line for fast-path access */ unsigned int flags; unsigned long long priv_flags; @@ -511,7 +511,7 @@ + +#define PPP_CHANNEL_DISCONNECT 0 +#define PPP_CHANNEL_CONNECT 1 - + struct net_device_path; struct net_device_path_ctx; @@ -30,9 +34,19 @@ struct ppp_channel_ops { @@ -534,12 +534,12 @@ + struct net_device_path *, + const struct ppp_channel *); }; - + struct ppp_channel { @@ -76,6 +90,51 @@ extern int ppp_unit_number(struct ppp_ch /* Get the device name associated with a channel, or NULL if none */ extern char *ppp_dev_name(struct ppp_channel *); - + +/* Call this to obtain the underlying protocol of the PPP channel, + * e.g. PX_PROTO_OE + */ diff --git a/target/linux/qualcommax/patches-6.1/0600-3-qca-nss-ecm-support-net-bonding.patch b/target/linux/qualcommax/patches-6.1/0600-3-qca-nss-ecm-support-net-bonding.patch index 304b2c471b820f..a56b877a526d98 100644 --- a/target/linux/qualcommax/patches-6.1/0600-3-qca-nss-ecm-support-net-bonding.patch +++ b/target/linux/qualcommax/patches-6.1/0600-3-qca-nss-ecm-support-net-bonding.patch @@ -9,7 +9,7 @@ static struct flow_dissector flow_keys_bonding __read_mostly; /*-------------------------- Forward declarations ---------------------------*/ -@@ -4372,6 +4374,24 @@ static int bond_get_lowest_level_rcu(str +@@ -4377,6 +4379,24 @@ static int bond_get_lowest_level_rcu(str } #endif @@ -34,7 +34,7 @@ static void bond_get_stats(struct net_device *bond_dev, struct rtnl_link_stats64 *stats) { -@@ -5784,6 +5804,11 @@ static void bond_destructor(struct net_d +@@ -5789,6 +5809,11 @@ static void bond_destructor(struct net_d if (bond->rr_tx_counter) free_percpu(bond->rr_tx_counter); @@ -46,7 +46,7 @@ } void bond_setup(struct net_device *bond_dev) -@@ -6345,6 +6370,14 @@ int bond_create(struct net *net, const c +@@ -6352,6 +6377,14 @@ int bond_create(struct net *net, const c bond_work_init_all(bond); diff --git a/target/linux/qualcommax/patches-6.1/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch b/target/linux/qualcommax/patches-6.1/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch index d318ccb5353ab6..d931107e7b0bcc 100644 --- a/target/linux/qualcommax/patches-6.1/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch +++ b/target/linux/qualcommax/patches-6.1/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch @@ -238,7 +238,7 @@ if (bond_is_lb(bond)) bond_alb_handle_link_change(bond, new_active, BOND_LINK_UP); } else { -@@ -1798,7 +1815,8 @@ int bond_enslave(struct net_device *bond +@@ -1803,7 +1820,8 @@ int bond_enslave(struct net_device *bond const struct net_device_ops *slave_ops = slave_dev->netdev_ops; struct slave *new_slave = NULL, *prev_slave; struct sockaddr_storage ss; @@ -248,7 +248,7 @@ int res = 0, i; if (slave_dev->flags & IFF_MASTER && -@@ -2241,6 +2259,15 @@ int bond_enslave(struct net_device *bond +@@ -2246,6 +2264,15 @@ int bond_enslave(struct net_device *bond bond_is_active_slave(new_slave) ? "an active" : "a backup", new_slave->link != BOND_LINK_DOWN ? "an up" : "a down"); @@ -264,7 +264,7 @@ /* enslave is successful */ bond_queue_slave_event(new_slave); return 0; -@@ -2306,6 +2333,15 @@ err_undo_flags: +@@ -2311,6 +2338,15 @@ err_undo_flags: } } @@ -280,7 +280,7 @@ return res; } -@@ -2328,7 +2364,8 @@ static int __bond_release_one(struct net +@@ -2333,7 +2369,8 @@ static int __bond_release_one(struct net struct slave *slave, *oldcurrent; struct sockaddr_storage ss; int old_flags = bond_dev->flags; @@ -290,7 +290,7 @@ /* slave is not a slave or master is not master of this slave */ if (!(slave_dev->flags & IFF_SLAVE) || -@@ -2349,6 +2386,15 @@ static int __bond_release_one(struct net +@@ -2354,6 +2391,15 @@ static int __bond_release_one(struct net bond_set_slave_inactive_flags(slave, BOND_SLAVE_NOTIFY_NOW); @@ -306,7 +306,7 @@ bond_sysfs_slave_del(slave); /* recompute stats just before removing the slave */ -@@ -2668,6 +2714,8 @@ static void bond_miimon_commit(struct bo +@@ -2673,6 +2719,8 @@ static void bond_miimon_commit(struct bo struct slave *slave, *primary, *active; bool do_failover = false; struct list_head *iter; @@ -315,7 +315,7 @@ ASSERT_RTNL(); -@@ -2707,6 +2755,12 @@ static void bond_miimon_commit(struct bo +@@ -2712,6 +2760,12 @@ static void bond_miimon_commit(struct bo bond_set_active_slave(slave); } @@ -328,7 +328,7 @@ slave_info(bond->dev, slave->dev, "link status definitely up, %u Mbps %s duplex\n", slave->speed == SPEED_UNKNOWN ? 0 : slave->speed, slave->duplex ? "full" : "half"); -@@ -2755,6 +2809,16 @@ static void bond_miimon_commit(struct bo +@@ -2760,6 +2814,16 @@ static void bond_miimon_commit(struct bo unblock_netpoll_tx(); } @@ -345,7 +345,7 @@ bond_set_carrier(bond); } -@@ -4002,8 +4066,219 @@ static inline u32 bond_eth_hash(struct s +@@ -4007,8 +4071,219 @@ static inline u32 bond_eth_hash(struct s return 0; ep = (struct ethhdr *)(data + mhoff); @@ -566,7 +566,7 @@ static bool bond_flow_ip(struct sk_buff *skb, struct flow_keys *fk, const void *data, int hlen, __be16 l2_proto, int *nhoff, int *ip_proto, bool l34) -@@ -5200,15 +5475,23 @@ static netdev_tx_t bond_3ad_xor_xmit(str +@@ -5205,15 +5480,23 @@ static netdev_tx_t bond_3ad_xor_xmit(str struct net_device *dev) { struct bonding *bond = netdev_priv(dev); @@ -597,7 +597,7 @@ } /* in broadcast mode, we send everything to all usable interfaces. */ -@@ -5458,8 +5741,9 @@ static netdev_tx_t __bond_start_xmit(str +@@ -5463,8 +5746,9 @@ static netdev_tx_t __bond_start_xmit(str return bond_xmit_roundrobin(skb, dev); case BOND_MODE_ACTIVEBACKUP: return bond_xmit_activebackup(skb, dev); @@ -651,7 +651,7 @@ void bond_work_init_all(struct bonding *bond); #ifdef CONFIG_PROC_FS -@@ -803,4 +811,18 @@ static inline netdev_tx_t bond_tx_drop(s +@@ -794,4 +802,18 @@ static inline netdev_tx_t bond_tx_drop(s return NET_XMIT_DROP; } diff --git a/target/linux/qualcommax/patches-6.1/0600-5-qca-nss-ecm-support-macvlan.patch b/target/linux/qualcommax/patches-6.1/0600-5-qca-nss-ecm-support-macvlan.patch index 9bf8464ea063b0..5f18c6be736aa6 100644 --- a/target/linux/qualcommax/patches-6.1/0600-5-qca-nss-ecm-support-macvlan.patch +++ b/target/linux/qualcommax/patches-6.1/0600-5-qca-nss-ecm-support-macvlan.patch @@ -3,7 +3,7 @@ @@ -15,6 +15,13 @@ struct macvlan_port; #define MACVLAN_MC_FILTER_BITS 8 #define MACVLAN_MC_FILTER_SZ (1 << MACVLAN_MC_FILTER_BITS) - + +/* QCA NSS ECM Support - Start */ +/* + * Callback for updating interface statistics for macvlan flows offloaded from host CPU. @@ -20,7 +20,7 @@ #endif + macvlan_offload_stats_update_cb_t offload_stats_update; /* QCA NSS ECM support */ }; - + static inline void macvlan_count_rx(const struct macvlan_dev *vlan, @@ -107,4 +115,26 @@ static inline int macvlan_release_l2fw_o macvlan->accel_priv = NULL; @@ -54,7 +54,7 @@ @@ -933,6 +933,34 @@ static void macvlan_uninit(struct net_de macvlan_port_destroy(port->dev); } - + +/* QCA NSS ECM Support - Start */ +/* Update macvlan statistics processed by offload engines */ +static void macvlan_dev_update_stats(struct net_device *dev, @@ -91,6 +91,6 @@ vlan->port = port; vlan->set_features = MACVLAN_FEATURES; + vlan->offload_stats_update = macvlan_dev_update_stats; /* QCA NSS ECM Support */ - + vlan->mode = MACVLAN_MODE_VEPA; if (data && data[IFLA_MACVLAN_MODE]) diff --git a/target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch b/target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch index fbe6a368796511..110b22606fd517 100644 --- a/target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch +++ b/target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch @@ -1,9 +1,9 @@ --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -171,6 +171,13 @@ config NF_CONNTRACK_TIMEOUT - + If unsure, say `N'. - + +config NF_CONNTRACK_DSCPREMARK_EXT + bool 'Connection tracking extension for dscp remark target' + depends on NETFILTER_ADVANCED @@ -26,7 +26,7 @@ + NF_CT_EXT_NUM, }; - + --- a/net/netfilter/nf_conntrack_extend.c +++ b/net/netfilter/nf_conntrack_extend.c @@ -23,6 +23,7 @@ @@ -35,7 +35,7 @@ #include +#include #include - + #define NF_CT_EXT_PREALLOC 128u /* conntrack events are on by default */ @@ -54,6 +55,9 @@ static const u8 nf_ct_ext_type_len[NF_CT #if IS_ENABLED(CONFIG_NET_ACT_CT) @@ -45,7 +45,7 @@ + [NF_CT_EXT_DSCPREMARK] = sizeof(struct nf_ct_dscpremark_ext), +#endif }; - + static __always_inline unsigned int total_extension_size(void) @@ -86,6 +90,9 @@ static __always_inline unsigned int tota #if IS_ENABLED(CONFIG_NET_ACT_CT) @@ -56,7 +56,7 @@ +#endif ; } - + --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile @@ -14,6 +14,7 @@ nf_conntrack-$(CONFIG_NF_CONNTRACK_LABEL diff --git a/target/linux/qualcommax/patches-6.1/0602-qca-nss-drv-add-qdisc-support.patch b/target/linux/qualcommax/patches-6.1/0602-qca-nss-drv-add-qdisc-support.patch index a62fb5dd54a825..bbffeb1f0b683b 100644 --- a/target/linux/qualcommax/patches-6.1/0602-qca-nss-drv-add-qdisc-support.patch +++ b/target/linux/qualcommax/patches-6.1/0602-qca-nss-drv-add-qdisc-support.patch @@ -1,6 +1,6 @@ --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h -@@ -765,6 +765,7 @@ typedef unsigned char *sk_buff_data_t; +@@ -773,6 +773,7 @@ typedef unsigned char *sk_buff_data_t; * @offload_fwd_mark: Packet was L2-forwarded in hardware * @offload_l3_fwd_mark: Packet was L3-forwarded in hardware * @tc_skip_classify: do not classify packet. set by IFB device @@ -8,7 +8,7 @@ * @tc_at_ingress: used within tc_classify to distinguish in/egress * @redirected: packet was redirected by packet classifier * @from_ingress: packet was redirected from the ingress path -@@ -960,6 +961,8 @@ struct sk_buff { +@@ -968,6 +969,8 @@ struct sk_buff { #ifdef CONFIG_NET_CLS_ACT __u8 tc_skip_classify:1; __u8 tc_at_ingress:1; /* See TC_AT_INGRESS_MASK */ diff --git a/target/linux/qualcommax/patches-6.1/0603-1-qca-nss-clients-add-qdisc-support.patch b/target/linux/qualcommax/patches-6.1/0603-1-qca-nss-clients-add-qdisc-support.patch index 060edfd27f433e..671516cfcdde9e 100644 --- a/target/linux/qualcommax/patches-6.1/0603-1-qca-nss-clients-add-qdisc-support.patch +++ b/target/linux/qualcommax/patches-6.1/0603-1-qca-nss-clients-add-qdisc-support.patch @@ -5,15 +5,15 @@ void (*function)(struct timer_list *); u32 flags; + unsigned long cust_data; - + #ifdef CONFIG_LOCKDEP struct lockdep_map lockdep_map; --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -151,6 +151,31 @@ resched: - + } - + +void ifb_update_offload_stats(struct net_device *dev, struct pcpu_sw_netstats *offload_stats) +{ + struct ifb_dev_private *dp; @@ -52,9 +52,9 @@ dev->needs_free_netdev = true; --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h -@@ -4587,6 +4587,15 @@ void dev_uc_flush(struct net_device *dev +@@ -4588,6 +4588,15 @@ void dev_uc_flush(struct net_device *dev void dev_uc_init(struct net_device *dev); - + /** + * ifb_update_offload_stats - Update the IFB interface stats + * @dev: IFB device to update the stats @@ -68,10 +68,10 @@ * __dev_uc_sync - Synchonize device's unicast list * @dev: device to sync * @sync: function to call if address should be added -@@ -5123,6 +5132,11 @@ static inline bool netif_is_failover_sla +@@ -5133,6 +5142,11 @@ static inline bool netif_is_failover_sla return dev->priv_flags & IFF_FAILOVER_SLAVE; } - + +static inline bool netif_is_ifb_dev(const struct net_device *dev) +{ + return dev->priv_flags_ext & IFF_EXT_IFB; @@ -83,9 +83,9 @@ --- a/include/uapi/linux/pkt_sched.h +++ b/include/uapi/linux/pkt_sched.h @@ -1278,4 +1278,248 @@ enum { - + #define TCA_ETS_MAX (__TCA_ETS_MAX - 1) - + +/* QCA NSS Clients Support - Start */ +enum { + TCA_NSS_ACCEL_MODE_NSS_FW, @@ -338,13 +338,13 @@ return q; } +EXPORT_SYMBOL(qdisc_lookup); - + struct Qdisc *qdisc_lookup_rcu(struct net_device *dev, u32 handle) { -@@ -2322,4 +2323,26 @@ static int __init pktsched_init(void) +@@ -2386,4 +2387,26 @@ static int __init pktsched_init(void) return 0; } - + +/* QCA NSS Qdisc Support - Start */ +bool tcf_destroy(struct tcf_proto *tp, bool force) +{ @@ -370,22 +370,13 @@ subsys_initcall(pktsched_init); --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c -@@ -1046,7 +1046,7 @@ static void qdisc_free_cb(struct rcu_hea - qdisc_free(q); - } - --static void qdisc_destroy(struct Qdisc *qdisc) -+void qdisc_destroy(struct Qdisc *qdisc) - { - const struct Qdisc_ops *ops = qdisc->ops; - -@@ -1069,6 +1069,7 @@ static void qdisc_destroy(struct Qdisc * - +@@ -1069,6 +1069,7 @@ static void __qdisc_destroy(struct Qdisc + call_rcu(&qdisc->rcu, qdisc_free_cb); } +EXPORT_SYMBOL(qdisc_destroy); - - void qdisc_put(struct Qdisc *qdisc) + + void qdisc_destroy(struct Qdisc *qdisc) { --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -397,10 +388,10 @@ u32 limit; const struct Qdisc_ops *ops; struct qdisc_size_table __rcu *stab; -@@ -711,6 +712,40 @@ static inline bool skb_skip_tc_classify( +@@ -719,6 +720,40 @@ static inline bool skb_skip_tc_classify( return false; } - + +/* + * Set skb classify bit field. + */ @@ -438,10 +429,10 @@ /* Reset all TX qdiscs greater than index of a device. */ static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i) { -@@ -1295,4 +1330,9 @@ static inline void qdisc_synchronize(con +@@ -1305,4 +1340,9 @@ static inline void qdisc_synchronize(con msleep(1); } - + +/* QCA NSS Qdisc Support - Start */ +void qdisc_destroy(struct Qdisc *qdisc); +void tcf_destroy_chain(struct tcf_proto __rcu **fl); diff --git a/target/linux/qualcommax/patches-6.1/0603-3-qca-nss-clients-add-PPTP-support.patch b/target/linux/qualcommax/patches-6.1/0603-3-qca-nss-clients-add-PPTP-support.patch index 75e8323045ac7e..5fb9917bc9067e 100644 --- a/target/linux/qualcommax/patches-6.1/0603-3-qca-nss-clients-add-PPTP-support.patch +++ b/target/linux/qualcommax/patches-6.1/0603-3-qca-nss-clients-add-PPTP-support.patch @@ -131,7 +131,7 @@ --- a/drivers/net/ppp/pptp.c +++ b/drivers/net/ppp/pptp.c -@@ -49,6 +49,8 @@ static struct proto pptp_sk_proto __read +@@ -50,6 +50,8 @@ static struct proto pptp_sk_proto __read static const struct ppp_channel_ops pptp_chan_ops; static const struct proto_ops pptp_ops; @@ -140,7 +140,7 @@ static struct pppox_sock *lookup_chan(u16 call_id, __be32 s_addr) { struct pppox_sock *sock; -@@ -90,6 +92,79 @@ static int lookup_chan_dst(u16 call_id, +@@ -91,6 +93,79 @@ static int lookup_chan_dst(u16 call_id, return i < MAX_CALLID; } @@ -220,7 +220,16 @@ static int add_chan(struct pppox_sock *sock, struct pptp_addr *sa) { -@@ -145,8 +220,11 @@ static int pptp_xmit(struct ppp_channel +@@ -136,7 +211,7 @@ static struct rtable *pptp_route_output( + struct net *net; + + net = sock_net(sk); +- flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark, 0, ++ flowi4_init_output(fl4, 0, sk->sk_mark, 0, + RT_SCOPE_UNIVERSE, IPPROTO_GRE, 0, + po->proto.pptp.dst_addr.sin_addr.s_addr, + po->proto.pptp.src_addr.sin_addr.s_addr, +@@ -163,8 +238,11 @@ static int pptp_xmit(struct ppp_channel struct rtable *rt; struct net_device *tdev; @@ -232,16 +241,7 @@ if (sk_pppox(po)->sk_state & PPPOX_DEAD) goto tx_error; -@@ -155,7 +233,7 @@ static int pptp_xmit(struct ppp_channel - opt->dst_addr.sin_addr.s_addr, - opt->src_addr.sin_addr.s_addr, - 0, 0, IPPROTO_GRE, -- RT_TOS(0), sk->sk_bound_dev_if); -+ RT_TOS(0), 0); - if (IS_ERR(rt)) - goto tx_error; - -@@ -244,7 +322,32 @@ static int pptp_xmit(struct ppp_channel +@@ -258,7 +336,32 @@ static int pptp_xmit(struct ppp_channel ip_select_ident(net, skb, NULL); ip_send_check(iph); @@ -275,7 +275,7 @@ return 1; tx_error: -@@ -300,6 +403,13 @@ static int pptp_rcv_core(struct sock *sk +@@ -314,6 +417,13 @@ static int pptp_rcv_core(struct sock *sk goto drop; payload = skb->data + headersize; @@ -289,7 +289,7 @@ /* check for expected sequence number */ if (seq < opt->seq_recv + 1 || WRAPPED(opt->seq_recv, seq)) { if ((payload[0] == PPP_ALLSTATIONS) && (payload[1] == PPP_UI) && -@@ -357,6 +467,7 @@ static int pptp_rcv(struct sk_buff *skb) +@@ -371,6 +481,7 @@ static int pptp_rcv(struct sk_buff *skb) if (po) { skb_dst_drop(skb); nf_reset_ct(skb); @@ -297,17 +297,7 @@ return sk_receive_skb(sk_pppox(po), skb, 0); } drop: -@@ -442,8 +553,7 @@ static int pptp_connect(struct socket *s - opt->dst_addr.sin_addr.s_addr, - opt->src_addr.sin_addr.s_addr, - 0, 0, -- IPPROTO_GRE, RT_CONN_FLAGS(sk), -- sk->sk_bound_dev_if); -+ IPPROTO_GRE, RT_CONN_FLAGS(sk), 0); - if (IS_ERR(rt)) { - error = -EHOSTUNREACH; - goto end; -@@ -464,7 +574,7 @@ static int pptp_connect(struct socket *s +@@ -473,7 +584,7 @@ static int pptp_connect(struct socket *s opt->dst_addr = sp->sa_addr.pptp; sk->sk_state |= PPPOX_CONNECTED; @@ -316,7 +306,7 @@ end: release_sock(sk); return error; -@@ -594,9 +704,169 @@ static int pptp_ppp_ioctl(struct ppp_cha +@@ -603,9 +714,169 @@ static int pptp_ppp_ioctl(struct ppp_cha return err; } diff --git a/target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-add-iptunnel-support.patch b/target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-add-iptunnel-support.patch index 81da18bd796fa8..928510087da42a 100644 --- a/target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-add-iptunnel-support.patch +++ b/target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-add-iptunnel-support.patch @@ -10,10 +10,10 @@ __u32 flags; /* tunnel flags */ --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h -@@ -554,4 +554,9 @@ static inline void ip_tunnel_info_opts_s - +@@ -553,4 +553,9 @@ static inline void ip_tunnel_info_opts_s + #endif /* CONFIG_INET */ - + +/* QCA NSS Clients Support - Start */ +void ipip6_update_offload_stats(struct net_device *dev, void *ptr); +void ip6_update_offload_stats(struct net_device *dev, void *ptr); @@ -25,7 +25,7 @@ @@ -2398,6 +2398,26 @@ nla_put_failure: return -EMSGSIZE; } - + +/* QCA NSS Client Support - Start */ +/* + * Update offload stats @@ -54,7 +54,7 @@ @@ -1733,6 +1733,23 @@ nla_put_failure: return -EMSGSIZE; } - + +/* QCA NSS Clients Support - Start */ +void ipip6_update_offload_stats(struct net_device *dev, void *ptr) +{ diff --git a/target/linux/qualcommax/patches-6.1/0603-5-qca-nss-clients-add-vxlan-support.patch b/target/linux/qualcommax/patches-6.1/0603-5-qca-nss-clients-add-vxlan-support.patch index 8fdea03563b841..8c14040bb5d76a 100644 --- a/target/linux/qualcommax/patches-6.1/0603-5-qca-nss-clients-add-vxlan-support.patch +++ b/target/linux/qualcommax/patches-6.1/0603-5-qca-nss-clients-add-vxlan-support.patch @@ -61,7 +61,7 @@ /* caller should hold vxlan->hash_lock */ static struct vxlan_rdst *vxlan_fdb_find_rdst(struct vxlan_fdb *f, union vxlan_addr *ip, __be16 port, -@@ -2607,6 +2638,9 @@ static void vxlan_xmit_one(struct sk_buf +@@ -2654,6 +2685,9 @@ static void vxlan_xmit_one(struct sk_buf goto out_unlock; } @@ -71,7 +71,7 @@ tos = ip_tunnel_ecn_encap(tos, old_iph, skb); ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr), -@@ -2677,7 +2711,10 @@ static void vxlan_xmit_one(struct sk_buf +@@ -2725,7 +2759,10 @@ static void vxlan_xmit_one(struct sk_buf if (err < 0) goto tx_error; diff --git a/target/linux/qualcommax/patches-6.1/0604-qca-add-mcs-support.patch b/target/linux/qualcommax/patches-6.1/0604-qca-add-mcs-support.patch index 6c4f44374471d4..c8ad52104b75ee 100644 --- a/target/linux/qualcommax/patches-6.1/0604-qca-add-mcs-support.patch +++ b/target/linux/qualcommax/patches-6.1/0604-qca-add-mcs-support.patch @@ -3,7 +3,7 @@ @@ -256,4 +256,17 @@ extern br_get_dst_hook_t __rcu *br_get_d extern struct net_device *br_fdb_bridge_dev_get_and_hold(struct net_bridge *br); /* QCA NSS bridge-mgr support - End */ - + +/* QCA qca-mcs support - Start */ +typedef struct net_bridge_port *br_get_dst_hook_t(const struct net_bridge_port *src, + struct sk_buff **skb); @@ -35,19 +35,19 @@ return fdb_find_rcu(&br->fdb_hash_tbl, addr, vid); } +EXPORT_SYMBOL_GPL(br_fdb_find_rcu); /* QCA qca-mcs support */ - + /* When a static FDB entry is added, the mac address from the entry is * added to the bridge private HW address list and all required ports --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -853,6 +853,7 @@ void br_manage_promisc(struct net_bridge int nbp_backup_change(struct net_bridge_port *p, struct net_device *backup_dev); - + /* br_input.c */ +int br_pass_frame_up(struct sk_buff *skb); /* QCA qca-mcs support */ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb); rx_handler_func_t *br_get_rx_handler(const struct net_device *dev); - + @@ -2177,4 +2178,14 @@ struct nd_msg *br_is_nd_neigh_msg(struct #define __br_get(__hook, __default, __args ...) \ (__hook ? (__hook(__args)) : (__default)) @@ -78,7 +78,7 @@ @@ -463,6 +463,12 @@ static void __exit br_deinit(void) br_fdb_fini(); } - + +/* QCA qca-mcs support - Start */ +/* Hook for bridge event notifications */ +br_notify_hook_t __rcu *br_notify_hook __read_mostly; @@ -108,7 +108,7 @@ @@ -23,6 +23,16 @@ #include "br_private.h" #include "br_private_tunnel.h" - + +/* QCA qca-mcs support - Start */ +/* Hook for external Multicast handler */ +br_multicast_handle_hook_t __rcu *br_multicast_handle_hook __read_mostly; @@ -125,7 +125,7 @@ @@ -30,7 +40,7 @@ br_netif_receive_skb(struct net *net, st return netif_receive_skb(skb); } - + -static int br_pass_frame_up(struct sk_buff *skb) +int br_pass_frame_up(struct sk_buff *skb) { @@ -136,7 +136,7 @@ br_netif_receive_skb); } +EXPORT_SYMBOL_GPL(br_pass_frame_up); /* QCA qca-mcs support */ - + /* note: already called with rcu_read_lock */ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb) @@ -84,6 +95,11 @@ int br_handle_frame_finish(struct net *n @@ -148,11 +148,11 @@ + struct net_bridge_port *pdst = NULL; + br_get_dst_hook_t *get_dst_hook = rcu_dereference(br_get_dst_hook); + /* QCA qca-mcs support - End */ - + if (!p) goto drop; @@ -158,6 +174,11 @@ int br_handle_frame_finish(struct net *n - + switch (pkt_type) { case BR_PKT_MULTICAST: + /* QCA qca-mcs support - Start */ @@ -296,7 +296,7 @@ @@ -113,6 +113,15 @@ static void igmpmsg_netlink_event(const static void mroute_clean_tables(struct mr_table *mrt, int flags); static void ipmr_expire_process(struct timer_list *t); - + +/* QCA ECM qca-mcs support - Start */ +/* spinlock for offload */ +static DEFINE_SPINLOCK(lock); @@ -312,7 +312,7 @@ @@ -223,6 +232,228 @@ static int ipmr_rule_fill(struct fib_rul return 0; } - + +/* QCA ECM qca-mcs support - Start */ +/* ipmr_sync_entry_update() + * Call the registered offload callback to report an update to a multicast @@ -541,7 +541,7 @@ @@ -1193,6 +1424,11 @@ static int ipmr_mfc_delete(struct mr_tab mroute_netlink_event(mrt, c, RTM_DELROUTE); mr_cache_put(&c->_c); - + + /* QCA ECM qca-mcs support - Start */ + /* Inform offload modules of the delete event */ + ipmr_sync_entry_delete(c->mfc_origin, c->mfc_mcastgrp); @@ -549,7 +549,7 @@ + return 0; } - + @@ -1222,6 +1458,12 @@ static int ipmr_mfc_add(struct net *net, call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_REPLACE, c, mrt->id); @@ -562,7 +562,7 @@ + return 0; } - + @@ -1282,6 +1524,7 @@ static void mroute_clean_tables(struct m struct net *net = read_pnet(&mrt->net); struct mr_mfc *c, *tmp; @@ -570,7 +570,7 @@ + u32 origin, group; /* QCA ECM qca-mcs support */ LIST_HEAD(list); int i; - + @@ -1306,10 +1549,19 @@ static void mroute_clean_tables(struct m rhltable_remove(&mrt->mfc_hash, &c->mnode, ipmr_rht_params); list_del_rcu(&c->list); @@ -590,13 +590,13 @@ + /* QCA ECM qca-mcs support - End */ } } - + --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -102,6 +102,17 @@ static int ip6mr_rtm_dumproute(struct sk static void mroute_clean_tables(struct mr_table *mrt, int flags); static void ipmr_expire_process(struct timer_list *t); - + +/* QCA qca-mcs support - Start */ +/* Spinlock for offload */ +static DEFINE_SPINLOCK(lock); @@ -614,7 +614,7 @@ @@ -380,6 +391,227 @@ static struct mr_table_ops ip6mr_mr_tabl .cmparg_any = &ip6mr_mr_table_ops_cmparg_any, }; - + +/* QCA qca-mcs support - Start */ +/* ip6mr_sync_entry_update() + * Call the registered offload callback to report an update to a multicast @@ -844,7 +844,7 @@ { struct mfc6_cache *c; + struct in6_addr mc_origin, mc_group; /* QCA qca-mcs support */ - + /* The entries are added/deleted only under RTNL */ rcu_read_lock(); @@ -1229,6 +1462,12 @@ static int ip6mr_mfc_delete(struct mr_ta @@ -859,7 +859,7 @@ + rhltable_remove(&mrt->mfc_hash, &c->_c.mnode, ip6mr_rht_params); list_del_rcu(&c->_c.list); - + @@ -1236,6 +1475,12 @@ static int ip6mr_mfc_delete(struct mr_ta FIB_EVENT_ENTRY_DEL, c, mrt->id); mr6_netlink_event(mrt, c, RTM_DELROUTE); @@ -872,7 +872,7 @@ + return 0; } - + @@ -1457,6 +1702,12 @@ static int ip6mr_mfc_add(struct net *net call_ip6mr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_REPLACE, c, mrt->id); @@ -885,9 +885,9 @@ + return 0; } - + @@ -1519,6 +1770,10 @@ static int ip6mr_mfc_add(struct net *net - + static void mroute_clean_tables(struct mr_table *mrt, int flags) { + /* QCA qca-mcs support - Start */ @@ -922,3 +922,4 @@ + /* QCA qca-mcs support - End */ } } + diff --git a/target/linux/qualcommax/patches-6.1/0605-qca-nss-cfi-support.patch b/target/linux/qualcommax/patches-6.1/0605-qca-nss-cfi-support.patch index a92092d601bdbc..67e85a18faec5c 100644 --- a/target/linux/qualcommax/patches-6.1/0605-qca-nss-cfi-support.patch +++ b/target/linux/qualcommax/patches-6.1/0605-qca-nss-cfi-support.patch @@ -45,7 +45,7 @@ esp.tfclen = 0; if (x->tfcpad) { struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb); -@@ -888,6 +894,7 @@ static int esp_input(struct xfrm_state * +@@ -890,6 +896,7 @@ static int esp_input(struct xfrm_state * u8 *iv; struct scatterlist *sg; int err = -EINVAL; @@ -53,7 +53,7 @@ if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr) + ivlen)) goto out; -@@ -895,6 +902,12 @@ static int esp_input(struct xfrm_state * +@@ -897,6 +904,12 @@ static int esp_input(struct xfrm_state * if (elen <= 0) goto out; @@ -88,7 +88,7 @@ esp.tfclen = 0; if (x->tfcpad) { struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb); -@@ -932,6 +938,7 @@ static int esp6_input(struct xfrm_state +@@ -934,6 +940,7 @@ static int esp6_input(struct xfrm_state __be32 *seqhi; u8 *iv; struct scatterlist *sg; @@ -96,7 +96,7 @@ if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr) + ivlen)) { ret = -EINVAL; -@@ -943,6 +950,12 @@ static int esp6_input(struct xfrm_state +@@ -945,6 +952,12 @@ static int esp6_input(struct xfrm_state goto out; } From 9f60f10b6f05ac801deeacb8d9ea101aade068f6 Mon Sep 17 00:00:00 2001 From: bitthief Date: Thu, 9 Nov 2023 03:44:34 +0200 Subject: [PATCH 043/225] hostapd: update to latest HEAD Reference: https: //github.com/openwrt/openwrt/pull/13911 Signed-off-by: bitthief --- package/network/services/hostapd/Makefile | 6 +-- ...ix-sta-add-after-previous-connection.patch | 4 +- ...ewrite-neigh-code-to-not-depend-on-l.patch | 6 +-- ...edtls-TLS-crypto-option-initial-port.patch | 2 +- ...efile-make-run-tests-with-CONFIG_TLS.patch | 44 +++++++++---------- ...ix-setting-QoS-map-on-secondary-BSSs.patch | 20 --------- .../hostapd/patches/200-multicall.patch | 18 ++++---- .../services/hostapd/patches/300-noscan.patch | 4 +- .../341-mesh-ctrl-iface-channel-switch.patch | 2 +- .../patches/380-disable_ctrl_iface_mib.patch | 16 +++---- ...dd-new-config-params-to-be-used-with.patch | 2 +- .../patches/463-add-mcast_rate-to-11s.patch | 6 +-- ...tapd-config-support-random-BSS-color.patch | 2 +- .../hostapd/patches/600-ubus_support.patch | 14 +++--- .../hostapd/patches/601-ucode_support.patch | 28 ++++++------ .../patches/701-reload_config_inline.patch | 2 +- .../hostapd/patches/710-vlan_no_bridge.patch | 2 +- .../patches/720-iface_max_num_sta.patch | 6 +-- .../hostapd/patches/730-ft_iface.patch | 4 +- .../hostapd/patches/740-snoop_iface.patch | 6 +-- ...750-qos_map_set_without_interworking.patch | 8 ++-- .../hostapd/patches/760-dynamic_own_ip.patch | 2 +- ..._AP-functions-dependant-on-CONFIG_AP.patch | 4 +- ...-extra-ies-only-if-allowed-by-driver.patch | 4 +- 24 files changed, 96 insertions(+), 116 deletions(-) delete mode 100644 package/network/services/hostapd/patches/180-driver_nl80211-fix-setting-QoS-map-on-secondary-BSSs.patch diff --git a/package/network/services/hostapd/Makefile b/package/network/services/hostapd/Makefile index 17f9dcb581dbea..8766d547e64457 100644 --- a/package/network/services/hostapd/Makefile +++ b/package/network/services/hostapd/Makefile @@ -9,9 +9,9 @@ PKG_RELEASE:=6 PKG_SOURCE_URL:=http://w1.fi/hostap.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2023-09-08 -PKG_SOURCE_VERSION:=e5ccbfc69ecf297590341ae8b461edba9d8e964c -PKG_MIRROR_HASH:=fcc6550f46c7f8bbdbf71e63f8f699b9a0878565ad1b90a17855f5ec21283b8f +PKG_SOURCE_DATE:=2023-10-31 +PKG_SOURCE_VERSION:=ddf026b1c6e825e99a931b9769045f50afa198ab +PKG_MIRROR_HASH:=41e402c2a5806adec33d782e9d3552aeb1b28d094efb463b3d72f1fc0f8c3aa6 PKG_MAINTAINER:=Felix Fietkau PKG_LICENSE:=BSD-3-Clause diff --git a/package/network/services/hostapd/patches/021-fix-sta-add-after-previous-connection.patch b/package/network/services/hostapd/patches/021-fix-sta-add-after-previous-connection.patch index edf599e3e282f3..227c580552d479 100644 --- a/package/network/services/hostapd/patches/021-fix-sta-add-after-previous-connection.patch +++ b/package/network/services/hostapd/patches/021-fix-sta-add-after-previous-connection.patch @@ -1,6 +1,6 @@ --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c -@@ -4621,6 +4621,13 @@ static int add_associated_sta(struct hos +@@ -4616,6 +4616,13 @@ static int add_associated_sta(struct hos * drivers to accept the STA parameter configuration. Since this is * after a new FT-over-DS exchange, a new TK has been derived, so key * reinstallation is not a concern for this case. @@ -14,7 +14,7 @@ */ wpa_printf(MSG_DEBUG, "Add associated STA " MACSTR " (added_unassoc=%d auth_alg=%u ft_over_ds=%u reassoc=%d authorized=%d ft_tk=%d fils_tk=%d)", -@@ -4634,7 +4641,8 @@ static int add_associated_sta(struct hos +@@ -4629,7 +4636,8 @@ static int add_associated_sta(struct hos (!(sta->flags & WLAN_STA_AUTHORIZED) || (reassoc && sta->ft_over_ds && sta->auth_alg == WLAN_AUTH_FT) || (!wpa_auth_sta_ft_tk_already_set(sta->wpa_sm) && diff --git a/package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch b/package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch index ef2bb408fb28d9..ba1f6e6c23c8cd 100644 --- a/package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch +++ b/package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch @@ -92,7 +92,7 @@ Signed-off-by: Felix Fietkau if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) { wpa_printf(MSG_DEBUG, -@@ -11883,13 +11880,14 @@ static int wpa_driver_br_add_ip_neigh(vo +@@ -11893,13 +11890,14 @@ static int wpa_driver_br_add_ip_neigh(vo const u8 *ipaddr, int prefixlen, const u8 *addr) { @@ -112,7 +112,7 @@ Signed-off-by: Felix Fietkau int res; if (!ipaddr || prefixlen == 0 || !addr) -@@ -11908,85 +11906,66 @@ static int wpa_driver_br_add_ip_neigh(vo +@@ -11918,85 +11916,66 @@ static int wpa_driver_br_add_ip_neigh(vo } if (version == 4) { @@ -220,7 +220,7 @@ Signed-off-by: Felix Fietkau addrsize = 16; } else { return -EINVAL; -@@ -12004,41 +11983,30 @@ static int wpa_driver_br_delete_ip_neigh +@@ -12014,41 +11993,30 @@ static int wpa_driver_br_delete_ip_neigh return -1; } diff --git a/package/network/services/hostapd/patches/110-mbedtls-TLS-crypto-option-initial-port.patch b/package/network/services/hostapd/patches/110-mbedtls-TLS-crypto-option-initial-port.patch index 22107944dce7d5..1d14a8f715ed4a 100644 --- a/package/network/services/hostapd/patches/110-mbedtls-TLS-crypto-option-initial-port.patch +++ b/package/network/services/hostapd/patches/110-mbedtls-TLS-crypto-option-initial-port.patch @@ -8041,7 +8041,7 @@ Signed-off-by: Glenn Strauss # Driver interface for generic Linux wireless extensions # Note: WEXT is deprecated in the current Linux kernel version and no new # functionality is added to it. nl80211-based interface is the new -@@ -326,6 +327,7 @@ CONFIG_BACKEND=file +@@ -329,6 +330,7 @@ CONFIG_BACKEND=file # openssl = OpenSSL (default) # gnutls = GnuTLS # internal = Internal TLSv1 implementation (experimental) diff --git a/package/network/services/hostapd/patches/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch b/package/network/services/hostapd/patches/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch index e967cff427e177..e96083c5435b74 100644 --- a/package/network/services/hostapd/patches/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch +++ b/package/network/services/hostapd/patches/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch @@ -727,7 +727,7 @@ Signed-off-by: Glenn Strauss def check_ec_support(dev): tls = dev.request("GET tls_library") -@@ -1595,7 +1638,7 @@ def test_ap_wpa2_eap_ttls_pap_subject_ma +@@ -1712,7 +1755,7 @@ def test_ap_wpa2_eap_ttls_pap_subject_ma eap_connect(dev[0], hapd, "TTLS", "pap user", anonymous_identity="ttls", password="password", ca_cert="auth_serv/ca.pem", phase2="auth=PAP", @@ -736,7 +736,7 @@ Signed-off-by: Glenn Strauss altsubject_match="EMAIL:noone@example.com;DNS:server.w1.fi;URI:http://example.com/") eap_reauth(dev[0], "TTLS") -@@ -2830,6 +2873,7 @@ def test_ap_wpa2_eap_tls_neg_domain_matc +@@ -2947,6 +2990,7 @@ def test_ap_wpa2_eap_tls_neg_domain_matc def test_ap_wpa2_eap_tls_neg_subject_match(dev, apdev): """WPA2-Enterprise negative test - subject mismatch""" @@ -744,7 +744,7 @@ Signed-off-by: Glenn Strauss params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") hostapd.add_ap(apdev[0], params) dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", -@@ -2890,6 +2934,7 @@ def test_ap_wpa2_eap_tls_neg_subject_mat +@@ -3007,6 +3051,7 @@ def test_ap_wpa2_eap_tls_neg_subject_mat def test_ap_wpa2_eap_tls_neg_altsubject_match(dev, apdev): """WPA2-Enterprise negative test - altsubject mismatch""" @@ -752,7 +752,7 @@ Signed-off-by: Glenn Strauss params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") hostapd.add_ap(apdev[0], params) -@@ -3430,7 +3475,7 @@ def test_ap_wpa2_eap_ikev2_oom(dev, apde +@@ -3547,7 +3592,7 @@ def test_ap_wpa2_eap_ikev2_oom(dev, apde dev[0].request("REMOVE_NETWORK all") tls = dev[0].request("GET tls_library") @@ -761,7 +761,7 @@ Signed-off-by: Glenn Strauss tests = [(1, "os_get_random;dh_init")] else: tests = [(1, "crypto_dh_init;dh_init")] -@@ -4744,7 +4789,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca +@@ -4861,7 +4906,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca params["private_key"] = "auth_serv/iCA-server/server.key" hostapd.add_ap(apdev[0], params) tls = dev[0].request("GET tls_library") @@ -770,7 +770,7 @@ Signed-off-by: Glenn Strauss ca_cert = "auth_serv/iCA-user/ca-and-root.pem" client_cert = "auth_serv/iCA-user/user_and_ica.pem" else: -@@ -4810,6 +4855,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca +@@ -4927,6 +4972,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca run_ap_wpa2_eap_tls_intermediate_ca_ocsp(dev, apdev, params, "-sha1") def run_ap_wpa2_eap_tls_intermediate_ca_ocsp(dev, apdev, params, md): @@ -778,7 +778,7 @@ Signed-off-by: Glenn Strauss params = int_eap_server_params() params["ca_cert"] = "auth_serv/iCA-server/ca-and-root.pem" params["server_cert"] = "auth_serv/iCA-server/server.pem" -@@ -4819,7 +4865,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ +@@ -4936,7 +4982,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ try: hostapd.add_ap(apdev[0], params) tls = dev[0].request("GET tls_library") @@ -787,7 +787,7 @@ Signed-off-by: Glenn Strauss ca_cert = "auth_serv/iCA-user/ca-and-root.pem" client_cert = "auth_serv/iCA-user/user_and_ica.pem" else: -@@ -4855,7 +4901,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ +@@ -4972,7 +5018,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ try: hostapd.add_ap(apdev[0], params) tls = dev[0].request("GET tls_library") @@ -796,7 +796,7 @@ Signed-off-by: Glenn Strauss ca_cert = "auth_serv/iCA-user/ca-and-root.pem" client_cert = "auth_serv/iCA-user/user_and_ica.pem" else: -@@ -4905,7 +4951,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca +@@ -5022,7 +5068,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca try: hostapd.add_ap(apdev[0], params) tls = dev[0].request("GET tls_library") @@ -805,7 +805,7 @@ Signed-off-by: Glenn Strauss ca_cert = "auth_serv/iCA-user/ca-and-root.pem" client_cert = "auth_serv/iCA-user/user_and_ica.pem" else: -@@ -4972,7 +5018,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca +@@ -5089,7 +5135,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca hostapd.add_ap(apdev[0], params) tls = dev[0].request("GET tls_library") @@ -814,7 +814,7 @@ Signed-off-by: Glenn Strauss ca_cert = "auth_serv/iCA-user/ca-and-root.pem" client_cert = "auth_serv/iCA-user/user_and_ica.pem" else: -@@ -5230,6 +5276,7 @@ def test_ap_wpa2_eap_ttls_server_cert_ek +@@ -5347,6 +5393,7 @@ def test_ap_wpa2_eap_ttls_server_cert_ek def test_ap_wpa2_eap_ttls_server_pkcs12(dev, apdev): """WPA2-Enterprise using EAP-TTLS and server PKCS#12 file""" @@ -822,7 +822,7 @@ Signed-off-by: Glenn Strauss skip_with_fips(dev[0]) params = int_eap_server_params() del params["server_cert"] -@@ -5242,6 +5289,7 @@ def test_ap_wpa2_eap_ttls_server_pkcs12( +@@ -5359,6 +5406,7 @@ def test_ap_wpa2_eap_ttls_server_pkcs12( def test_ap_wpa2_eap_ttls_server_pkcs12_extra(dev, apdev): """EAP-TTLS and server PKCS#12 file with extra certs""" @@ -830,7 +830,7 @@ Signed-off-by: Glenn Strauss skip_with_fips(dev[0]) params = int_eap_server_params() del params["server_cert"] -@@ -5264,6 +5312,7 @@ def test_ap_wpa2_eap_ttls_dh_params_serv +@@ -5381,6 +5429,7 @@ def test_ap_wpa2_eap_ttls_dh_params_serv def test_ap_wpa2_eap_ttls_dh_params_dsa_server(dev, apdev): """WPA2-Enterprise using EAP-TTLS and alternative server dhparams (DSA)""" @@ -838,7 +838,7 @@ Signed-off-by: Glenn Strauss params = int_eap_server_params() params["dh_file"] = "auth_serv/dsaparam.pem" hapd = hostapd.add_ap(apdev[0], params) -@@ -5575,8 +5624,8 @@ def test_ap_wpa2_eap_non_ascii_identity2 +@@ -5692,8 +5741,8 @@ def test_ap_wpa2_eap_non_ascii_identity2 def test_openssl_cipher_suite_config_wpas(dev, apdev): """OpenSSL cipher suite configuration on wpa_supplicant""" tls = dev[0].request("GET tls_library") @@ -849,7 +849,7 @@ Signed-off-by: Glenn Strauss params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") hapd = hostapd.add_ap(apdev[0], params) eap_connect(dev[0], hapd, "TTLS", "pap user", -@@ -5602,14 +5651,14 @@ def test_openssl_cipher_suite_config_wpa +@@ -5719,14 +5768,14 @@ def test_openssl_cipher_suite_config_wpa def test_openssl_cipher_suite_config_hapd(dev, apdev): """OpenSSL cipher suite configuration on hostapd""" tls = dev[0].request("GET tls_library") @@ -868,7 +868,7 @@ Signed-off-by: Glenn Strauss eap_connect(dev[0], hapd, "TTLS", "pap user", anonymous_identity="ttls", password="password", ca_cert="auth_serv/ca.pem", phase2="auth=PAP") -@@ -6051,13 +6100,17 @@ def test_ap_wpa2_eap_tls_versions(dev, a +@@ -6168,13 +6217,17 @@ def test_ap_wpa2_eap_tls_versions(dev, a check_tls_ver(dev[0], hapd, "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1", "TLSv1.2") @@ -891,7 +891,7 @@ Signed-off-by: Glenn Strauss if "run=OpenSSL 1.1.1" in tls or "run=OpenSSL 3.0" in tls: check_tls_ver(dev[0], hapd, "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1 tls_disable_tlsv1_3=0", "TLSv1.3") -@@ -6079,6 +6132,11 @@ def test_ap_wpa2_eap_tls_versions_server +@@ -6196,6 +6249,11 @@ def test_ap_wpa2_eap_tls_versions_server tests = [("TLSv1", "[ENABLE-TLSv1.0][DISABLE-TLSv1.1][DISABLE-TLSv1.2][DISABLE-TLSv1.3]"), ("TLSv1.1", "[ENABLE-TLSv1.0][ENABLE-TLSv1.1][DISABLE-TLSv1.2][DISABLE-TLSv1.3]"), ("TLSv1.2", "[ENABLE-TLSv1.0][ENABLE-TLSv1.1][ENABLE-TLSv1.2][DISABLE-TLSv1.3]")] @@ -903,7 +903,7 @@ Signed-off-by: Glenn Strauss for exp, flags in tests: hapd.disable() hapd.set("tls_flags", flags) -@@ -7138,6 +7196,7 @@ def test_ap_wpa2_eap_assoc_rsn(dev, apde +@@ -7255,6 +7313,7 @@ def test_ap_wpa2_eap_assoc_rsn(dev, apde def test_eap_tls_ext_cert_check(dev, apdev): """EAP-TLS and external server certification validation""" # With internal server certificate chain validation @@ -911,7 +911,7 @@ Signed-off-by: Glenn Strauss id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TLS", identity="tls user", ca_cert="auth_serv/ca.pem", -@@ -7150,6 +7209,7 @@ def test_eap_tls_ext_cert_check(dev, apd +@@ -7267,6 +7326,7 @@ def test_eap_tls_ext_cert_check(dev, apd def test_eap_ttls_ext_cert_check(dev, apdev): """EAP-TTLS and external server certification validation""" # Without internal server certificate chain validation @@ -919,7 +919,7 @@ Signed-off-by: Glenn Strauss id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", identity="pap user", anonymous_identity="ttls", password="password", phase2="auth=PAP", -@@ -7160,6 +7220,7 @@ def test_eap_ttls_ext_cert_check(dev, ap +@@ -7277,6 +7337,7 @@ def test_eap_ttls_ext_cert_check(dev, ap def test_eap_peap_ext_cert_check(dev, apdev): """EAP-PEAP and external server certification validation""" # With internal server certificate chain validation @@ -927,7 +927,7 @@ Signed-off-by: Glenn Strauss id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="PEAP", identity="user", anonymous_identity="peap", ca_cert="auth_serv/ca.pem", -@@ -7170,6 +7231,7 @@ def test_eap_peap_ext_cert_check(dev, ap +@@ -7287,6 +7348,7 @@ def test_eap_peap_ext_cert_check(dev, ap def test_eap_fast_ext_cert_check(dev, apdev): """EAP-FAST and external server certification validation""" @@ -935,7 +935,7 @@ Signed-off-by: Glenn Strauss check_eap_capa(dev[0], "FAST") # With internal server certificate chain validation dev[0].request("SET blob fast_pac_auth_ext ") -@@ -7184,10 +7246,6 @@ def test_eap_fast_ext_cert_check(dev, ap +@@ -7301,10 +7363,6 @@ def test_eap_fast_ext_cert_check(dev, ap run_ext_cert_check(dev, apdev, id) def run_ext_cert_check(dev, apdev, net_id): diff --git a/package/network/services/hostapd/patches/180-driver_nl80211-fix-setting-QoS-map-on-secondary-BSSs.patch b/package/network/services/hostapd/patches/180-driver_nl80211-fix-setting-QoS-map-on-secondary-BSSs.patch deleted file mode 100644 index 4929c581ce2bde..00000000000000 --- a/package/network/services/hostapd/patches/180-driver_nl80211-fix-setting-QoS-map-on-secondary-BSSs.patch +++ /dev/null @@ -1,20 +0,0 @@ -From: Felix Fietkau -Date: Thu, 14 Sep 2023 10:53:50 +0200 -Subject: [PATCH] driver_nl80211: fix setting QoS map on secondary BSSs - -The setting is per-BSS, not per PHY - -Signed-off-by: Felix Fietkau ---- - ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -11341,7 +11341,7 @@ static int nl80211_set_qos_map(void *pri - wpa_hexdump(MSG_DEBUG, "nl80211: Setting QoS Map", - qos_map_set, qos_map_set_len); - -- if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_QOS_MAP)) || -+ if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_QOS_MAP)) || - nla_put(msg, NL80211_ATTR_QOS_MAP, qos_map_set_len, qos_map_set)) { - nlmsg_free(msg); - return -ENOBUFS; diff --git a/package/network/services/hostapd/patches/200-multicall.patch b/package/network/services/hostapd/patches/200-multicall.patch index e3ed00f2ded2a4..8f54a8d3544718 100644 --- a/package/network/services/hostapd/patches/200-multicall.patch +++ b/package/network/services/hostapd/patches/200-multicall.patch @@ -156,7 +156,7 @@ wpa_cli.exe: wpa_cli --- a/src/drivers/driver.h +++ b/src/drivers/driver.h -@@ -6667,8 +6667,8 @@ union wpa_event_data { +@@ -6676,8 +6676,8 @@ union wpa_event_data { * Driver wrapper code should call this function whenever an event is received * from the driver. */ @@ -167,7 +167,7 @@ /** * wpa_supplicant_event_global - Report a driver event for wpa_supplicant -@@ -6680,7 +6680,7 @@ void wpa_supplicant_event(void *ctx, enu +@@ -6689,7 +6689,7 @@ void wpa_supplicant_event(void *ctx, enu * Same as wpa_supplicant_event(), but we search for the interface in * wpa_global. */ @@ -178,7 +178,7 @@ /* --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c -@@ -2184,8 +2184,8 @@ err: +@@ -2182,8 +2182,8 @@ err: #endif /* CONFIG_OWE */ @@ -189,7 +189,7 @@ { struct hostapd_data *hapd = ctx; #ifndef CONFIG_NO_STDOUT_DEBUG -@@ -2489,7 +2489,7 @@ void wpa_supplicant_event(void *ctx, enu +@@ -2487,7 +2487,7 @@ void wpa_supplicant_event(void *ctx, enu } @@ -231,7 +231,7 @@ os_memset(&global, 0, sizeof(global)); --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c -@@ -5353,8 +5353,8 @@ static void wpas_link_reconfig(struct wp +@@ -5530,8 +5530,8 @@ static void wpas_link_reconfig(struct wp } @@ -242,7 +242,7 @@ { struct wpa_supplicant *wpa_s = ctx; int resched; -@@ -6272,7 +6272,7 @@ void wpa_supplicant_event(void *ctx, enu +@@ -6449,7 +6449,7 @@ void wpa_supplicant_event(void *ctx, enu } @@ -253,7 +253,7 @@ struct wpa_supplicant *wpa_s; --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c -@@ -7462,7 +7462,6 @@ struct wpa_interface * wpa_supplicant_ma +@@ -7469,7 +7469,6 @@ struct wpa_interface * wpa_supplicant_ma return NULL; } @@ -261,7 +261,7 @@ /** * wpa_supplicant_match_existing - Match existing interfaces * @global: Pointer to global data from wpa_supplicant_init() -@@ -7497,6 +7496,11 @@ static int wpa_supplicant_match_existing +@@ -7504,6 +7503,11 @@ static int wpa_supplicant_match_existing #endif /* CONFIG_MATCH_IFACE */ @@ -273,7 +273,7 @@ /** * wpa_supplicant_add_iface - Add a new network interface -@@ -7753,6 +7757,8 @@ struct wpa_global * wpa_supplicant_init( +@@ -7760,6 +7764,8 @@ struct wpa_global * wpa_supplicant_init( #ifndef CONFIG_NO_WPA_MSG wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb); #endif /* CONFIG_NO_WPA_MSG */ diff --git a/package/network/services/hostapd/patches/300-noscan.patch b/package/network/services/hostapd/patches/300-noscan.patch index 3b5f4325de0c96..9573916bb4dccf 100644 --- a/package/network/services/hostapd/patches/300-noscan.patch +++ b/package/network/services/hostapd/patches/300-noscan.patch @@ -1,6 +1,6 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -3448,6 +3448,10 @@ static int hostapd_config_fill(struct ho +@@ -3450,6 +3450,10 @@ static int hostapd_config_fill(struct ho if (bss->ocv && !bss->ieee80211w) bss->ieee80211w = 1; #endif /* CONFIG_OCV */ @@ -13,7 +13,7 @@ } else if (os_strcmp(buf, "ht_capab") == 0) { --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h -@@ -1075,6 +1075,8 @@ struct hostapd_config { +@@ -1076,6 +1076,8 @@ struct hostapd_config { int ht_op_mode_fixed; u16 ht_capab; diff --git a/package/network/services/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch b/package/network/services/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch index 8784452876b22e..2173f0eb686a05 100644 --- a/package/network/services/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch +++ b/package/network/services/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch @@ -1,6 +1,6 @@ --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c -@@ -1825,15 +1825,35 @@ int ap_switch_channel(struct wpa_supplic +@@ -1837,15 +1837,35 @@ int ap_switch_channel(struct wpa_supplic #ifdef CONFIG_CTRL_IFACE diff --git a/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch b/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch index f7720fce2fac84..6d43f169e5a50a 100644 --- a/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch +++ b/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch @@ -51,7 +51,7 @@ if (wpa_s->ap_iface) { pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos, end - pos, -@@ -12087,6 +12087,7 @@ char * wpa_supplicant_ctrl_iface_process +@@ -12162,6 +12162,7 @@ char * wpa_supplicant_ctrl_iface_process reply_len = -1; } else if (os_strncmp(buf, "NOTE ", 5) == 0) { wpa_printf(MSG_INFO, "NOTE: %s", buf + 5); @@ -59,7 +59,7 @@ } else if (os_strcmp(buf, "MIB") == 0) { reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size); if (reply_len >= 0) { -@@ -12099,6 +12100,7 @@ char * wpa_supplicant_ctrl_iface_process +@@ -12174,6 +12175,7 @@ char * wpa_supplicant_ctrl_iface_process reply_size - reply_len); #endif /* CONFIG_MACSEC */ } @@ -67,7 +67,7 @@ } else if (os_strncmp(buf, "STATUS", 6) == 0) { reply_len = wpa_supplicant_ctrl_iface_status( wpa_s, buf + 6, reply, reply_size); -@@ -12587,6 +12589,7 @@ char * wpa_supplicant_ctrl_iface_process +@@ -12662,6 +12664,7 @@ char * wpa_supplicant_ctrl_iface_process reply_len = wpa_supplicant_ctrl_iface_bss( wpa_s, buf + 4, reply, reply_size); #ifdef CONFIG_AP @@ -75,7 +75,7 @@ } else if (os_strcmp(buf, "STA-FIRST") == 0) { reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size); } else if (os_strncmp(buf, "STA ", 4) == 0) { -@@ -12595,12 +12598,15 @@ char * wpa_supplicant_ctrl_iface_process +@@ -12670,12 +12673,15 @@ char * wpa_supplicant_ctrl_iface_process } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply, reply_size); @@ -155,7 +155,7 @@ #ifdef CONFIG_P2P_MANAGER static int p2p_manager_disconnect(struct hostapd_data *hapd, u16 stype, -@@ -884,12 +885,12 @@ int hostapd_ctrl_iface_status(struct hos +@@ -894,12 +895,12 @@ int hostapd_ctrl_iface_status(struct hos return len; len += ret; } @@ -190,7 +190,7 @@ static void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx) --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c -@@ -5328,6 +5328,7 @@ static const char * wpa_bool_txt(int val +@@ -5342,6 +5342,7 @@ static const char * wpa_bool_txt(int val return val ? "TRUE" : "FALSE"; } @@ -198,7 +198,7 @@ #define RSN_SUITE "%02x-%02x-%02x-%d" #define RSN_SUITE_ARG(s) \ -@@ -5480,7 +5481,7 @@ int wpa_get_mib_sta(struct wpa_state_mac +@@ -5494,7 +5495,7 @@ int wpa_get_mib_sta(struct wpa_state_mac return len; } @@ -228,7 +228,7 @@ --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c -@@ -1499,7 +1499,7 @@ int wpas_ap_wps_nfc_report_handover(stru +@@ -1511,7 +1511,7 @@ int wpas_ap_wps_nfc_report_handover(stru #endif /* CONFIG_WPS */ diff --git a/package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch b/package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch index dc19553e26ea87..8084b593dcd049 100644 --- a/package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch +++ b/package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch @@ -22,7 +22,7 @@ Signed-hostap: Antonio Quartulli #include "common/defs.h" #include "common/ieee802_11_defs.h" #include "common/wpa_common.h" -@@ -953,6 +954,9 @@ struct wpa_driver_associate_params { +@@ -960,6 +961,9 @@ struct wpa_driver_associate_params { * responsible for selecting with which BSS to associate. */ const u8 *bssid; diff --git a/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch b/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch index daa36c2f35cbb9..f46c95fab77935 100644 --- a/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch +++ b/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch @@ -19,7 +19,7 @@ Tested-by: Simon Wunderlich --- a/src/drivers/driver.h +++ b/src/drivers/driver.h -@@ -1827,6 +1827,7 @@ struct wpa_driver_mesh_join_params { +@@ -1834,6 +1834,7 @@ struct wpa_driver_mesh_join_params { #define WPA_DRIVER_MESH_FLAG_AMPE 0x00000008 unsigned int flags; bool handle_dfs; @@ -29,7 +29,7 @@ Tested-by: Simon Wunderlich struct wpa_driver_set_key_params { --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c -@@ -11667,6 +11667,18 @@ static int nl80211_put_mesh_id(struct nl +@@ -11677,6 +11677,18 @@ static int nl80211_put_mesh_id(struct nl } @@ -48,7 +48,7 @@ Tested-by: Simon Wunderlich static int nl80211_put_mesh_config(struct nl_msg *msg, struct wpa_driver_mesh_bss_params *params) { -@@ -11728,6 +11740,7 @@ static int nl80211_join_mesh(struct i802 +@@ -11738,6 +11750,7 @@ static int nl80211_join_mesh(struct i802 nl80211_put_basic_rates(msg, params->basic_rates) || nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) || nl80211_put_beacon_int(msg, params->beacon_int) || diff --git a/package/network/services/hostapd/patches/465-hostapd-config-support-random-BSS-color.patch b/package/network/services/hostapd/patches/465-hostapd-config-support-random-BSS-color.patch index 7d3d94648e1930..ec10db8ed1494b 100644 --- a/package/network/services/hostapd/patches/465-hostapd-config-support-random-BSS-color.patch +++ b/package/network/services/hostapd/patches/465-hostapd-config-support-random-BSS-color.patch @@ -13,7 +13,7 @@ Signed-off-by: David Bauer --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -3500,6 +3500,8 @@ static int hostapd_config_fill(struct ho +@@ -3502,6 +3502,8 @@ static int hostapd_config_fill(struct ho } else if (os_strcmp(buf, "he_bss_color") == 0) { conf->he_op.he_bss_color = atoi(pos) & 0x3f; conf->he_op.he_bss_color_disabled = 0; diff --git a/package/network/services/hostapd/patches/600-ubus_support.patch b/package/network/services/hostapd/patches/600-ubus_support.patch index a6ccf83331fe3e..10ca946050c72d 100644 --- a/package/network/services/hostapd/patches/600-ubus_support.patch +++ b/package/network/services/hostapd/patches/600-ubus_support.patch @@ -119,7 +119,7 @@ if (res == HOSTAPD_ACL_PENDING) return; -@@ -5161,7 +5173,7 @@ static void handle_assoc(struct hostapd_ +@@ -5156,7 +5168,7 @@ static void handle_assoc(struct hostapd_ int resp = WLAN_STATUS_SUCCESS; u16 reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE; const u8 *pos; @@ -173,7 +173,7 @@ wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR --- a/src/ap/beacon.c +++ b/src/ap/beacon.c -@@ -1036,6 +1036,12 @@ void handle_probe_req(struct hostapd_dat +@@ -1045,6 +1045,12 @@ void handle_probe_req(struct hostapd_dat u16 csa_offs[2]; size_t csa_offs_len; struct radius_sta rad_info; @@ -186,7 +186,7 @@ if (hapd->iconf->rssi_ignore_probe_request && ssi_signal && ssi_signal < hapd->iconf->rssi_ignore_probe_request) -@@ -1222,6 +1228,12 @@ void handle_probe_req(struct hostapd_dat +@@ -1231,6 +1237,12 @@ void handle_probe_req(struct hostapd_dat } #endif /* CONFIG_P2P */ @@ -212,7 +212,7 @@ if (addr == NULL) { /* -@@ -396,6 +400,12 @@ int hostapd_notif_assoc(struct hostapd_d +@@ -404,6 +408,12 @@ int hostapd_notif_assoc(struct hostapd_d goto fail; } @@ -348,7 +348,7 @@ CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c -@@ -7595,6 +7595,8 @@ struct wpa_supplicant * wpa_supplicant_a +@@ -7600,6 +7600,8 @@ struct wpa_supplicant * wpa_supplicant_a } #endif /* CONFIG_P2P */ @@ -357,7 +357,7 @@ return wpa_s; } -@@ -7621,6 +7623,8 @@ int wpa_supplicant_remove_iface(struct w +@@ -7626,6 +7628,8 @@ int wpa_supplicant_remove_iface(struct w struct wpa_supplicant *parent = wpa_s->parent; #endif /* CONFIG_MESH */ @@ -366,7 +366,7 @@ /* Remove interface from the global list of interfaces */ prev = global->ifaces; if (prev == wpa_s) { -@@ -7967,8 +7971,12 @@ int wpa_supplicant_run(struct wpa_global +@@ -7972,8 +7976,12 @@ int wpa_supplicant_run(struct wpa_global eloop_register_signal_terminate(wpa_supplicant_terminate, global); eloop_register_signal_reconfig(wpa_supplicant_reconfig, global); diff --git a/package/network/services/hostapd/patches/601-ucode_support.patch b/package/network/services/hostapd/patches/601-ucode_support.patch index cfdb51f356cc1b..1f2f3d5364a553 100644 --- a/package/network/services/hostapd/patches/601-ucode_support.patch +++ b/package/network/services/hostapd/patches/601-ucode_support.patch @@ -196,7 +196,7 @@ #ifdef CONFIG_BGSCAN if (state == WPA_COMPLETED && wpa_s->current_ssid != wpa_s->bgscan_ssid) -@@ -7594,6 +7595,7 @@ struct wpa_supplicant * wpa_supplicant_a +@@ -7601,6 +7602,7 @@ struct wpa_supplicant * wpa_supplicant_a #endif /* CONFIG_P2P */ wpas_ubus_add_bss(wpa_s); @@ -204,7 +204,7 @@ return wpa_s; } -@@ -7621,6 +7623,7 @@ int wpa_supplicant_remove_iface(struct w +@@ -7628,6 +7630,7 @@ int wpa_supplicant_remove_iface(struct w struct wpa_supplicant *parent = wpa_s->parent; #endif /* CONFIG_MESH */ @@ -212,7 +212,7 @@ wpas_ubus_free_bss(wpa_s); /* Remove interface from the global list of interfaces */ -@@ -7931,6 +7934,7 @@ struct wpa_global * wpa_supplicant_init( +@@ -7938,6 +7941,7 @@ struct wpa_global * wpa_supplicant_init( eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0, wpas_periodic, global, NULL); @@ -220,7 +220,7 @@ return global; } -@@ -7969,12 +7973,8 @@ int wpa_supplicant_run(struct wpa_global +@@ -7976,12 +7980,8 @@ int wpa_supplicant_run(struct wpa_global eloop_register_signal_terminate(wpa_supplicant_terminate, global); eloop_register_signal_reconfig(wpa_supplicant_reconfig, global); @@ -233,7 +233,7 @@ return 0; } -@@ -8007,6 +8007,8 @@ void wpa_supplicant_deinit(struct wpa_gl +@@ -8014,6 +8014,8 @@ void wpa_supplicant_deinit(struct wpa_gl wpas_notify_supplicant_deinitialized(global); @@ -280,7 +280,7 @@ --- a/src/drivers/driver.h +++ b/src/drivers/driver.h -@@ -3787,6 +3787,25 @@ struct wpa_driver_ops { +@@ -3796,6 +3796,25 @@ struct wpa_driver_ops { const char *ifname); /** @@ -306,7 +306,7 @@ * set_sta_vlan - Bind a station into a specific interface (AP only) * @priv: Private driver interface data * @ifname: Interface (main or virtual BSS or VLAN) -@@ -6440,6 +6459,7 @@ union wpa_event_data { +@@ -6449,6 +6468,7 @@ union wpa_event_data { /** * struct ch_switch @@ -314,7 +314,7 @@ * @freq: Frequency of new channel in MHz * @ht_enabled: Whether this is an HT channel * @ch_offset: Secondary channel offset -@@ -6450,6 +6470,7 @@ union wpa_event_data { +@@ -6459,6 +6479,7 @@ union wpa_event_data { * @punct_bitmap: Puncturing bitmap */ struct ch_switch { @@ -324,7 +324,7 @@ int ch_offset; --- a/src/drivers/driver_nl80211_event.c +++ b/src/drivers/driver_nl80211_event.c -@@ -1202,6 +1202,7 @@ static void mlme_event_ch_switch(struct +@@ -1203,6 +1203,7 @@ static void mlme_event_ch_switch(struct struct nlattr *bw, struct nlattr *cf1, struct nlattr *cf2, struct nlattr *punct_bitmap, @@ -332,7 +332,7 @@ int finished) { struct i802_bss *bss; -@@ -1265,6 +1266,8 @@ static void mlme_event_ch_switch(struct +@@ -1266,6 +1267,8 @@ static void mlme_event_ch_switch(struct data.ch_switch.cf1 = nla_get_u32(cf1); if (cf2) data.ch_switch.cf2 = nla_get_u32(cf2); @@ -341,7 +341,7 @@ if (finished) bss->flink->freq = data.ch_switch.freq; -@@ -3912,6 +3915,7 @@ static void do_process_drv_event(struct +@@ -3913,6 +3916,7 @@ static void do_process_drv_event(struct tb[NL80211_ATTR_CENTER_FREQ1], tb[NL80211_ATTR_CENTER_FREQ2], tb[NL80211_ATTR_PUNCT_BITMAP], @@ -349,7 +349,7 @@ 0); break; case NL80211_CMD_CH_SWITCH_NOTIFY: -@@ -3924,6 +3928,7 @@ static void do_process_drv_event(struct +@@ -3925,6 +3929,7 @@ static void do_process_drv_event(struct tb[NL80211_ATTR_CENTER_FREQ1], tb[NL80211_ATTR_CENTER_FREQ2], tb[NL80211_ATTR_PUNCT_BITMAP], @@ -359,7 +359,7 @@ case NL80211_CMD_DISCONNECT: --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c -@@ -5389,6 +5389,7 @@ void supplicant_event(void *ctx, enum wp +@@ -5566,6 +5566,7 @@ void supplicant_event(void *ctx, enum wp event_to_string(event), event); #endif /* CONFIG_NO_STDOUT_DEBUG */ @@ -611,7 +611,7 @@ static int driver_nl80211_send_mlme(void *priv, const u8 *data, size_t data_len, int noack, unsigned int freq, -@@ -13697,6 +13789,8 @@ const struct wpa_driver_ops wpa_driver_n +@@ -13707,6 +13779,8 @@ const struct wpa_driver_ops wpa_driver_n .set_acl = wpa_driver_nl80211_set_acl, .if_add = wpa_driver_nl80211_if_add, .if_remove = driver_nl80211_if_remove, diff --git a/package/network/services/hostapd/patches/701-reload_config_inline.patch b/package/network/services/hostapd/patches/701-reload_config_inline.patch index 3c62bf670f5bc5..e654f2f433194a 100644 --- a/package/network/services/hostapd/patches/701-reload_config_inline.patch +++ b/package/network/services/hostapd/patches/701-reload_config_inline.patch @@ -1,6 +1,6 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -4816,7 +4816,12 @@ struct hostapd_config * hostapd_config_r +@@ -4818,7 +4818,12 @@ struct hostapd_config * hostapd_config_r int errors = 0; size_t i; diff --git a/package/network/services/hostapd/patches/710-vlan_no_bridge.patch b/package/network/services/hostapd/patches/710-vlan_no_bridge.patch index 63d1b8a3b83533..f625f4bda4b46b 100644 --- a/package/network/services/hostapd/patches/710-vlan_no_bridge.patch +++ b/package/network/services/hostapd/patches/710-vlan_no_bridge.patch @@ -30,7 +30,7 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -3351,6 +3351,8 @@ static int hostapd_config_fill(struct ho +@@ -3353,6 +3353,8 @@ static int hostapd_config_fill(struct ho #ifndef CONFIG_NO_VLAN } else if (os_strcmp(buf, "dynamic_vlan") == 0) { bss->ssid.dynamic_vlan = atoi(pos); diff --git a/package/network/services/hostapd/patches/720-iface_max_num_sta.patch b/package/network/services/hostapd/patches/720-iface_max_num_sta.patch index 089c1ddc2461ba..598f8dfe7b39bb 100644 --- a/package/network/services/hostapd/patches/720-iface_max_num_sta.patch +++ b/package/network/services/hostapd/patches/720-iface_max_num_sta.patch @@ -1,6 +1,6 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -2848,6 +2848,14 @@ static int hostapd_config_fill(struct ho +@@ -2850,6 +2850,14 @@ static int hostapd_config_fill(struct ho line, bss->max_num_sta, MAX_STA_COUNT); return 1; } @@ -59,7 +59,7 @@ { --- a/src/ap/beacon.c +++ b/src/ap/beacon.c -@@ -1252,7 +1252,7 @@ void handle_probe_req(struct hostapd_dat +@@ -1261,7 +1261,7 @@ void handle_probe_req(struct hostapd_dat if (hapd->conf->no_probe_resp_if_max_sta && is_multicast_ether_addr(mgmt->da) && is_multicast_ether_addr(mgmt->bssid) && @@ -70,7 +70,7 @@ " since no room for additional STA", --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h -@@ -1039,6 +1039,8 @@ struct hostapd_config { +@@ -1040,6 +1040,8 @@ struct hostapd_config { unsigned int track_sta_max_num; unsigned int track_sta_max_age; diff --git a/package/network/services/hostapd/patches/730-ft_iface.patch b/package/network/services/hostapd/patches/730-ft_iface.patch index 0795ed15a1402b..348005162d6ecd 100644 --- a/package/network/services/hostapd/patches/730-ft_iface.patch +++ b/package/network/services/hostapd/patches/730-ft_iface.patch @@ -1,6 +1,6 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -3007,6 +3007,8 @@ static int hostapd_config_fill(struct ho +@@ -3009,6 +3009,8 @@ static int hostapd_config_fill(struct ho wpa_printf(MSG_INFO, "Line %d: Obsolete peerkey parameter ignored", line); #ifdef CONFIG_IEEE80211R_AP @@ -21,7 +21,7 @@ int bridge_hairpin; /* hairpin_mode on bridge members */ --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c -@@ -1727,8 +1727,12 @@ int hostapd_setup_wpa(struct hostapd_dat +@@ -1736,8 +1736,12 @@ int hostapd_setup_wpa(struct hostapd_dat wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt)) { const char *ft_iface; diff --git a/package/network/services/hostapd/patches/740-snoop_iface.patch b/package/network/services/hostapd/patches/740-snoop_iface.patch index ce64513a421b42..add46d3ebc08fe 100644 --- a/package/network/services/hostapd/patches/740-snoop_iface.patch +++ b/package/network/services/hostapd/patches/740-snoop_iface.patch @@ -104,7 +104,7 @@ static inline int hostapd_drv_vendor_cmd(struct hostapd_data *hapd, --- a/src/drivers/driver.h +++ b/src/drivers/driver.h -@@ -4209,7 +4209,7 @@ struct wpa_driver_ops { +@@ -4218,7 +4218,7 @@ struct wpa_driver_ops { * Returns: 0 on success, negative (<0) on failure */ int (*br_set_net_param)(void *priv, enum drv_br_net_param param, @@ -115,7 +115,7 @@ * get_wowlan - Get wake-on-wireless status --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c -@@ -12168,7 +12168,7 @@ static const char * drv_br_net_param_str +@@ -12178,7 +12178,7 @@ static const char * drv_br_net_param_str static int wpa_driver_br_set_net_param(void *priv, enum drv_br_net_param param, @@ -124,7 +124,7 @@ { struct i802_bss *bss = priv; char path[128]; -@@ -12194,8 +12194,11 @@ static int wpa_driver_br_set_net_param(v +@@ -12204,8 +12204,11 @@ static int wpa_driver_br_set_net_param(v return -EINVAL; } diff --git a/package/network/services/hostapd/patches/750-qos_map_set_without_interworking.patch b/package/network/services/hostapd/patches/750-qos_map_set_without_interworking.patch index 97c32df7044646..43914e9f6f4a30 100644 --- a/package/network/services/hostapd/patches/750-qos_map_set_without_interworking.patch +++ b/package/network/services/hostapd/patches/750-qos_map_set_without_interworking.patch @@ -18,7 +18,7 @@ #ifdef CONFIG_HS20 static int hs20_parse_conn_capab(struct hostapd_bss_config *bss, char *buf, -@@ -4062,10 +4062,10 @@ static int hostapd_config_fill(struct ho +@@ -4064,10 +4064,10 @@ static int hostapd_config_fill(struct ho bss->gas_frag_limit = val; } else if (os_strcmp(buf, "gas_comeback_delay") == 0) { bss->gas_comeback_delay = atoi(pos); @@ -50,7 +50,7 @@ wpa_printf(MSG_ERROR, "BSS Load initialization failed"); --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c -@@ -2683,8 +2683,6 @@ void wnm_bss_keep_alive_deinit(struct wp +@@ -2849,8 +2849,6 @@ void wnm_bss_keep_alive_deinit(struct wp } @@ -59,7 +59,7 @@ static int wpas_qos_map_set(struct wpa_supplicant *wpa_s, const u8 *qos_map, size_t len) { -@@ -2717,8 +2715,6 @@ static void interworking_process_assoc_r +@@ -2883,8 +2881,6 @@ static void interworking_process_assoc_r } } @@ -68,7 +68,7 @@ static void wpa_supplicant_set_4addr_mode(struct wpa_supplicant *wpa_s) { -@@ -3098,10 +3094,8 @@ static int wpa_supplicant_event_associnf +@@ -3264,10 +3260,8 @@ static int wpa_supplicant_event_associnf wnm_process_assoc_resp(wpa_s, data->assoc_info.resp_ies, data->assoc_info.resp_ies_len); #endif /* CONFIG_WNM */ diff --git a/package/network/services/hostapd/patches/760-dynamic_own_ip.patch b/package/network/services/hostapd/patches/760-dynamic_own_ip.patch index 2c705a68cf0acf..946b4533bf241a 100644 --- a/package/network/services/hostapd/patches/760-dynamic_own_ip.patch +++ b/package/network/services/hostapd/patches/760-dynamic_own_ip.patch @@ -98,7 +98,7 @@ hapd->conf->own_ip_addr.af == AF_INET && --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -2688,6 +2688,8 @@ static int hostapd_config_fill(struct ho +@@ -2690,6 +2690,8 @@ static int hostapd_config_fill(struct ho } else if (os_strcmp(buf, "iapp_interface") == 0) { wpa_printf(MSG_INFO, "DEPRECATED: iapp_interface not used"); #endif /* CONFIG_IAPP */ diff --git a/package/network/services/hostapd/patches/990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch b/package/network/services/hostapd/patches/990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch index 5809a3b7e8170f..ca029c393412a5 100644 --- a/package/network/services/hostapd/patches/990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch +++ b/package/network/services/hostapd/patches/990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch @@ -13,7 +13,7 @@ Signed-off-by: David Bauer --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c -@@ -12763,7 +12763,7 @@ char * wpa_supplicant_ctrl_iface_process +@@ -12838,7 +12838,7 @@ char * wpa_supplicant_ctrl_iface_process if (wpas_ctrl_iface_coloc_intf_report(wpa_s, buf + 18)) reply_len = -1; #endif /* CONFIG_WNM */ @@ -22,7 +22,7 @@ Signed-off-by: David Bauer } else if (os_strncmp(buf, "DISASSOC_IMMINENT ", 18) == 0) { if (ap_ctrl_iface_disassoc_imminent(wpa_s, buf + 18)) reply_len = -1; -@@ -12773,7 +12773,7 @@ char * wpa_supplicant_ctrl_iface_process +@@ -12848,7 +12848,7 @@ char * wpa_supplicant_ctrl_iface_process } else if (os_strncmp(buf, "BSS_TM_REQ ", 11) == 0) { if (ap_ctrl_iface_bss_tm_req(wpa_s, buf + 11)) reply_len = -1; diff --git a/package/network/services/hostapd/patches/992-nl80211-add-extra-ies-only-if-allowed-by-driver.patch b/package/network/services/hostapd/patches/992-nl80211-add-extra-ies-only-if-allowed-by-driver.patch index c7b595da57dd54..0246dc50213738 100644 --- a/package/network/services/hostapd/patches/992-nl80211-add-extra-ies-only-if-allowed-by-driver.patch +++ b/package/network/services/hostapd/patches/992-nl80211-add-extra-ies-only-if-allowed-by-driver.patch @@ -26,7 +26,7 @@ Signed-off-by: David Bauer --- a/src/drivers/driver.h +++ b/src/drivers/driver.h -@@ -2283,6 +2283,9 @@ struct wpa_driver_capa { +@@ -2292,6 +2292,9 @@ struct wpa_driver_capa { /** Maximum number of iterations in a single scan plan */ u32 max_sched_scan_plan_iterations; @@ -38,7 +38,7 @@ Signed-off-by: David Bauer --- a/src/drivers/driver_nl80211_capa.c +++ b/src/drivers/driver_nl80211_capa.c -@@ -949,6 +949,10 @@ static int wiphy_info_handler(struct nl_ +@@ -953,6 +953,10 @@ static int wiphy_info_handler(struct nl_ nla_get_u32(tb[NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS]); } From 9c5068900457c52424cb526f0124c17797322cf0 Mon Sep 17 00:00:00 2001 From: dimfish Date: Thu, 20 Jan 2022 19:49:43 +0300 Subject: [PATCH 044/225] Custom feed core --- include/feeds.mk | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/feeds.mk b/include/feeds.mk index 632fecb4a3aaec..18eb170dd79b90 100644 --- a/include/feeds.mk +++ b/include/feeds.mk @@ -27,15 +27,17 @@ $(strip $(if $(CONFIG_PER_FEED_REPO), \ $(PACKAGE_DIR))) endef +EXCLUDE_FEEDS:=nss_packages + # 1: destination file define FeedSourcesAppend ( \ - echo 'src/gz %d_core %U/targets/%S/packages'; \ + echo 'src/gz %d_core https://openwrt.admincomps.ru/nss/$(shell date +"%Y%m%d")/packages'; \ $(strip $(if $(CONFIG_PER_FEED_REPO), \ echo 'src/gz %d_base %U/packages/%A/base'; \ $(if $(filter %SNAPSHOT-y,$(VERSION_NUMBER)-$(CONFIG_BUILDBOT)), \ echo 'src/gz %d_kmods %U/targets/%S/kmods/$(LINUX_VERSION)-$(LINUX_RELEASE)-$(LINUX_VERMAGIC)';) \ - $(foreach feed,$(FEEDS_AVAILABLE), \ + $(foreach feed,$(filter-out $(EXCLUDE_FEEDS), $(FEEDS_AVAILABLE)), \ $(if $(CONFIG_FEED_$(feed)), \ echo '$(if $(filter m,$(CONFIG_FEED_$(feed))),# )src/gz %d_$(feed) %U/packages/%A/$(feed)';)))) \ ) >> $(1) From 82e55662bb19eb22914f830a9c74fc8444d8e918 Mon Sep 17 00:00:00 2001 From: dimfish Date: Wed, 2 Aug 2023 11:43:48 +0300 Subject: [PATCH 045/225] feeds: use forked dimfishr/nss-packages --- feeds.conf.default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feeds.conf.default b/feeds.conf.default index e0bad42753507c..4699f733f878e2 100644 --- a/feeds.conf.default +++ b/feeds.conf.default @@ -2,7 +2,7 @@ src-git packages https://git.openwrt.org/feed/packages.git src-git luci https://git.openwrt.org/project/luci.git src-git routing https://git.openwrt.org/feed/routing.git src-git telephony https://git.openwrt.org/feed/telephony.git -src-git nss_packages https://github.com/bitthief/nss-packages.git +src-git nss_packages https://github.com/dimfishr/nss-packages.git #src-git video https://github.com/openwrt/video.git #src-git targets https://github.com/openwrt/targets.git #src-git oldpackages http://git.openwrt.org/packages.git From c96a5a9b53ad76d72cfd8533e76631d83e3075fd Mon Sep 17 00:00:00 2001 From: dimfish Date: Mon, 31 Jan 2022 14:48:21 +0300 Subject: [PATCH 046/225] Enable WiFi --- package/kernel/mac80211/files/lib/wifi/mac80211.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/kernel/mac80211/files/lib/wifi/mac80211.sh b/package/kernel/mac80211/files/lib/wifi/mac80211.sh index e24a2a634ea606..4a3d6455b5eaa2 100644 --- a/package/kernel/mac80211/files/lib/wifi/mac80211.sh +++ b/package/kernel/mac80211/files/lib/wifi/mac80211.sh @@ -203,7 +203,7 @@ detect_mac80211() { set wireless.${name}.channel=${channel} set wireless.${name}.band=${mode_band} set wireless.${name}.htmode=$htmode - set wireless.${name}.disabled=1 + set wireless.${name}.disabled=0 set wireless.default_${name}=wifi-iface set wireless.default_${name}.device=${name} From e923cfd71c6000753937c112206bb0236e879791 Mon Sep 17 00:00:00 2001 From: dimfish Date: Thu, 17 Feb 2022 14:15:12 +0300 Subject: [PATCH 047/225] Disable autobuild --- .github/FUNDING.yml | 1 - .github/ISSUE_TEMPLATE/bug-report.yml | 93 ------------ .github/ISSUE_TEMPLATE/config.yml | 12 -- .github/labeler.yml | 139 ------------------ .github/pull_request_template | 8 - .github/workflows/coverity.yml | 19 --- .github/workflows/formal.yml | 73 --------- .github/workflows/kernel.yml | 42 ------ .github/workflows/label-kernel.yml | 16 -- .github/workflows/label-target.yml | 16 -- .github/workflows/labeler.yml | 33 ----- .github/workflows/packages.yml | 42 ------ .github/workflows/push-containers.yml | 28 ---- .github/workflows/scripts/ci_helpers.sh | 26 ---- .../workflows/scripts/show_build_failures.sh | 15 -- .github/workflows/toolchain.yml | 29 ---- .github/workflows/tools.yml | 27 ---- 17 files changed, 619 deletions(-) delete mode 100644 .github/FUNDING.yml delete mode 100644 .github/ISSUE_TEMPLATE/bug-report.yml delete mode 100644 .github/ISSUE_TEMPLATE/config.yml delete mode 100644 .github/labeler.yml delete mode 100644 .github/pull_request_template delete mode 100644 .github/workflows/coverity.yml delete mode 100644 .github/workflows/formal.yml delete mode 100644 .github/workflows/kernel.yml delete mode 100644 .github/workflows/label-kernel.yml delete mode 100644 .github/workflows/label-target.yml delete mode 100644 .github/workflows/labeler.yml delete mode 100644 .github/workflows/packages.yml delete mode 100644 .github/workflows/push-containers.yml delete mode 100644 .github/workflows/scripts/ci_helpers.sh delete mode 100755 .github/workflows/scripts/show_build_failures.sh delete mode 100644 .github/workflows/toolchain.yml delete mode 100644 .github/workflows/tools.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 4d7a7262697a31..00000000000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1 +0,0 @@ -custom: [ 'https://openwrt.org/donate' ] diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml deleted file mode 100644 index 2ec7b7d7d8893a..00000000000000 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ /dev/null @@ -1,93 +0,0 @@ -name: Bug report -description: Create a bug report to help us improve -labels: - - bug -body: - - type: textarea - id: description - attributes: - label: Describe the bug - description: A clear and concise description of the bug. - validations: - required: true - - type: input - id: version - attributes: - label: OpenWrt version - description: | - The OpenWrt release or commit hash where this bug occurs (use command below). - ```. /etc/openwrt_release && echo $DISTRIB_REVISION``` - validations: - required: true - - type: input - id: release - attributes: - label: OpenWrt release - description: | - The OpenWrt release or commit hash where this bug occurs (use command below). - ```. /etc/openwrt_release && echo $DISTRIB_RELEASE``` - validations: - required: true - - type: input - id: target - attributes: - label: OpenWrt target/subtarget - description: | - The OpenWrt target and subtarget where this bug is observed (use command below). - ```. /etc/openwrt_release && echo $DISTRIB_TARGET``` - validations: - required: true - - type: input - id: device - attributes: - label: Device - description: | - The device exhibiting this bug (if unsure, use command below). - ```cat /tmp/sysinfo/model``` - validations: - required: true - - type: dropdown - id: image_kind - attributes: - label: Image kind - options: - - Official downloaded image - - Self-built image - validations: - required: true - - type: textarea - id: reproduce - attributes: - label: Steps to reproduce - description: Steps to reproduce the reported behaviour. - - type: textarea - id: behaviour - attributes: - label: Actual behaviour - description: A clear and concise description of what actually happens. - - type: textarea - id: expected - attributes: - label: Expected behaviour - description: A clear and concise description of what you expected to happen. - - type: textarea - id: additional - attributes: - label: Additional info - description: Add any additional info you think might be helfpul. - - type: textarea - id: diffconfig - attributes: - label: Diffconfig - description: | - In case of a self-built image, please attach diffconfig. - ```./scripts/diffconfig.sh``` - render: text - - type: checkboxes - id: terms - attributes: - label: Terms - description: By submitting this issue, you agree to the terms below. - options: - - label: I am reporting an issue for OpenWrt, not an unsupported fork. - required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index 91e2489077c78a..00000000000000 --- a/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,12 +0,0 @@ ---- -blank_issues_enabled: false -contact_links: - - name: Feature request - url: https://forum.openwrt.org/c/feature-requests - about: The OpenWrt project relies on volunteers. While we appreciate feature requests, we might lack the manpower to handle them. Ideally, you get familiar with the codebase and attempt to contribute the feature yourself. We recommend to post in the forum, as this is the most likely place to receive feedback on feature requests. - - name: OpenWrt community - url: https://openwrt.org/contact - about: Consider reaching out to our community to get help. OpenWrt is a complex software project with many pitfalls; there is a good chance someone can help you solve your issue in no time. - - name: OpenWrt documentation - url: https://openwrt.org/docs/start - about: The OpenWrt documentation contains a lot of valuable information. diff --git a/.github/labeler.yml b/.github/labeler.yml deleted file mode 100644 index c8f8466d4a6100..00000000000000 --- a/.github/labeler.yml +++ /dev/null @@ -1,139 +0,0 @@ -# target/* -"target/airoha": - - "target/linux/airoha/**" -"target/apm821xx": - - "target/linux/apm821xx/**" -"target/archs38": - - "target/linux/archs38/**" -"target/armsr": - - "target/linux/armsr/**" -"target/at91": - - "target/linux/at91/**" - - "package/boot/at91bootstrap/**" - - "package/boot/uboot-at91/**" -"target/ath25": - - "target/linux/ath25/**" -"target/ath79": - - "target/linux/ath79/**" -"target/bcm27xx": - - "target/linux/bcm27xx/**" - - "package/kernel/bcm27xx-gpu-fw/**" -"target/bcm47xx": - - "target/linux/bcm47xx/**" -"target/bcm4908": - - "target/linux/bcm4908/**" - - "package/boot/uboot-bcm4908/**" -"target/bcm53xx": - - "target/linux/bcm53xx/**" - - "package/boot/uboot-bcm53xx/**" -"target/bcm63xx": - - "target/linux/bcm63xx/**" - - "package/kernel/bcm63xx-cfe/**" - - "package/boot/arm-trusted-firmware-bcm63xx/**" -"target/bmips": - - "target/linux/bmips/**" -"target/gemini": - - "target/linux/gemini/**" -"target/imx": - - "target/linux/imx/**" - - "package/boot/imx-bootlets/**" - - "package/boot/uboot-imx/**" -"target/ipq40xx": - - "target/linux/ipq40xx/**" -"target/ipq806x": - - "target/linux/ipq806x/**" -"target/qualcommax": - - "target/linux/qualcommax/**" -"target/kirkwood": - - "target/linux/kirkwood/**" - - "package/boot/uboot-kirkwood/**" -"target/lantiq": - - "target/linux/lantiq/**" - - "package/kernel/lantiq/**" - - "package/firmware/lantiq/**" - - "package/boot/uboot-lantiq/**" -"target/layerscape": - - "target/linux/layerscape/**" - - "package/firmware/layerscape/**" - - "package/boot/tfa-layerscape/**" - - "package/boot/uboot-layerscape/**" - - "package/network/utils/layerscape/**" -"target/malta": - - "target/linux/malta/**" -"target/mediatek": - - "target/linux/mediatek/**" - - "package/boot/arm-trusted-firmware-mediatek/**" - - "package/boot/uboot-mediatek/**" -"target/mpc85xx": - - "target/linux/mpc85xx/**" -"target/mvebu": - - "target/linux/mvebu/**" - - "package/boot/arm-trusted-firmware-mvebu/**" - - "package/boot/uboot-mvebu/**" -"target/mxs": - - "target/linux/mxs/**" - - "package/boot/uboot-mxs/**" -"target/octeon": - - "target/linux/octeon/**" -"target/octeontx": - - "target/linux/octeontx/**" -"target/omap": - - "target/linux/omap/**" - - "package/boot/uboot-omap/**" -"target/oxnas": - - "target/linux/oxnas/**" - - "package/boot/uboot-oxnas/**" -"target/pistachio": - - "target/linux/pistachio/**" -"target/qoriq": - - "target/linux/qoriq/**" -"target/ramips": - - "target/linux/ramips/**" -"target/realtek": - - "target/linux/realtek/**" -"target/rockchip": - - "target/linux/rockchip/**" - - "package/boot/arm-trusted-firmware-rockchip/**" - - "package/boot/uboot-rockchip/**" -"target/sifiveu": - - "target/linux/sifiveu/**" - - "package/boot/uboot-sifiveu/**" - - "package/boot/opensbi/**" -"target/sunxi": - - "target/linux/sunxi/**" - - "package/boot/arm-trusted-firmware-sunxi/**" - - "package/boot/uboot-sunxi/**" -"target/tegra": - - "target/linux/tegra/**" - - "package/boot/uboot-tegra/**" -"target/uml": - - "target/linux/uml/**" -"target/x86": - - "target/linux/x86/**" -"target/zynq": - - "target/linux/zynq/**" - - "package/boot/uboot-zynq/**" -# target/imagebuilder -"target/imagebuilder": - - "target/imagebuilder/**" -# kernel -"kernel": - - "target/linux/generic/**" - - "target/linux/**/config-*" - - "target/linux/**/patches-*" - - "target/linux/**/files/**" - - "package/kernel/linux/**" -# core packages -"core packages": - - "package/**" -# build/scripts/tools -"build/scripts/tools": - - "include/**" - - "scripts/**" - - "tools/**" -# toolchain -"toolchain": - - "toolchain/**" -# GitHub/CI -"GitHub/CI": - - ".github/**" diff --git a/.github/pull_request_template b/.github/pull_request_template deleted file mode 100644 index a2d6bd185ff61d..00000000000000 --- a/.github/pull_request_template +++ /dev/null @@ -1,8 +0,0 @@ -Thanks for your contribution to OpenWrt! - -To help keep the codebase consistent and readable, -and to help people review your contribution, -we ask you to follow the rules you find in the wiki at this link -https://openwrt.org/submitting-patches - -Please remove this message before posting the pull request. diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml deleted file mode 100644 index f54695986daace..00000000000000 --- a/.github/workflows/coverity.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Coverity scan build - -on: - schedule: - - cron: '30 2 * * 6' - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - -jobs: - coverity_build: - name: Coverity x86/64 build - secrets: - coverity_api_token: ${{ secrets.COVERITY_API_TOKEN }} - permissions: - contents: read - packages: read - actions: write - uses: openwrt/actions-shared-workflows/.github/workflows/coverity.yml@main diff --git a/.github/workflows/formal.yml b/.github/workflows/formal.yml deleted file mode 100644 index 8083c5832ca4d4..00000000000000 --- a/.github/workflows/formal.yml +++ /dev/null @@ -1,73 +0,0 @@ -name: Test Formalities - -on: - pull_request: - -permissions: - contents: read - -jobs: - build: - name: Test Formalities - runs-on: ubuntu-latest - strategy: - fail-fast: false - - steps: - - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.sha }} - fetch-depth: 0 - - - name: Determine branch name - run: | - BRANCH="${GITHUB_BASE_REF#refs/heads/}" - echo "Building for $BRANCH" - echo "BRANCH=$BRANCH" >> $GITHUB_ENV - - - name: Test formalities - run: | - source .github/workflows/scripts/ci_helpers.sh - - RET=0 - for commit in $(git rev-list HEAD ^origin/$BRANCH); do - info "=== Checking commit '$commit'" - if git show --format='%P' -s $commit | grep -qF ' '; then - err "Pull request should not include merge commits" - RET=1 - fi - - author="$(git show -s --format=%aN $commit)" - if echo $author | grep -q '\S\+\s\+\S\+'; then - success "Author name ($author) seems ok" - else - err "Author name ($author) need to be your real name 'firstname lastname'" - RET=1 - fi - - subject="$(git show -s --format=%s $commit)" - if echo "$subject" | grep -q -e '^[0-9A-Za-z,+/_\.-]\+: ' -e '^Revert '; then - success "Commit subject line seems ok ($subject)" - else - err "Commit subject line MUST start with ': ' ($subject)" - RET=1 - fi - - body="$(git show -s --format=%b $commit)" - sob="$(git show -s --format='Signed-off-by: %aN <%aE>' $commit)" - if echo "$body" | grep -qF "$sob"; then - success "Signed-off-by match author" - else - err "Signed-off-by is missing or doesn't match author (should be '$sob')" - RET=1 - fi - - if echo "$body" | grep -v "Signed-off-by:"; then - success "A commit message exists" - else - err "Missing commit message. Please describe your changes" - RET=1 - fi - done - - exit $RET diff --git a/.github/workflows/kernel.yml b/.github/workflows/kernel.yml deleted file mode 100644 index 43c610ab4f00cb..00000000000000 --- a/.github/workflows/kernel.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: Build Kernel - -on: - pull_request: - paths: - - '.github/workflows/check-kernel-patches.yml' - - '.github/workflows/build.yml' - - '.github/workflows/kernel.yml' - - 'include/kernel*' - - 'package/kernel/**' - - 'target/linux/**' - push: - paths: - - '.github/workflows/check-kernel-patches.yml' - - '.github/workflows/build.yml' - - '.github/workflows/kernel.yml' - - 'include/kernel*' - - 'package/kernel/**' - - 'target/linux/**' - branches-ignore: - - master - -permissions: - contents: read - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} - -jobs: - build-kernels: - name: Build all affected Kernels - permissions: - contents: read - packages: read - actions: write - secrets: - ccache_s3_endpoint: ${{ secrets.CCACHE_S3_ENDPOINT }} - ccache_s3_bucket: ${{ secrets.CCACHE_S3_BUCKET }} - ccache_s3_access_key: ${{ secrets.CCACHE_S3_ACCESS_KEY }} - ccache_s3_secret_key: ${{ secrets.CCACHE_S3_SECRET_KEY }} - uses: openwrt/actions-shared-workflows/.github/workflows/kernel.yml@main diff --git a/.github/workflows/label-kernel.yml b/.github/workflows/label-kernel.yml deleted file mode 100644 index 655d7d6ff371b5..00000000000000 --- a/.github/workflows/label-kernel.yml +++ /dev/null @@ -1,16 +0,0 @@ -# ci:kernel:x86:64 is going to trigger CI kernel check jobs for x86/64 target - -name: Build kernel and check patches for target specified in labels -on: - pull_request: - types: - - labeled - -jobs: - build-kernels-label: - name: Build all affected Kernels from defined label - permissions: - contents: read - packages: read - actions: write - uses: openwrt/actions-shared-workflows/.github/workflows/label-kernel.yml@main diff --git a/.github/workflows/label-target.yml b/.github/workflows/label-target.yml deleted file mode 100644 index 989ee9fcb43491..00000000000000 --- a/.github/workflows/label-target.yml +++ /dev/null @@ -1,16 +0,0 @@ -# ci:target:x86:64 is going to trigger CI target check jobs for x86/64 target - -name: Build check target specified in labels -on: - pull_request: - types: - - labeled - -jobs: - build-target-label: - name: Build target from defined label - permissions: - contents: read - packages: read - actions: write - uses: openwrt/actions-shared-workflows/.github/workflows/label-target.yml@main diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml deleted file mode 100644 index 5f82b88a50a7dc..00000000000000 --- a/.github/workflows/labeler.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: 'Pull Request Labeler' -on: - - pull_request_target - -permissions: - contents: read - -jobs: - labeler: - permissions: - contents: read # to determine modified files (actions/labeler) - pull-requests: write # to add labels to PRs (actions/labeler) - - name: Pull Request Labeler - runs-on: ubuntu-latest - steps: - - uses: actions/labeler@v4 - with: - repo-token: '${{ secrets.GITHUB_TOKEN }}' - - - name: Check Branch - id: check-branch - run: | - if echo "${{ github.base_ref }}" | grep -q -E 'openwrt-[0-9][0-9]\.[0-9][0-9]'; then - echo "release-tag=$(echo ${{ github.base_ref }} | sed 's/openwrt-/release\//')" >> $GITHUB_OUTPUT - fi - - - uses: buildsville/add-remove-label@v2.0.0 - if: ${{ steps.check-branch.outputs.release-tag }} - with: - token: ${{secrets.GITHUB_TOKEN}} - labels: ${{ steps.check-branch.outputs.release-tag }} - type: add diff --git a/.github/workflows/packages.yml b/.github/workflows/packages.yml deleted file mode 100644 index f061c1cd371a5d..00000000000000 --- a/.github/workflows/packages.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: Build all core packages - -on: - pull_request: - paths: - - '.github/workflows/packages.yml' - - 'config/**' - - 'include/**' - - 'package/**' - - 'target/linux/generic/**' - - 'toolchain/**' - push: - paths: - - '.github/workflows/packages.yml' - - 'config/**' - - 'include/**' - - 'package/**' - - 'target/linux/generic/**' - - 'toolchain/**' - branches-ignore: - - master - -permissions: - contents: read - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} - -jobs: - build-packages: - name: Build all core packages for selected target - permissions: - contents: read - packages: read - actions: write - secrets: - ccache_s3_endpoint: ${{ secrets.CCACHE_S3_ENDPOINT }} - ccache_s3_bucket: ${{ secrets.CCACHE_S3_BUCKET }} - ccache_s3_access_key: ${{ secrets.CCACHE_S3_ACCESS_KEY }} - ccache_s3_secret_key: ${{ secrets.CCACHE_S3_SECRET_KEY }} - uses: openwrt/actions-shared-workflows/.github/workflows/packages.yml@main diff --git a/.github/workflows/push-containers.yml b/.github/workflows/push-containers.yml deleted file mode 100644 index 74f534d57a4a40..00000000000000 --- a/.github/workflows/push-containers.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Build and Push prebuilt tools container - -on: - push: - paths: - - 'include/version.mk' - - 'include/cmake.mk' - - 'tools/**' - - '.github/workflows/push-containers.yml' - - 'toolchain/**' - branches-ignore: - - master - -permissions: - contents: read - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - build-push-containers: - name: Build and Push all prebuilt containers - permissions: - contents: read - packages: write - actions: write - uses: openwrt/actions-shared-workflows/.github/workflows/push-containers.yml@main diff --git a/.github/workflows/scripts/ci_helpers.sh b/.github/workflows/scripts/ci_helpers.sh deleted file mode 100644 index 2f9daf81e2bad6..00000000000000 --- a/.github/workflows/scripts/ci_helpers.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh - -color_out() { - printf "\e[0;$1m%s\e[0;0m\n" "$2" -} - -success() { - color_out 32 "$1" -} - -info() { - color_out 36 "$1" -} - -err() { - color_out 31 "$1" -} - -warn() { - color_out 33 "$1" -} - -err_die() { - err "$1" - exit 1 -} diff --git a/.github/workflows/scripts/show_build_failures.sh b/.github/workflows/scripts/show_build_failures.sh deleted file mode 100755 index 7b1a021155bdc1..00000000000000 --- a/.github/workflows/scripts/show_build_failures.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -original_exit_code="${ret:-1}" -log_dir_path="${1:-logs}" -context="${2:-10}" - -show_make_build_errors() { - grep -slr 'make\[[[:digit:]]\+\].*Error [[:digit:]]\+$' "$log_dir_path" | while IFS= read -r log_file; do - printf "====== Make errors from %s ======\n" "$log_file"; - grep -r -C"$context" 'make\[[[:digit:]]\+\].*Error [[:digit:]]\+$' "$log_file" ; - done -} - -show_make_build_errors -exit "$original_exit_code" diff --git a/.github/workflows/toolchain.yml b/.github/workflows/toolchain.yml deleted file mode 100644 index 0bc9fec1795f76..00000000000000 --- a/.github/workflows/toolchain.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Build Toolchains - -on: - pull_request: - paths: - - '.github/workflows/toolchain.yml' - - 'toolchain/**' - push: - paths: - - '.github/workflows/toolchain.yml' - - 'toolchain/**' - branches-ignore: - - master - -permissions: - contents: read - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} - -jobs: - build-toolchains: - name: Build Toolchains for each target - permissions: - contents: read - packages: read - actions: write - uses: openwrt/actions-shared-workflows/.github/workflows/toolchain.yml@main diff --git a/.github/workflows/tools.yml b/.github/workflows/tools.yml deleted file mode 100644 index 35904a5e564f65..00000000000000 --- a/.github/workflows/tools.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: Build host tools - -on: - pull_request: - paths: - - 'include/**' - - 'tools/**' - - '.github/workflows/tools.yml' - push: - paths: - - 'include/**' - - 'tools/**' - - '.github/workflows/tools.yml' - branches-ignore: - - master - -permissions: - contents: read - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} - -jobs: - build-tools: - name: Build host tools for linux and macos based systems - uses: openwrt/actions-shared-workflows/.github/workflows/tools.yml@main From 3ef10dd293180a693fc40fd13bc8bf001a5d0c38 Mon Sep 17 00:00:00 2001 From: dimfish Date: Tue, 7 Mar 2023 18:53:02 +0300 Subject: [PATCH 048/225] Add all Governors --- target/linux/qualcommax/config-6.1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/target/linux/qualcommax/config-6.1 b/target/linux/qualcommax/config-6.1 index 00d92ad71a8b92..09b9776d4ac6ef 100644 --- a/target/linux/qualcommax/config-6.1 +++ b/target/linux/qualcommax/config-6.1 @@ -80,12 +80,12 @@ CONFIG_CPU_FREQ=y # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y CONFIG_CPU_FREQ_GOV_ATTR_SET=y -# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set -# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y -# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_STAT=y CONFIG_CPU_FREQ_THERMAL=y CONFIG_CPU_IDLE=y From 6924bb55e746deaf0b610741085540066cd567f6 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Tue, 21 Mar 2023 08:09:22 +0100 Subject: [PATCH 049/225] mac80211: ath11k: add HACK patch to fix failing sysupgrade Add HACK patch to fix failing sysupgrade on any device that have ath11k wifi card. Due to some BUG, some packet in the tx ring are never "complated" and moved to the tx completion ring. This cause the related idr of the packet to never be freed and num_tx_pending never decreated to 0. This cause the flush function to timeout and sysupgrade to fail as it takes too much time to terminates the process. Workaround this on the driver side instead of adding an hack to the .sh file to make it easier to drop and track in the future. The workaround is quite simple, when tx_flush is called and the function timeouts every ring is put under lock and idr freed of the stuck packets. THIS IS NOT A FIX BUT A WORKAROUND FOR AN ANNOYING PROBLEM. Signed-off-by: Christian Marangi --- ...-drop-pending-packet-for-ath11k_mac_.patch | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 package/kernel/mac80211/patches/ath11k/999-wifi-ath11k-HACK-drop-pending-packet-for-ath11k_mac_.patch diff --git a/package/kernel/mac80211/patches/ath11k/999-wifi-ath11k-HACK-drop-pending-packet-for-ath11k_mac_.patch b/package/kernel/mac80211/patches/ath11k/999-wifi-ath11k-HACK-drop-pending-packet-for-ath11k_mac_.patch new file mode 100644 index 00000000000000..d92f86f24d15f5 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/999-wifi-ath11k-HACK-drop-pending-packet-for-ath11k_mac_.patch @@ -0,0 +1,87 @@ +From 97a3daa845cfe96d07fb270df72bf7c3e05dd866 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 10 Oct 2022 17:04:36 +0200 +Subject: [PATCH] wifi: ath11k: HACK drop pending packet for + ath11k_mac_flush_tx_complete + +Some packets may be lost and stay in the tx_pending counter. Drop them +when an interface is torn down. + +THIS IS NOT A FIX AS AFTER A LONG TIME WE WILL END UP WITH FILLED RING +AND NOTHING WILL WORK + +Signed-off-by: Christian Marangi +--- + drivers/net/wireless/ath/ath11k/mac.c | 53 +++++++++++++++++++++++++++ + 1 file changed, 53 insertions(+) + +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index 110a38cce0a7..101b54a6749e 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -7387,8 +7387,62 @@ static int ath11k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value) + + static int ath11k_mac_flush_tx_complete(struct ath11k *ar) + { ++ struct ath11k_base *ab = ar->ab; + long time_left; + int ret = 0; ++ int i; ++ ++ time_left = wait_event_timeout(ar->dp.tx_empty_waitq, ++ (atomic_read(&ar->dp.num_tx_pending) == 0), ++ ATH11K_FLUSH_TIMEOUT); ++ /* XXX: hack some packets are lost for some reason. Drop pending idr. ++ * THIS IS NOT A FIX AS AFTER A LONG TIME WE WILL END UP WITH FILLED RING ++ * AND NOTHING WILL WORK ++ */ ++ if (time_left == 0) { ++ int msdu_id, num_tx_pending_dropped; ++ struct ath11k_dp *dp = &ab->dp; ++ struct ath11k_skb_cb *skb_cb; ++ struct dp_tx_ring *tx_ring; ++ struct sk_buff *msdu; ++ ++ ath11k_warn(ar->ab, "failed to flush transmit queue, data pkts pending %d\n", ++ atomic_read(&ar->dp.num_tx_pending)); ++ ++ for (i = 0; i < ab->hw_params.max_tx_ring; i++) { ++ tx_ring = &dp->tx_ring[i]; ++ ++ spin_lock(&tx_ring->tx_idr_lock); ++ } ++ ++ for (i = 0; i < ab->hw_params.max_tx_ring; i++) { ++ num_tx_pending_dropped = 0; ++ tx_ring = &dp->tx_ring[i]; ++ ++ idr_for_each_entry(&tx_ring->txbuf_idr, msdu, msdu_id) { ++ idr_remove(&tx_ring->txbuf_idr, msdu_id); ++ ++ skb_cb = ATH11K_SKB_CB(msdu); ++ ++ dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, ++ DMA_TO_DEVICE); ++ dev_kfree_skb_any(msdu); ++ ++ atomic_dec(&ar->dp.num_tx_pending); ++ num_tx_pending_dropped++; ++ } ++ ++ if (num_tx_pending_dropped > 0) ++ ath11k_err(ar->ab, "pkts stuck in tx_ring %d, DROPPED %d pkts\n", ++ i, num_tx_pending_dropped); ++ } ++ ++ for (i = 0; i < ab->hw_params.max_tx_ring; i++) { ++ tx_ring = &dp->tx_ring[i]; ++ ++ spin_unlock(&tx_ring->tx_idr_lock); ++ } ++ } + + time_left = wait_event_timeout(ar->dp.tx_empty_waitq, + (atomic_read(&ar->dp.num_tx_pending) == 0), +-- +2.39.2 + From 01759e730025d94fc85e989a5a5e5517dbbc0a2f Mon Sep 17 00:00:00 2001 From: dimfish Date: Mon, 31 Jul 2023 17:30:06 +0300 Subject: [PATCH 050/225] netfilter: optional tcp window check --- ...ilter_optional_tcp_window_check.patc.patch | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/0613-netfilter_optional_tcp_window_check.patc.patch diff --git a/target/linux/qualcommax/patches-6.1/0613-netfilter_optional_tcp_window_check.patc.patch b/target/linux/qualcommax/patches-6.1/0613-netfilter_optional_tcp_window_check.patc.patch new file mode 100644 index 00000000000000..150853573d0116 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0613-netfilter_optional_tcp_window_check.patc.patch @@ -0,0 +1,108 @@ +From ed42112c77bfb68594f49e252ace2dd6b8c8e7ff Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Thu, 16 Mar 2023 17:21:39 +0530 +Subject: [PATCH 063/281] OpenWrt: + 613-netfilter_optional_tcp_window_check.patch + +netfilter: optional tcp window check + +Signed-off-by: Felix Fietkau +Signed-off-by: Christian 'Ansuel' Marangi + +Change-Id: I6f7a23b89062cca58c87554e75ae32b0e2aa2831 +Signed-off-by: Ram Chandra Jangir +--- + include/net/netns/conntrack.h | 1 + + net/netfilter/nf_conntrack_proto_tcp.c | 9 ++++++++- + net/netfilter/nf_conntrack_standalone.c | 10 ++++++++++ + 3 files changed, 19 insertions(+), 1 deletion(-) + +diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h +index 1f463b3957c7..2af4f8d24282 100644 +--- a/include/net/netns/conntrack.h ++++ b/include/net/netns/conntrack.h +@@ -26,6 +26,7 @@ struct nf_tcp_net { + unsigned int timeouts[TCP_CONNTRACK_TIMEOUT_MAX]; + u8 tcp_loose; + u8 tcp_be_liberal; ++ u8 tcp_no_window_check; + u8 tcp_max_retrans; + u8 tcp_ignore_invalid_rst; + #if IS_ENABLED(CONFIG_NF_FLOW_TABLE) +diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c +index 3ac1af6f59fc..0a2badd52b54 100644 +--- a/net/netfilter/nf_conntrack_proto_tcp.c ++++ b/net/netfilter/nf_conntrack_proto_tcp.c +@@ -513,11 +513,15 @@ tcp_in_window(struct nf_conn *ct, enum ip_conntrack_dir dir, + struct ip_ct_tcp *state = &ct->proto.tcp; + struct ip_ct_tcp_state *sender = &state->seen[dir]; + struct ip_ct_tcp_state *receiver = &state->seen[!dir]; ++ const struct nf_tcp_net *tn = nf_tcp_pernet(nf_ct_net(ct)); + __u32 seq, ack, sack, end, win, swin; + bool in_recv_win, seq_ok; + s32 receiver_offset; + u16 win_raw; + ++ if (tn->tcp_no_window_check) ++ return NFCT_TCP_ACCEPT; ++ + /* + * Get the required data from the packet. + */ +@@ -1257,7 +1261,7 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct, + IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED && + timeouts[new_state] > timeouts[TCP_CONNTRACK_UNACK]) + timeout = timeouts[TCP_CONNTRACK_UNACK]; +- else if (ct->proto.tcp.last_win == 0 && ++ else if (!tn->tcp_no_window_check && ct->proto.tcp.last_win == 0 && + timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS]) + timeout = timeouts[TCP_CONNTRACK_RETRANS]; + else +@@ -1573,6 +1577,9 @@ void nf_conntrack_tcp_init_net(struct net *net) + */ + tn->tcp_be_liberal = 0; + ++ /* Skip Windows Check */ ++ tn->tcp_no_window_check = 0; ++ + /* If it's non-zero, we turn off RST sequence number check */ + tn->tcp_ignore_invalid_rst = 0; + +diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c +index e9654169b005..84b8e28f0782 100644 +--- a/net/netfilter/nf_conntrack_standalone.c ++++ b/net/netfilter/nf_conntrack_standalone.c +@@ -637,6 +637,7 @@ enum nf_ct_sysctl_index { + #endif + NF_SYSCTL_CT_PROTO_TCP_LOOSE, + NF_SYSCTL_CT_PROTO_TCP_LIBERAL, ++ NF_SYSCTL_CT_PROTO_TCP_NO_WINDOW_CHECK, + NF_SYSCTL_CT_PROTO_TCP_IGNORE_INVALID_RST, + NF_SYSCTL_CT_PROTO_TCP_MAX_RETRANS, + NF_SYSCTL_CT_PROTO_TIMEOUT_UDP, +@@ -844,6 +845,14 @@ static struct ctl_table nf_ct_sysctl_table[] = { + .extra1 = SYSCTL_ZERO, + .extra2 = SYSCTL_ONE, + }, ++ [NF_SYSCTL_CT_PROTO_TCP_NO_WINDOW_CHECK] = { ++ .procname = "nf_conntrack_tcp_no_window_check", ++ .maxlen = sizeof(u8), ++ .mode = 0644, ++ .proc_handler = proc_dou8vec_minmax, ++ .extra1 = SYSCTL_ZERO, ++ .extra2 = SYSCTL_ONE, ++ }, + [NF_SYSCTL_CT_PROTO_TCP_IGNORE_INVALID_RST] = { + .procname = "nf_conntrack_tcp_ignore_invalid_rst", + .maxlen = sizeof(u8), +@@ -1054,6 +1063,7 @@ static void nf_conntrack_standalone_init_tcp_sysctl(struct net *net, + + XASSIGN(LOOSE, &tn->tcp_loose); + XASSIGN(LIBERAL, &tn->tcp_be_liberal); ++ XASSIGN(NO_WINDOW_CHECK, &tn->tcp_no_window_check); + XASSIGN(MAX_RETRANS, &tn->tcp_max_retrans); + XASSIGN(IGNORE_INVALID_RST, &tn->tcp_ignore_invalid_rst); + #undef XASSIGN +-- +2.17.1 + From 0983482769382786d6dff1b664c107af6dd585fe Mon Sep 17 00:00:00 2001 From: dimfish Date: Wed, 2 Aug 2023 11:33:36 +0300 Subject: [PATCH 051/225] Revert to ath11k-firmware: update to WLAN.HK.2.9.0.1-01385-QCAHKSWPL_SILICONZ-1 --- package/firmware/ath11k-firmware/Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package/firmware/ath11k-firmware/Makefile b/package/firmware/ath11k-firmware/Makefile index ea4977aa68ca1e..fc7968a95764a4 100644 --- a/package/firmware/ath11k-firmware/Makefile +++ b/package/firmware/ath11k-firmware/Makefile @@ -8,9 +8,9 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ath11k-firmware -PKG_SOURCE_DATE:=2023-08-22 -PKG_SOURCE_VERSION:=d8f82a98ff1aef330d65d8b5660b46d1a9809ee3 -PKG_MIRROR_HASH:=3dba19449758c3b17f117990d7ad4086554e012b579f1de16e9d9196a7fbaaa7 +PKG_SOURCE_DATE:=2023-03-31 +PKG_SOURCE_VERSION:=a039049a9349722fa5c74185452ab04644a0d351 +PKG_MIRROR_HASH:=ed401e3f6e91d70565b3396139193f7e815f410db93700697205ac8ed1b828c5 PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git @@ -60,14 +60,14 @@ $(eval $(call Download,qcn9074-board)) define Package/ath11k-firmware-ipq8074/install $(INSTALL_DIR) $(1)/lib/firmware/IPQ8074 $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/ath11k-firmware/IPQ8074/hw2.0/2.9.0.1/WLAN.HK.2.9.0.1-01890-QCAHKSWPL_SILICONZ-1/* \ + $(PKG_BUILD_DIR)/ath11k-firmware/IPQ8074/hw2.0/testing/2.9.0.1/WLAN.HK.2.9.0.1-01385-QCAHKSWPL_SILICONZ-1/* \ $(1)/lib/firmware/IPQ8074/ endef define Package/ath11k-firmware-qcn9074/install $(INSTALL_DIR) $(1)/lib/firmware/ath11k/QCN9074/hw1.0 $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/ath11k-firmware/QCN9074/hw1.0/2.9.0.1/WLAN.HK.2.9.0.1-01890-QCAHKSWPL_SILICONZ-1/* \ + $(PKG_BUILD_DIR)/ath11k-firmware/QCN9074/hw1.0/testing/2.9.0.1/WLAN.HK.2.9.0.1-01385-QCAHKSWPL_SILICONZ-1/* \ $(1)/lib/firmware/ath11k/QCN9074/hw1.0/ $(INSTALL_BIN) \ $(DL_DIR)/$(QCN9074_BOARD_FILE) $(1)/lib/firmware/ath11k/QCN9074/hw1.0/board-2.bin From 836fc200f80785ecd6d591ebea3dd83db1fde978 Mon Sep 17 00:00:00 2001 From: dimfish Date: Wed, 16 Aug 2023 17:42:40 +0300 Subject: [PATCH 052/225] Firewall: disable software offloading --- package/network/config/firewall/files/firewall.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/network/config/firewall/files/firewall.config b/package/network/config/firewall/files/firewall.config index 231ee7116d6f80..b694b8cb308b05 100644 --- a/package/network/config/firewall/files/firewall.config +++ b/package/network/config/firewall/files/firewall.config @@ -3,7 +3,7 @@ config defaults option input REJECT option output ACCEPT option forward REJECT - option flow_offloading 1 + option flow_offloading 0 option fullcone 1 # Uncomment this line to disable ipv6 rules # option disable_ipv6 1 From a30f48840e84f2ab46def5116e8b044beac306c2 Mon Sep 17 00:00:00 2001 From: dimfish Date: Thu, 9 Nov 2023 19:49:17 +0300 Subject: [PATCH 053/225] qualcommax: netdevice: Add IFF_EXT_HW_NO_OFFLOAD --- .../0614-netdevice-Add-IFF_EXT_HW_NO_OFFLOAD.patch | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/0614-netdevice-Add-IFF_EXT_HW_NO_OFFLOAD.patch diff --git a/target/linux/qualcommax/patches-6.1/0614-netdevice-Add-IFF_EXT_HW_NO_OFFLOAD.patch b/target/linux/qualcommax/patches-6.1/0614-netdevice-Add-IFF_EXT_HW_NO_OFFLOAD.patch new file mode 100644 index 00000000000000..df24e0ea1de8fb --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0614-netdevice-Add-IFF_EXT_HW_NO_OFFLOAD.patch @@ -0,0 +1,11 @@ +--- a/include/linux/netdevice.h ++++ a/include/linux/netdevice.h +@@ -1725,6 +1725,8 @@ + IFF_EXT_GRE_V4_TAP = 1<<4, + IFF_EXT_GRE_V6_TAP = 1<<5, + IFF_EXT_IFB = 1<<6, ++ IFF_EXT_MAPT = 1<<7, ++ IFF_EXT_HW_NO_OFFLOAD = 1<<8, + }; + + #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN From 7c87f6e031c35ec54144cbba674b2f4eee03195e Mon Sep 17 00:00:00 2001 From: dimfish Date: Fri, 10 Nov 2023 11:47:59 +0300 Subject: [PATCH 054/225] qualcommax: uapi: Add IPPROTO_ETHERIP --- .../patches-6.1/0615-uapi-Add-IPPROTO_ETHERIP.patch | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/0615-uapi-Add-IPPROTO_ETHERIP.patch diff --git a/target/linux/qualcommax/patches-6.1/0615-uapi-Add-IPPROTO_ETHERIP.patch b/target/linux/qualcommax/patches-6.1/0615-uapi-Add-IPPROTO_ETHERIP.patch new file mode 100644 index 00000000000000..b058851cabe019 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0615-uapi-Add-IPPROTO_ETHERIP.patch @@ -0,0 +1,11 @@ +--- a/include/uapi/linux/in.h ++++ a/include/uapi/linux/in.h +@@ -63,6 +63,8 @@ + #define IPPROTO_MTP IPPROTO_MTP + IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */ + #define IPPROTO_BEETPH IPPROTO_BEETPH ++ IPPROTO_ETHERIP = 97, /* ETHERIP protocol number */ ++#define IPPROTO_ETHERIP IPPROTO_ETHERIP + IPPROTO_ENCAP = 98, /* Encapsulation Header */ + #define IPPROTO_ENCAP IPPROTO_ENCAP + IPPROTO_PIM = 103, /* Protocol Independent Multicast */ From bb2136f9af83bb1f04c7dc45c9a5a132b1918c44 Mon Sep 17 00:00:00 2001 From: dimfish Date: Fri, 10 Nov 2023 20:53:04 +0300 Subject: [PATCH 055/225] qualcommax: net: Add bond_is_mlo_device --- .../0616-net-Add-bond_is_mlo_device.patch | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/0616-net-Add-bond_is_mlo_device.patch diff --git a/target/linux/qualcommax/patches-6.1/0616-net-Add-bond_is_mlo_device.patch b/target/linux/qualcommax/patches-6.1/0616-net-Add-bond_is_mlo_device.patch new file mode 100644 index 00000000000000..9f419fe9d21656 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0616-net-Add-bond_is_mlo_device.patch @@ -0,0 +1,32 @@ +--- a/include/net/bonding.h ++++ a/include/net/bonding.h +@@ -287,6 +287,19 @@ + bool bond_sk_check(struct bonding *bond); + + /** ++ * Returns False if the net_device is not MLO bond netdvice ++ * ++ */ ++static inline bool bond_is_mlo_device(struct net_device *bond_dev) ++{ ++ struct bonding *bond = netdev_priv(bond_dev); ++ if (BOND_MODE(bond) == BOND_MODE_MLO) ++ return true; ++ ++ return false; ++} ++ ++/** + * Returns NULL if the net_device does not belong to any of the bond's slaves + * + * Caller must hold bond lock for read +--- a/include/uapi/linux/if_bonding.h ++++ a/include/uapi/linux/if_bonding.h +@@ -71,6 +71,7 @@ + #define BOND_MODE_8023AD 4 + #define BOND_MODE_TLB 5 + #define BOND_MODE_ALB 6 /* TLB + RLB (receive load balancing) */ ++#define BOND_MODE_MLO 7 /* MLO (Multi link) mode for Wi-Fi 7 AP links */ + + /* each slave's link has 4 states */ + #define BOND_LINK_UP 0 /* link is up and running */ From 90d3926d04ceb6f024ba7d529817711dfc2a338d Mon Sep 17 00:00:00 2001 From: dimfish Date: Tue, 14 Nov 2023 12:23:45 +0300 Subject: [PATCH 056/225] qca-nss-dp: update to 12.4 --- package/kernel/qca-nss-dp/Makefile | 6 +++--- ...-a-phy-handle-property-to-connect-to-.patch | 18 ++++++++---------- ...dp-allow-setting-netdev-name-from-DTS.patch | 2 +- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/package/kernel/qca-nss-dp/Makefile b/package/kernel/qca-nss-dp/Makefile index f9e992f246af2f..708901c782e462 100644 --- a/package/kernel/qca-nss-dp/Makefile +++ b/package/kernel/qca-nss-dp/Makefile @@ -5,9 +5,9 @@ PKG_RELEASE:=2 PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-dp.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2023-06-06 -PKG_SOURCE_VERSION:=fa67464466f69f00967cc373d1bdd6025f57eb89 -PKG_MIRROR_HASH:=51bf524382a5cb542c2c80d12a91f87b9736de3ac3c1d4a351c97b3502d68574 +PKG_SOURCE_DATE:=2023-10-04 +PKG_SOURCE_VERSION:=8a21ce862f3129b1d3a7a3f402a0527396da50ab +PKG_MIRROR_HASH:=d2793ebf871b96df2508f628ac9e8ad8b7bd05cd0cf6155fc4f9719ff3d7bf20 PKG_BUILD_PARALLEL:=1 PKG_FLAGS:=nonshared diff --git a/package/kernel/qca-nss-dp/patches/0006-nss_dp_main-Use-a-phy-handle-property-to-connect-to-.patch b/package/kernel/qca-nss-dp/patches/0006-nss_dp_main-Use-a-phy-handle-property-to-connect-to-.patch index 0432b82dda3f5c..a82487a4a0375e 100644 --- a/package/kernel/qca-nss-dp/patches/0006-nss_dp_main-Use-a-phy-handle-property-to-connect-to-.patch +++ b/package/kernel/qca-nss-dp/patches/0006-nss_dp_main-Use-a-phy-handle-property-to-connect-to-.patch @@ -26,7 +26,7 @@ Signed-off-by: Robert Marko --- a/include/nss_dp_dev.h +++ b/include/nss_dp_dev.h -@@ -202,13 +202,10 @@ struct nss_dp_dev { +@@ -228,13 +228,10 @@ struct nss_dp_dev { unsigned long drv_flags; /* Driver specific feature flags */ /* Phy related stuff */ @@ -43,7 +43,7 @@ Signed-off-by: Robert Marko --- a/nss_dp_main.c +++ b/nss_dp_main.c -@@ -418,7 +418,7 @@ static int nss_dp_open(struct net_device +@@ -717,7 +717,7 @@ static int nss_dp_open(struct net_device netif_start_queue(netdev); @@ -52,7 +52,7 @@ Signed-off-by: Robert Marko /* Notify data plane link is up */ if (dp_priv->data_plane_ops->link_state(dp_priv->dpc, 1)) { netdev_dbg(netdev, "Data plane set link failed\n"); -@@ -615,6 +615,12 @@ static int32_t nss_dp_of_get_pdata(struc +@@ -914,6 +914,12 @@ static int32_t nss_dp_of_get_pdata(struc return -EFAULT; } @@ -65,7 +65,7 @@ Signed-off-by: Robert Marko if (of_property_read_u32(np, "qcom,mactype", &hal_pdata->mactype)) { pr_err("%s: error reading mactype\n", np->name); return -EFAULT; -@@ -635,18 +641,6 @@ static int32_t nss_dp_of_get_pdata(struc +@@ -934,18 +940,6 @@ static int32_t nss_dp_of_get_pdata(struc return -EFAULT; #endif @@ -84,7 +84,7 @@ Signed-off-by: Robert Marko #if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)) maddr = (uint8_t *)of_get_mac_address(np); #if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 4, 0)) -@@ -695,56 +689,6 @@ static int32_t nss_dp_of_get_pdata(struc +@@ -1023,56 +1017,6 @@ static int32_t nss_dp_of_get_pdata(struc return 0; } @@ -141,7 +141,7 @@ Signed-off-by: Robert Marko #ifdef CONFIG_NET_SWITCHDEV /* * nss_dp_is_phy_dev() -@@ -803,7 +747,6 @@ static int32_t nss_dp_probe(struct platf +@@ -1131,7 +1075,6 @@ static int32_t nss_dp_probe(struct platf struct device_node *np = pdev->dev.of_node; struct nss_gmac_hal_platform_data gmac_hal_pdata; int32_t ret = 0; @@ -149,7 +149,7 @@ Signed-off-by: Robert Marko #if defined(NSS_DP_PPE_SUPPORT) uint32_t vsi_id; fal_port_t port_id; -@@ -880,22 +823,14 @@ static int32_t nss_dp_probe(struct platf +@@ -1210,20 +1153,12 @@ static int32_t nss_dp_probe(struct platf dp_priv->drv_flags |= NSS_DP_PRIV_FLAG(INIT_DONE); @@ -162,14 +162,12 @@ Signed-off-by: Robert Marko - snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, - dp_priv->miibus->id, dp_priv->phy_mdio_addr); - -+ if (dp_priv->phy_node) { - SET_NETDEV_DEV(netdev, &pdev->dev); - - dp_priv->phydev = phy_connect(netdev, phy_id, - &nss_dp_adjust_link, - dp_priv->phy_mii_type); - if (IS_ERR(dp_priv->phydev)) { - netdev_dbg(netdev, "failed to connect to phy device\n"); ++ if (dp_priv->phy_node) { + dp_priv->phydev = of_phy_connect(netdev, dp_priv->phy_node, + &nss_dp_adjust_link, 0, + dp_priv->phy_mii_type); diff --git a/package/kernel/qca-nss-dp/patches/0008-nss-dp-allow-setting-netdev-name-from-DTS.patch b/package/kernel/qca-nss-dp/patches/0008-nss-dp-allow-setting-netdev-name-from-DTS.patch index e90bf32ced7707..3de94ebe531c26 100644 --- a/package/kernel/qca-nss-dp/patches/0008-nss-dp-allow-setting-netdev-name-from-DTS.patch +++ b/package/kernel/qca-nss-dp/patches/0008-nss-dp-allow-setting-netdev-name-from-DTS.patch @@ -15,7 +15,7 @@ Signed-off-by: Robert Marko --- a/nss_dp_main.c +++ b/nss_dp_main.c -@@ -746,18 +746,29 @@ static int32_t nss_dp_probe(struct platf +@@ -1074,18 +1074,29 @@ static int32_t nss_dp_probe(struct platf struct nss_dp_dev *dp_priv; struct device_node *np = pdev->dev.of_node; struct nss_gmac_hal_platform_data gmac_hal_pdata; From 9dd349751dd5dd886dad0279cf877fe9d3781bee Mon Sep 17 00:00:00 2001 From: dimfish Date: Tue, 14 Nov 2023 12:29:53 +0300 Subject: [PATCH 057/225] qca-nss-cfi: update to 12.4 --- package/kernel/qca-nss-cfi/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/kernel/qca-nss-cfi/Makefile b/package/kernel/qca-nss-cfi/Makefile index 4841aaa74beff8..f7197e38d62295 100644 --- a/package/kernel/qca-nss-cfi/Makefile +++ b/package/kernel/qca-nss-cfi/Makefile @@ -5,9 +5,9 @@ PKG_RELEASE:=1 PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-cfi.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2021-12-14 -PKG_SOURCE_VERSION:=a0239b330846770793aefc3debf4be7edad6ffcd -PKG_MIRROR_HASH:=036bb67b5d497393199958775ea1733a445731d5c5e29c3a8b1e98d49b3721d4 +PKG_SOURCE_DATE:=2022-12-15 +PKG_SOURCE_VERSION:=5cd07ce299ee3ce62dbe4f6783ad36361e57583b +PKG_MIRROR_HASH:=e449eee24fccc09b1cf0f1367bb54cedadcc46a30423934744e78272443197e7 PKG_BUILD_PARALLEL:=1 From fdd213d9a4dc015d046b6b752f837ab58b2f278f Mon Sep 17 00:00:00 2001 From: dimfish Date: Tue, 14 Nov 2023 12:33:10 +0300 Subject: [PATCH 058/225] qca-nss-crypto: update to 12.4 --- package/kernel/qca-nss-crypto/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/kernel/qca-nss-crypto/Makefile b/package/kernel/qca-nss-crypto/Makefile index 5662757944442a..19b55133d88857 100644 --- a/package/kernel/qca-nss-crypto/Makefile +++ b/package/kernel/qca-nss-crypto/Makefile @@ -5,9 +5,9 @@ PKG_RELEASE:=1 PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-crypto.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2022-03-20 -PKG_SOURCE_VERSION:=2271a3a66f7e8284d42a9e787ddec6f24a1d2e15 -PKG_MIRROR_HASH:=cd8049f6ab05f5dda6b5d563cf28aad3c3e3160d48214a6773e769e813ba11aa +PKG_SOURCE_DATE:=2022-12-15 +PKG_SOURCE_VERSION:=3c5a574ce99d7f0b9f892002020f1bf9bfc57a81 +PKG_MIRROR_HASH:=ff487c5574481f548eef7b61129fa7be1d83ae285dcc3356a06be237440d8782 PKG_BUILD_PARALLEL:=1 From 7bc5d9d0100c54f2b00f1369b35472fedbcd4141 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 16 Dec 2023 18:09:40 -0500 Subject: [PATCH 059/225] ath11k-nss: WIP (DOES NOT WORK) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Attempt at getting NSS WiFi Offload working on kernel 6.1 (backport 6.5) These patches are a mix of @ansuel branch for 5.15 (ipq807x-5.15-ecm-wifi) https://github.com/Ansuel/openwrt/commit/3ecaee768e8d08d20eaf2a554eb2bf1da9bbf21b And QUIC's upstream NSS patches on [NHSS.QSDK.12.4.5.r3](https://git.codelinaro.org/clo/qsdk/oss/system/feeds/wlan-open.git) For the actual package setup (Makfiles,ath.mk) Qualcomm's branch is under 'wlan-open/NHSS.QSDK.12.4.5.r3' Looks like they've swtiched to using backports 6.5-rc3, and figured to use a mix of their patches on 'NHSS.QSDK.12.4.5.r3' (nss) 'wlan-open/NHSS.QSDK.12.4.5.r3' (syncing with openwrt main). Booting with "nss_offload=1 frame_mode=2" Logs show: [ 16.606282] WARNING: CPU: 2 PID: 3524 at ath11k_nss_tx+0x1d4/0x1e0 [ath11k] [ 16.611060] Modules linked in: ecm pppoe ppp_async nft_fib_inet nf_flow_table_inet ath11k_ahb ath11k pptp pppox ppp_generic nft_reject_ipv6 nft_reject_ipv4 nft_reject_inet nft_reject nft_redir nft_quota nft_objref nft_numgen nft_nat nft_masq nft_log nft_limit nft_hash nft_fullcone nft_flow_offload nft_fib_ipv6 nft_fib_ipv4 nft_fib nft_ct nft_compat nft_chain_nat nf_tables nf_nat nf_flow_table nf_conntrack_netlink nf_conntrack mac80211 iptable_mangle iptable_filter ipt_REJECT ipt_ECN ip_tables cfg80211 xt_time xt_tcpudp xt_tcpmss xt_statistic xt_multiport xt_mark xt_mac xt_limit xt_length xt_hl xt_ecn xt_dscp xt_comment xt_TCPMSS xt_LOG xt_HL xt_DSCP xt_CLASSIFY x_tables wireguard slhc sch_cake qrtr_smd qrtr qmi_helpers nfnetlink nf_reject_ipv6 nf_reject_ipv4 nf_log_syslog nf_defrag_ipv4 mhi libcrc32c libchacha20poly1305 compat sch_tbf sch_ingress sch_htb sch_hfsc em_u32 cls_u32 cls_route cls_matchall cls_fw cls_flow cls_basic act_skbedit act_mirred act_gact qca_nss_cfi_cryptoapi [ 16.611215] qca_nss_crypto qca_nss_qdisc qca_nss_wifi_meshmgr qca_nss_gre ledtrig_usbport qca_mcs bonding ip6_gre ip_gre gre ifb nat46 nf_defrag_ipv6 sit qca_nss_drv ip6_tunnel tunnel6 tunnel4 nls_utf8 nls_iso8859_1 nls_cp437 vxlan seqiv michael_mic uas usb_storage leds_gpio xhci_plat_hcd xhci_pci xhci_hcd dwc3 dwc3_qcom qca_nss_dp qca_ssdk ramoops reed_solomon pstore gpio_button_hotplug ext4 mbcache jbd2 aquantia hwmon crc_ccitt crc32c_generic [ 16.721723] CPU: 2 PID: 3524 Comm: hostapd Not tainted 6.1.68 #0 [ 16.743958] Hardware name: Dynalink DL-WRX36 (DT) [ 16.750032] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 16.754635] pc : ath11k_nss_tx+0x1d4/0x1e0 [ath11k] [ 16.761403] lr : ath11k_nss_tx+0x1bc/0x1e0 [ath11k] [ 16.766264] sp : ffffffc00b1db790 [ 16.771122] x29: ffffffc00b1db790 x28: 0000000000000038 x27: 0000000000000000 [ 16.774602] x26: ffffff8006dd7430 x25: ffffff8007ea9dc8 x24: 0000000060000012 [ 16.781719] x23: ffffff8005c6a060 x22: ffffff8005c6a060 x21: ffffff80072f12d8 [ 16.788837] x20: ffffff8007ea9dc8 x19: ffffff8006082800 x18: 0000000000000005 [ 16.795957] x17: 6976312065707974 x16: 207061636e652062 x15: 6b73207874207373 [ 16.803075] x14: ffffffc00a0dd518 x13: 000000000000018b x12: 000000000000018b [ 16.810192] x11: 00000000ffffffea x10: ffffffc00a135518 x9 : 0000000000000001 [ 16.817310] x8 : 0000000000000001 x7 : 0000000000017fe8 x6 : c0000000ffffefff [ 16.824429] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000 [ 16.831547] x2 : ffffff80072f1370 x1 : 0000000000000000 x0 : 0000000000000001 [ 16.838665] Call trace: [ 16.845774] ath11k_nss_tx+0x1d4/0x1e0 [ath11k] [ 16.848035] ath11k_mac_tx_mgmt_pending_free+0x3034/0x9600 [ath11k] [ 16.852551] ieee80211_handle_wake_tx_queue+0x68/0xb10 [mac80211] [ 16.858801] ieee80211_probereq_get+0xca4/0x11f0 [mac80211] [ 16.865049] ieee80211_tx_prepare_skb+0x1dc/0x240 [mac80211] [ 16.870432] ieee80211_xmit+0xcc/0x120 [mac80211] [ 16.876333] __ieee80211_subif_start_xmit+0x2b8/0x380 [mac80211] [ 16.880937] ieee80211_subif_start_xmit+0x40/0x3b0 [mac80211] [ 16.887013] ieee80211_subif_start_xmit_8023+0xb8/0x430 [mac80211] [ 16.892656] dev_hard_start_xmit+0x8c/0x110 [ 16.898728] __dev_queue_xmit+0x1f0/0xbc0 [ 16.902808] dev_queue_xmit+0x14/0x20 [ 16.906975] packet_sendmsg+0x768/0x1260 [ 16.910620] __sys_sendto+0xdc/0x140 [ 16.914613] __arm64_sys_sendto+0x28/0x40 [ 16.918174] invoke_syscall.constprop.0+0x5c/0x110 [ 16.922081] do_el0_svc+0x58/0x170 [ 16.926765] el0_svc+0x18/0x60 [ 16.930149] el0t_64_sync_handler+0x114/0x120 [ 16.933190] el0t_64_sync+0x174/0x178 [ 16.933197] ---[ end trace 0000000000000000 ]--- [ 16.933230] ath11k c000000.wifi: failed to transmit frame -22 [ 17.041495] ath11k c000000.wifi: encap mismatch in nss tx skb encap type 1vif encap type 2 [ 17.041578] ath11k c000000.wifi: failed to transmit frame -22 Which is confusing since the parameter is definitley set to '2'. ➤ cat /sys/module/ath11k/parameters/frame_mode 2 Booting with either "nss_offload=1 frame_mode=3" (RAW), or "nss_offload=1 frame_mode=1" (Native Wifi) Results in: [ 15.644742] ath11k c000000.wifi: peer not found for nss peer delete [ 15.744742] ath11k c000000.wifi: peer not found for nss peer delete [ 15.745742] ath11k c000000.wifi: peer not found for nss peer delete [ 15.746682] ath11k c000000.wifi: peer not found for nss peer delete Clients connect and then are immediately kicked off, stuck in a loop. --- package/kernel/mac80211/Makefile | 6 + package/kernel/mac80211/ath.mk | 25 +- ...dma-counter-increamenting-improperly.patch | 51 + ...nitor-crash-if-tx-offload-is-enabled.patch | 60 + .../107-ath11k-tid-counter-fix.patch | 21 + .../113-ath11k-add-8023-undecap-support.patch | 55 + ...-adding-support-for-mgmt-frame-stats.patch | 300 ++ ...-when-using-encapsulation-offloading.patch | 12 + ...91-ath11k-add-mgmt-and-data-ack-rssi.patch | 41 + .../199-001-mac80211-add-nss-support.patch | 461 +++ ...-ath11k_nss-add-nss-driver-interface.patch | 3008 +++++++++++++++++ .../199-003-ath11k-add-nss-support.patch | 1271 +++++++ ...-004-ath10k-add-nss-driver-interface.patch | 20 + ...th11k-Enable-512MB-profile-in-ath11k.patch | 1009 ++++++ ...14-ath11k-qos-null-frame-tx-over-wmi.patch | 520 +++ ...11k-Disable-rx_header-tlv-for-2K-SKB.patch | 856 +++++ ...-nss-thread-priority-during-pdev_ini.patch | 109 + ...avoid-stack-corrupt-in-nwifi-undecap.patch | 11 + ...e-free-of-peer-rx_tid-during-reo-cmd.patch | 40 + .../ath11k_nss/319-ath11k-nss-2K-SKB.patch | 37 + ...1k-skip-status-ring-entry-processing.patch | 191 ++ ...ccess-of-the-dma-buffer-back-to-dma-.patch | 28 + .../patches/ath11k_nss/999-fix-build.patch | 237 ++ 23 files changed, 8367 insertions(+), 2 deletions(-) create mode 100644 package/kernel/mac80211/patches/ath11k_nss/087-ath11k-fix-ul-ofdma-counter-increamenting-improperly.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/105-ath11k-fix-monitor-crash-if-tx-offload-is-enabled.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/107-ath11k-tid-counter-fix.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/113-ath11k-add-8023-undecap-support.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/142-ath11k-adding-support-for-mgmt-frame-stats.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/146-mac80211-enable-TKIP-when-using-encapsulation-offloading.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/191-ath11k-add-mgmt-and-data-ack-rssi.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/199-004-ath10k-add-nss-driver-interface.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-512MB-profile-in-ath11k.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/214-ath11k-qos-null-frame-tx-over-wmi.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/318-ath11k-avoid-stack-corrupt-in-nwifi-undecap.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/319-ath11k-fix-double-free-of-peer-rx_tid-during-reo-cmd.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/319-ath11k-nss-2K-SKB.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/336-ath11k-skip-status-ring-entry-processing.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/342-ath11k-provide-access-of-the-dma-buffer-back-to-dma-.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/999-fix-build.patch diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 17e0d9451e1c4b..31bb9aed055f30 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -273,6 +273,10 @@ ifeq ($(BUILD_VARIANT),smallbuffers) C_DEFINES+= -DCONFIG_ATH10K_SMALLBUFFERS endif +ifdef CONFIG_ATH11K_NSS_SUPPORT + IREMAP_CFLAGS+=-I$(STAGING_DIR)/usr/include/qca-nss-drv +endif + MAKE_OPTS:= \ $(subst -C $(LINUX_DIR),-C "$(PKG_BUILD_DIR)",$(KERNEL_MAKEOPTS)) \ EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/include $(IREMAP_CFLAGS) $(C_DEFINES)" \ @@ -341,6 +345,7 @@ define Build/Patch $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath9k,ath9k/) $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/) $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/) + $(if $(CONFIG_ATH11K_NSS_SUPPORT),$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k_nss,ath11k_nss/)) $(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/) @@ -357,6 +362,7 @@ define Quilt/Refresh/Package $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath9k,ath9k/) $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/) $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/) + $(if $(CONFIG_ATH11K_NSS_SUPPORT),$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k_nss,ath11k_nss/)) $(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/) diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk index 881c89db253dc6..170bb26b4d4c87 100644 --- a/package/kernel/mac80211/ath.mk +++ b/package/kernel/mac80211/ath.mk @@ -13,7 +13,9 @@ PKG_CONFIG_DEPENDS += \ CONFIG_ATH10K_LEDS \ CONFIG_ATH10K_THERMAL \ CONFIG_ATH11K_THERMAL \ - CONFIG_ATH_USER_REGD + CONFIG_ATH_USER_REGD \ + CONFIG_ATH11K_MEM_PROFILE_512M \ + CONFIG_ATH11K_NSS_SUPPORT ifdef CONFIG_PACKAGE_MAC80211_DEBUGFS config-y += \ @@ -56,6 +58,8 @@ config-$(CONFIG_ATH9K_UBNTHSR) += ATH9K_UBNTHSR config-$(CONFIG_ATH10K_LEDS) += ATH10K_LEDS config-$(CONFIG_ATH10K_THERMAL) += ATH10K_THERMAL config-$(CONFIG_ATH11K_THERMAL) += ATH11K_THERMAL +config-$(CONFIG_ATH11K_MEM_PROFILE_512M) += ATH11K_MEM_PROFILE_512M +config-$(CONFIG_ATH11K_NSS_SUPPORT) += ATH11K_NSS_SUPPORT config-$(call config_package,ath9k-htc) += ATH9K_HTC config-$(call config_package,ath10k) += ATH10K ATH10K_PCI @@ -302,9 +306,14 @@ define KernelPackage/ath11k TITLE:=Qualcomm 802.11ax wireless chipset support (common code) 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 + +kmod-crypto-michael-mic +ATH11K_THERMAL:kmod-hwmon-core +ATH11K_THERMAL:kmod-thermal \ + +ATH11K_NSS_SUPPORT:kmod-qca-nss-drv 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 + AUTOLOAD:=$(call AutoProbe,ath11k) + MODPARAMS.ath11k:=nss_offload=1 frame_mode=2 +endif endef define KernelPackage/ath11k/description @@ -319,6 +328,18 @@ define KernelPackage/ath11k/config depends on PACKAGE_kmod-ath11k default y if TARGET_qualcommax + config ATH11K_NSS_SUPPORT + bool "Enable NSS WiFi offload" + default y if TARGET_qualcommax + + if PACKAGE_kmod-ath11k + + config ATH11K_MEM_PROFILE_512M + bool "Use limits for the 512MB memory size" + default y if ATH11K_NSS_SUPPORT + help + This allows selecting the ath11k memory size profile to be used. + endif endef define KernelPackage/ath11k-ahb diff --git a/package/kernel/mac80211/patches/ath11k_nss/087-ath11k-fix-ul-ofdma-counter-increamenting-improperly.patch b/package/kernel/mac80211/patches/ath11k_nss/087-ath11k-fix-ul-ofdma-counter-increamenting-improperly.patch new file mode 100644 index 00000000000000..42495d7db3470b --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/087-ath11k-fix-ul-ofdma-counter-increamenting-improperly.patch @@ -0,0 +1,51 @@ + drivers/net/wireless/ath/ath11k/dp_rx.c | 3 ++- + drivers/net/wireless/ath/ath11k/hal_rx.c | 3 +++ + drivers/net/wireless/ath/ath11k/hal_rx.h | 2 ++ + 3 files changed, 7 insertions(+), 1 deletion(-) + +--- 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 + goto next_skb; + } + +- arsta = ath11k_sta_to_arsta(peer->sta); +- ath11k_dp_rx_update_peer_stats(arsta, ppdu_info); ++ 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); ++ } + + if (ath11k_debugfs_is_pktlog_peer_valid(ar, peer->addr)) + trace_ath11k_htt_rxdesc(ar, skb->data, log_type, rx_buf_sz); +--- a/drivers/net/wireless/ath/ath11k/hal_rx.c ++++ b/drivers/net/wireless/ath/ath11k/hal_rx.c +@@ -900,6 +900,9 @@ ath11k_hal_rx_parse_mon_status_tlv(struc + ppdu_info->ast_index = + FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO2_AST_INDEX, + __le32_to_cpu(eu_stats->info2)); ++ ppdu_info->fc_valid = ++ FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO1_FC_VALID, ++ __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; +--- 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 { + }; + + #define HAL_RX_FCS_LEN 4 ++#define HAL_AST_IDX_INVALID 0xFFFF + + enum hal_rx_mon_status { + HAL_RX_MON_STATUS_PPDU_NOT_DONE, +@@ -150,6 +151,7 @@ struct hal_rx_mon_ppdu_info { + u8 rssi_comb; + u8 rssi_chain_pri20[HAL_RX_MAX_NSS]; + u16 tid; ++ u8 fc_valid; + u16 ht_flags; + u16 vht_flags; + u16 he_flags; diff --git a/package/kernel/mac80211/patches/ath11k_nss/105-ath11k-fix-monitor-crash-if-tx-offload-is-enabled.patch b/package/kernel/mac80211/patches/ath11k_nss/105-ath11k-fix-monitor-crash-if-tx-offload-is-enabled.patch new file mode 100644 index 00000000000000..9304833c87d1c3 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/105-ath11k-fix-monitor-crash-if-tx-offload-is-enabled.patch @@ -0,0 +1,60 @@ + drivers/net/wireless/ath/ath11k/dp_tx.c | 20 +++++++++++++++++--- + 1 file changed, 17 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/dp_tx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_tx.c +@@ -322,6 +322,8 @@ ath11k_dp_tx_htt_tx_complete_buf(struct + struct ath11k_skb_cb *skb_cb; + struct ath11k *ar; + struct ath11k_peer *peer; ++ struct ieee80211_vif *vif; ++ u8 flags = 0; + + spin_lock(&tx_ring->tx_idr_lock); + msdu = idr_remove(&tx_ring->txbuf_idr, ts->msdu_id); +@@ -348,6 +350,14 @@ ath11k_dp_tx_htt_tx_complete_buf(struct + return; + } + ++ if (!skb_cb->vif) { ++ dev_kfree_skb_any(msdu); ++ return; ++ } ++ ++ flags = skb_cb->flags; ++ vif = skb_cb->vif; ++ + memset(&info->status, 0, sizeof(info->status)); + + if (ts->acked) { +@@ -555,6 +565,8 @@ static void ath11k_dp_tx_complete_msdu(s + struct ath11k_peer *peer; + struct ath11k_sta *arsta; + struct rate_info rate; ++ struct ieee80211_vif *vif; ++ u8 flags = 0; + + if (WARN_ON_ONCE(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) { + /* Must not happen */ +@@ -575,6 +587,9 @@ static void ath11k_dp_tx_complete_msdu(s + return; + } + ++ flags = skb_cb->flags; ++ vif = skb_cb->vif; ++ + info = IEEE80211_SKB_CB(msdu); + memset(&info->status, 0, sizeof(info->status)); + +@@ -641,7 +656,10 @@ static void ath11k_dp_tx_complete_msdu(s + + spin_unlock_bh(&ab->base_lock); + +- ieee80211_tx_status_ext(ar->hw, &status); ++ if (flags & ATH11K_SKB_HW_80211_ENCAP) ++ ieee80211_tx_status_8023(ar->hw, vif, msdu); ++ else ++ ieee80211_tx_status_ext(ar->hw, &status); + } + + static inline void ath11k_dp_tx_status_parse(struct ath11k_base *ab, 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 new file mode 100644 index 00000000000000..1826e64bbcba05 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/107-ath11k-tid-counter-fix.patch @@ -0,0 +1,21 @@ +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/113-ath11k-add-8023-undecap-support.patch b/package/kernel/mac80211/patches/ath11k_nss/113-ath11k-add-8023-undecap-support.patch new file mode 100644 index 00000000000000..8ef3d9ba7c4d91 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/113-ath11k-add-8023-undecap-support.patch @@ -0,0 +1,55 @@ +--- 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 + ether_addr_copy(ieee80211_get_SA(hdr), sa); + } + ++static void ath11k_dp_rx_h_undecap_snap(struct ath11k *ar, ++ struct sk_buff *msdu, ++ u8 *first_hdr, ++ enum hal_encrypt_type enctype, ++ struct ieee80211_rx_status *status) ++{ ++ struct ieee80211_hdr *hdr; ++ size_t hdr_len; ++ u8 l3_pad_bytes; ++ struct hal_rx_desc *rx_desc; ++ ++ /* Delivered decapped frame: ++ * [amsdu header] <-- replaced with 802.11 hdr ++ * [rfc1042/llc] ++ * [payload] ++ */ ++ ++ rx_desc = (void *)msdu->data - sizeof(*rx_desc); ++ l3_pad_bytes = ath11k_dp_rx_h_msdu_end_l3pad(ar->ab, rx_desc); ++ ++ skb_put(msdu, l3_pad_bytes); ++ skb_pull(msdu, sizeof(struct ath11k_dp_amsdu_subframe_hdr) + l3_pad_bytes); ++ ++ hdr = (struct ieee80211_hdr *)first_hdr; ++ 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)); ++ } ++ ++ memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); ++} ++ + 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 + enctype, status); + break; + case DP_RX_DECAP_TYPE_8023: +- /* TODO: Handle undecap for these formats */ ++ ath11k_dp_rx_h_undecap_snap(ar, msdu, first_hdr, ++ enctype, status); + break; + } + } diff --git a/package/kernel/mac80211/patches/ath11k_nss/142-ath11k-adding-support-for-mgmt-frame-stats.patch b/package/kernel/mac80211/patches/ath11k_nss/142-ath11k-adding-support-for-mgmt-frame-stats.patch new file mode 100644 index 00000000000000..61feac0f6cb6e6 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/142-ath11k-adding-support-for-mgmt-frame-stats.patch @@ -0,0 +1,300 @@ +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -311,6 +311,16 @@ struct ath11k_rekey_data { + bool enable_offload; + }; + ++#define ATH11K_STATS_MGMT_FRM_TYPE_MAX 16 ++ ++struct ath11k_mgmt_frame_stats { ++ u32 tx_succ_cnt[ATH11K_STATS_MGMT_FRM_TYPE_MAX]; ++ u32 tx_fail_cnt[ATH11K_STATS_MGMT_FRM_TYPE_MAX]; ++ u32 rx_cnt[ATH11K_STATS_MGMT_FRM_TYPE_MAX]; ++ u32 tx_compl_succ[ATH11K_STATS_MGMT_FRM_TYPE_MAX]; ++ u32 tx_compl_fail[ATH11K_STATS_MGMT_FRM_TYPE_MAX]; ++}; ++ + struct ath11k_vif { + u32 vdev_id; + enum wmi_vdev_type vdev_type; +@@ -369,6 +379,8 @@ struct ath11k_vif { + #ifdef CPTCFG_ATH11K_DEBUGFS + struct dentry *debugfs_twt; + #endif /* CPTCFG_ATH11K_DEBUGFS */ ++ ++ struct ath11k_mgmt_frame_stats mgmt_stats; + }; + + struct ath11k_vif_iter { +@@ -901,6 +913,7 @@ struct ath11k_base { + struct list_head peers; + wait_queue_head_t peer_mapping_wq; + u8 mac_addr[ETH_ALEN]; ++ int userpd_id; + int irq_num[ATH11K_IRQ_NUM_MAX]; + struct ath11k_ext_irq_grp ext_irq_grp[ATH11K_EXT_IRQ_GRP_NUM_MAX]; + struct ath11k_targ_cap target_caps; +--- a/drivers/net/wireless/ath/ath11k/debugfs.c ++++ b/drivers/net/wireless/ath/ath11k/debugfs.c +@@ -1588,6 +1588,87 @@ static const struct file_operations fops + .llseek = default_llseek, + }; + ++static ssize_t ath11k_dump_mgmt_stats(struct file *file, char __user *ubuf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath11k *ar = file->private_data; ++ struct ath11k_vif *arvif = NULL; ++ struct ath11k_mgmt_frame_stats *mgmt_stats; ++ int len = 0, ret, i; ++ int size = (TARGET_NUM_VDEVS - 1) * 1500; ++ char *buf; ++ const char *mgmt_frm_type[ATH11K_STATS_MGMT_FRM_TYPE_MAX-1] = {"assoc_req", "assoc_resp", ++ "reassoc_req", "reassoc_resp", ++ "probe_req", "probe_resp", ++ "timing_advertisement", "reserved", ++ "beacon", "atim", "disassoc", ++ "auth", "deauth", "action", "action_no_ack"}; ++ ++ if (ar->state != ATH11K_STATE_ON) ++ return -ENETDOWN; ++ ++ buf = kzalloc(size, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ mutex_lock(&ar->conf_mutex); ++ spin_lock_bh(&ar->data_lock); ++ ++ list_for_each_entry (arvif, &ar->arvifs, list) { ++ if (!arvif) ++ break; ++ ++ if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) ++ continue; ++ ++ mgmt_stats = &arvif->mgmt_stats; ++ len += scnprintf(buf + len, size - len, "MGMT frame stats for vdev %u :\n", ++ arvif->vdev_id); ++ len += scnprintf(buf + len, size - len, " TX stats :\n "); ++ len += scnprintf(buf + len, size - len, " Success frames:\n"); ++ for (i = 0; i < ATH11K_STATS_MGMT_FRM_TYPE_MAX-1; i++) ++ len += scnprintf(buf + len, size - len, " %s: %d\n", mgmt_frm_type[i], ++ mgmt_stats->tx_succ_cnt[i]); ++ ++ len += scnprintf(buf + len, size - len, " Failed frames:\n"); ++ ++ for (i = 0; i < ATH11K_STATS_MGMT_FRM_TYPE_MAX-1; i++) ++ len += scnprintf(buf + len, size - len, " %s: %d\n", mgmt_frm_type[i], ++ mgmt_stats->tx_fail_cnt[i]); ++ ++ len += scnprintf(buf + len, size - len, " RX stats :\n"); ++ len += scnprintf(buf + len, size - len, " Success frames:\n"); ++ for (i = 0; i < ATH11K_STATS_MGMT_FRM_TYPE_MAX-1; i++) ++ len += scnprintf(buf + len, size - len, " %s: %d\n", mgmt_frm_type[i], ++ mgmt_stats->rx_cnt[i]); ++ ++ len += scnprintf(buf + len, size - len, " Tx completion stats :\n"); ++ len += scnprintf(buf + len, size - len, " success completions:\n"); ++ for (i = 0; i < ATH11K_STATS_MGMT_FRM_TYPE_MAX-1; i++) ++ len += scnprintf(buf + len, size - len, " %s: %d\n", mgmt_frm_type[i], ++ mgmt_stats->tx_compl_succ[i]); ++ len += scnprintf(buf + len, size - len, " failure completions:\n"); ++ for (i = 0; i < ATH11K_STATS_MGMT_FRM_TYPE_MAX-1; i++) ++ len += scnprintf(buf + len, size - len, " %s: %d\n", mgmt_frm_type[i], ++ mgmt_stats->tx_compl_fail[i]); ++ } ++ ++ spin_unlock_bh(&ar->data_lock); ++ ++ if (len > size) ++ len = size; ++ ++ ret = simple_read_from_buffer(ubuf, count, ppos, buf, len); ++ mutex_unlock(&ar->conf_mutex); ++ kfree(buf); ++ return ret; ++} ++ ++static const struct file_operations fops_dump_mgmt_stats = { ++ .read = ath11k_dump_mgmt_stats, ++ .open = simple_open ++}; ++ + int ath11k_debugfs_register(struct ath11k *ar) + { + struct ath11k_base *ab = ar->ab; +@@ -1620,6 +1701,9 @@ int ath11k_debugfs_register(struct ath11 + 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, +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -6146,9 +6146,9 @@ static int ath11k_mac_mgmt_tx(struct ath + */ + if (is_prb_rsp && + atomic_read(&ar->num_pending_mgmt_tx) > ATH11K_PRB_RSP_DROP_THRESHOLD) { +- ath11k_warn(ar->ab, ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, + "dropping probe response as pending queue is almost full\n"); +- return -ENOSPC; ++ return -EBUSY; + } + + if (skb_queue_len_lockless(q) >= ATH11K_TX_MGMT_NUM_PENDING_MAX) { +@@ -6174,9 +6174,11 @@ static void ath11k_mac_op_tx(struct ieee + struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_key_conf *key = info->control.hw_key; ++ struct ath11k_mgmt_frame_stats *mgmt_stats = &arvif->mgmt_stats; + struct ath11k_sta *arsta = NULL; + u32 info_flags = info->flags; + bool is_prb_rsp; ++ u16 frm_type = 0; + int ret; + + memset(skb_cb, 0, sizeof(*skb_cb)); +@@ -6190,12 +6192,21 @@ static void ath11k_mac_op_tx(struct ieee + if (info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { + skb_cb->flags |= ATH11K_SKB_HW_80211_ENCAP; + } else if (ieee80211_is_mgmt(hdr->frame_control)) { ++ frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, hdr->frame_control); + is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control); + ret = ath11k_mac_mgmt_tx(ar, skb, is_prb_rsp); + if (ret) { +- ath11k_warn(ar->ab, "failed to queue management frame %d\n", +- ret); ++ if (ret != -EBUSY) ++ ath11k_warn(ar->ab, "failed to queue management frame %d\n", ++ ret); + ieee80211_free_txskb(ar->hw, skb); ++ spin_lock_bh(&ar->data_lock); ++ mgmt_stats->tx_fail_cnt[frm_type]++; ++ spin_unlock_bh(&ar->data_lock); ++ } else { ++ spin_lock_bh(&ar->data_lock); ++ mgmt_stats->tx_succ_cnt[frm_type]++; ++ spin_unlock_bh(&ar->data_lock); + } + return; + } +--- 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 + + peer->sec_type = HAL_ENCRYPT_TYPE_OPEN; + peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; ++ peer->vif = arvif->vif; + + if (sta) { + 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 @@ + struct ath11k_peer { + struct list_head list; + struct ieee80211_sta *sta; ++ struct ieee80211_vif *vif; + int vdev_id; + u8 addr[ETH_ALEN]; + int peer_id; +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -5823,6 +5823,12 @@ static int wmi_process_mgmt_tx_comp(stru + struct sk_buff *msdu; + 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->txmgmt_idr_lock); +@@ -5850,6 +5856,31 @@ static int wmi_process_mgmt_tx_comp(stru + info->status.ack_signal = tx_compl_param->ack_rssi; + } + ++ 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 (!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); +@@ -7519,6 +7550,11 @@ static void ath11k_mgmt_rx_event(struct + struct ieee80211_hdr *hdr; + u16 fc; + struct ieee80211_supported_band *sband; ++ struct ath11k_peer *peer; ++ struct ieee80211_vif *vif; ++ struct ath11k_vif *arvif; ++ struct ath11k_mgmt_frame_stats *mgmt_stats; ++ u16 frm_type = 0; + + if (ath11k_pull_mgmt_rx_params_tlv(ab, skb, &rx_ev) != 0) { + ath11k_warn(ab, "failed to extract mgmt rx event"); +@@ -7584,7 +7620,34 @@ static void ath11k_mgmt_rx_event(struct + + hdr = (struct ieee80211_hdr *)skb->data; + fc = le16_to_cpu(hdr->frame_control); ++ frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, fc); ++ ++ spin_lock_bh(&ab->base_lock); ++ ++ peer = ath11k_peer_find_by_addr(ab, hdr->addr1); ++ if(!peer) ++ peer = ath11k_peer_find_by_addr(ab, hdr->addr3); ++ if (!peer) { ++ spin_unlock_bh(&ab->base_lock); ++ goto skip_mgmt_stats; ++ } ++ ++ vif = peer->vif; ++ ++ spin_unlock_bh(&ab->base_lock); ++ ++ if (!vif) ++ goto skip_mgmt_stats; ++ ++ spin_lock_bh(&ar->data_lock); ++ ++ arvif = ath11k_vif_to_arvif(vif); ++ mgmt_stats = &arvif->mgmt_stats; ++ mgmt_stats->rx_cnt[frm_type]++; ++ ++ spin_unlock_bh(&ar->data_lock); + ++skip_mgmt_stats: + /* Firmware is guaranteed to report all essential management frames via + * WMI while it can deliver some extra via HTT. Since there can be + * duplicates split the reporting wrt monitor/sniffing. diff --git a/package/kernel/mac80211/patches/ath11k_nss/146-mac80211-enable-TKIP-when-using-encapsulation-offloading.patch b/package/kernel/mac80211/patches/ath11k_nss/146-mac80211-enable-TKIP-when-using-encapsulation-offloading.patch new file mode 100644 index 00000000000000..82d8c4e05bb11f --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/146-mac80211-enable-TKIP-when-using-encapsulation-offloading.patch @@ -0,0 +1,12 @@ +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -4686,8 +4686,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8 + if (!key) + key = rcu_dereference(sdata->default_unicast_key); + +- if (key && (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) || +- key->conf.cipher == WLAN_CIPHER_SUITE_TKIP)) ++ if (key && (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))) + goto skip_offload; + + sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift); diff --git a/package/kernel/mac80211/patches/ath11k_nss/191-ath11k-add-mgmt-and-data-ack-rssi.patch b/package/kernel/mac80211/patches/ath11k_nss/191-ath11k-add-mgmt-and-data-ack-rssi.patch new file mode 100644 index 00000000000000..202439056c43da --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/191-ath11k-add-mgmt-and-data-ack-rssi.patch @@ -0,0 +1,41 @@ +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -9623,6 +9623,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; +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -4065,6 +4065,7 @@ 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; +@@ -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,8 @@ struct wmi_pdev_bss_chan_info_event { + u32 rx_bss_cycle_count_low; + u32 rx_bss_cycle_count_high; + u32 pdev_id; ++ u32 ppdu_id; ++ u32 ack_rssi; + } __packed; + + #define WMI_VDEV_INSTALL_KEY_COMPL_STATUS_SUCCESS 0 diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch b/package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch new file mode 100644 index 00000000000000..0b017ec97ad24d --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch @@ -0,0 +1,461 @@ +From 193bfea2185a0ee976f54812e41ace77e6ee85e4 Mon Sep 17 00:00:00 2001 +From: Sriram R +Date: Fri, 10 Jul 2020 12:46:12 +0530 +Subject: [PATCH 1/3] mac80211: add nss support + +Add Support for NSS Offload if the HW supports it. +New flag is introduced to indicate HW support for NSS +offload + +Signed-off-by: Sriram R +--- + include/net/mac80211.h | 13 +++++++++++++ + net/mac80211/debugfs.c | 1 + + net/mac80211/util.c | 16 ++++++++++++++++ + 3 files changed, 30 insertions(+) + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -380,6 +380,20 @@ enum ieee80211_bss_change { + /* when adding here, make sure to change ieee80211_reconfig */ + }; + ++/** ++ * enum ieee80211_nss_bss_change - NSS BSS change notification flags ++ * ++ * These flags are used with the nss_bss_info_changed() callback ++ * to indicate which NSS BSS parameter changed. ++ * ++ * @BSS_CHANGED_NSS_AP_ISOLATE: AP Isolate feature in NSS mode ++ * ++ */ ++ ++enum ieee80211_nss_bss_change { ++ BSS_CHANGED_NSS_AP_ISOLATE = BIT(0), ++}; ++ + /* + * The maximum number of IPv4 addresses listed for ARP filtering. If the number + * of addresses for an interface increase beyond this value, hardware ARP +@@ -683,6 +697,7 @@ struct ieee80211_fils_discovery { + * beamformee + * @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 + */ + struct ieee80211_bss_conf { + struct ieee80211_vif *vif; +@@ -776,6 +791,7 @@ struct ieee80211_bss_conf { + bool eht_su_beamformer; + bool eht_su_beamformee; + bool eht_mu_beamformer; ++ bool nss_ap_isolate; + }; + + /** +@@ -1406,7 +1422,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 +- * ++ * + * - DATA3_DATA_MCS + * - DATA3_DATA_DCM + * - DATA3_CODING +@@ -1414,7 +1430,7 @@ ieee80211_tx_info_clear_status(struct ie + * - DATA5_DATA_BW_RU_ALLOC + * - DATA6_NSTS + * - DATA3_STBC +- * ++ * + * 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 + lockdep_vif_mutex_held(vif)) + + /** ++ * ieee80211_vif_to_wdev_relaxed - return a wdev struct from a vif ++ * @vif: the vif to get the wdev for ++ * ++ * This function is similar to ieee80211_vif_to_wdev, but the wdev ++ * is returned even if sdata is not running. ++ * ++ */ ++struct wireless_dev *ieee80211_vif_to_wdev_relaxed(struct ieee80211_vif *vif); ++ ++/** + * enum ieee80211_key_flags - key flags + * + * These flags are used for communication about keys between the driver +@@ -2677,6 +2703,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. + * ++ * @IEEE80211_HW_SUPPORTS_NSS_OFFLOAD: Hardware/driver supports NSS offload ++ * + * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays + */ + enum ieee80211_hw_flags { +@@ -2734,6 +2762,7 @@ enum ieee80211_hw_flags { + IEEE80211_HW_SUPPORTS_CONC_MON_RX_DECAP, + IEEE80211_HW_DETECTS_COLOR_COLLISION, + IEEE80211_HW_MLO_MCAST_MULTI_LINK_TX, ++ IEEE80211_HW_SUPPORTS_NSS_OFFLOAD, + + /* keep last, obviously */ + NUM_IEEE80211_HW_FLAGS +@@ -3746,6 +3775,10 @@ struct ieee80211_prep_tx_info { + * non-MLO connections. + * The callback can sleep. + * ++ * @nss_bss_info_changed: Handler for configuration requests related to NSS BSS ++ * parameters that may vary during BSS's lifespan, and may affect low level ++ * driver. ++ * + * @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 { + 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); + 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 { + int (*reset_tid_config)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, u8 tids); +- void (*update_vif_offload)(struct ieee80211_hw *hw, ++ int (*update_vif_offload)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); + void (*sta_set_4addr)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + 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[] = { + FLAG(SUPPORTS_CONC_MON_RX_DECAP), + FLAG(DETECTS_COLOR_COLLISION), + FLAG(MLO_MCAST_MULTI_LINK_TX), ++ FLAG(SUPPORTS_NSS_OFFLOAD), + #undef FLAG + }; + +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -868,6 +868,22 @@ struct wireless_dev *ieee80211_vif_to_wd + } + EXPORT_SYMBOL_GPL(ieee80211_vif_to_wdev); + ++struct wireless_dev *ieee80211_vif_to_wdev_relaxed(struct ieee80211_vif *vif) ++{ ++ struct ieee80211_sub_if_data *sdata; ++ ++ if (!vif) ++ return NULL; ++ ++ sdata = vif_to_sdata(vif); ++ ++ if (sdata) ++ return &sdata->wdev; ++ ++ return NULL; ++} ++EXPORT_SYMBOL(ieee80211_vif_to_wdev_relaxed); ++ + /* + * Nothing should have been stuffed into the workqueue during + * the suspend->resume cycle. Since we can't check each caller +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -291,6 +291,17 @@ void ieee80211_link_info_change_notify(s + drv_link_info_changed(local, sdata, link->conf, link->link_id, changed); + } + ++void ieee80211_nss_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, ++ u64 changed) ++{ ++ struct ieee80211_local *local = sdata->local; ++ ++ if (!changed || sdata->vif.type == NL80211_IFTYPE_AP_VLAN) ++ return; ++ ++ drv_nss_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed); ++} ++ + 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_ + NL80211_FEATURE_FULL_AP_CLIENT_STATE; + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_STA); + wiphy_ext_feature_set(wiphy, +- NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211); +- wiphy_ext_feature_set(wiphy, +- NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH); +- wiphy_ext_feature_set(wiphy, +- NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS); +- wiphy_ext_feature_set(wiphy, + 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 + return -EINVAL; + } + ++ /* Control port over nl80211 is disabled for nss offload as ++ * sending per packet tx status is not supported and only ++ * rx over netdev from driver is done currently */ ++ if (!ieee80211_hw_check(hw, SUPPORTS_NSS_OFFLOAD)) { ++ wiphy_ext_feature_set(hw->wiphy, ++ NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211); ++ wiphy_ext_feature_set(hw->wiphy, ++ NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH); ++ wiphy_ext_feature_set(hw->wiphy, ++ NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS); ++ } ++ + #ifdef CONFIG_PM + if (hw->wiphy->wowlan && (!local->ops->suspend || !local->ops->resume)) + return -EINVAL; +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -2379,6 +2379,9 @@ sta_get_last_rx_stats(struct sta_info *s + struct ieee80211_sta_rx_stats *stats = &sta->deflink.rx_stats; + int cpu; + ++ if (ieee80211_hw_check(&sta->local->hw, SUPPORTS_NSS_OFFLOAD)) ++ return stats; ++ + if (!sta->deflink.pcpu_rx_stats) + return stats; + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -1028,11 +1028,23 @@ ieee80211_tx_h_stats(struct ieee80211_tx + { + struct sk_buff *skb; + int ac = -1; ++ struct ieee80211_hdr *hdr; ++ bool nss_offload; + + if (!tx->sta) + return TX_CONTINUE; + ++ nss_offload = ieee80211_hw_check(&tx->local->hw, SUPPORTS_NSS_OFFLOAD); ++ + skb_queue_walk(&tx->skbs, skb) { ++ /* Do not increment stats for data packets if NSS offload is enabled. ++ * As we use the stats from NSS, this will be a duplication ++ */ ++ if (nss_offload) { ++ hdr = (void *) skb->data; ++ if (ieee80211_is_data(hdr->frame_control)) ++ continue; ++ } + 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 + + if (unlikely(!multicast && ((skb->sk && + skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) || +- ctrl_flags & IEEE80211_TX_CTL_REQ_TX_STATUS))) ++ ctrl_flags & IEEE80211_TX_CTL_REQ_TX_STATUS) && ++ !(ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD) && ++ ieee80211_is_data(fc) && !ieee80211_is_qos_nullfunc(fc)))) + info_id = ieee80211_store_ack_skb(local, skb, &info_flags, + cookie); + +@@ -4639,13 +4653,16 @@ static void ieee80211_8023_xmit(struct i + } + + if (unlikely(skb->sk && +- skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) ++ skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS && ++ !ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD))) + info->ack_frame_id = ieee80211_store_ack_skb(local, skb, + &info->flags, NULL); + + dev_sw_netstats_tx_add(dev, skbs, len); +- sta->deflink.tx_stats.packets[queue] += skbs; +- sta->deflink.tx_stats.bytes[queue] += len; ++ if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) { ++ sta->deflink.tx_stats.packets[queue] += skbs; ++ sta->deflink.tx_stats.bytes[queue] += len; ++ } + + ieee80211_tpt_led_trig_tx(local, len); + +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -2447,6 +2447,9 @@ bool cfg80211_does_bw_fit_range(const st + + int cfg80211_sinfo_alloc_tid_stats(struct station_info *sinfo, gfp_t gfp) + { ++ if(sinfo->pertid) ++ return 0; ++ + sinfo->pertid = kcalloc(IEEE80211_NUM_TIDS + 1, + sizeof(*(sinfo->pertid)), + gfp); +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -2675,7 +2675,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; +- u64 changed = 0; ++ u32 changed = 0, nss_changed = 0; + + 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 + sdata->flags |= IEEE80211_SDATA_DONT_BRIDGE_PACKETS; + else + sdata->flags &= ~IEEE80211_SDATA_DONT_BRIDGE_PACKETS; ++ sdata->vif.bss_conf.nss_ap_isolate = params->ap_isolate; ++ nss_changed |= BSS_CHANGED_NSS_AP_ISOLATE; + ieee80211_check_fast_rx_iface(sdata); + } + +@@ -2753,6 +2755,8 @@ static int ieee80211_change_bss(struct w + + ieee80211_link_info_change_notify(sdata, link, changed); + ++ ieee80211_nss_bss_info_change_notify(sdata, nss_changed); ++ + return 0; + } + +--- a/net/mac80211/driver-ops.h ++++ b/net/mac80211/driver-ops.h +@@ -172,6 +172,23 @@ void drv_link_info_changed(struct ieee80 + struct ieee80211_bss_conf *info, + int link_id, u64 changed); + ++static inline void drv_nss_bss_info_changed(struct ieee80211_local *local, ++ struct ieee80211_sub_if_data *sdata, ++ struct ieee80211_bss_conf *info, ++ u32 changed) ++{ ++ might_sleep(); ++ ++ if (!check_sdata_in_driver(sdata)) ++ return; ++ ++ trace_drv_nss_bss_info_changed(local, sdata, info, changed); ++ if (local->ops->nss_bss_info_changed) { ++ local->ops->nss_bss_info_changed(&local->hw, &sdata->vif, changed); ++ } ++ trace_drv_nss_return_void(local); ++} ++ + static inline u64 drv_prepare_multicast(struct ieee80211_local *local, + struct netdev_hw_addr_list *mc_list) + { +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1845,6 +1845,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); ++void ieee80211_nss_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, ++ u64 changed); + void ieee80211_configure_filter(struct ieee80211_local *local); + u64 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata); + +--- a/net/mac80211/trace.h ++++ b/net/mac80211/trace.h +@@ -389,6 +389,38 @@ TRACE_EVENT(drv_config, + LOCAL_PR_ARG, __entry->changed, CHANDEF_PR_ARG + ) + ); ++TRACE_EVENT(drv_nss_bss_info_changed, ++ TP_PROTO(struct ieee80211_local *local, ++ struct ieee80211_sub_if_data *sdata, ++ struct ieee80211_bss_conf *info, ++ u32 changed), ++ ++ TP_ARGS(local, sdata, info, changed), ++ ++ TP_STRUCT__entry( ++ LOCAL_ENTRY ++ VIF_ENTRY ++ __field(u32, changed) ++ __field(bool, nss_ap_isolate); ++ ), ++ ++ TP_fast_assign( ++ LOCAL_ASSIGN; ++ VIF_ASSIGN; ++ __entry->changed = changed; ++ __entry->nss_ap_isolate = info->nss_ap_isolate; ++ ), ++ ++ TP_printk( ++ LOCAL_PR_FMT VIF_PR_FMT " changed:%#x", ++ LOCAL_PR_ARG, VIF_PR_ARG, __entry->changed ++ ) ++); ++ ++DEFINE_EVENT(local_only_evt, drv_nss_return_void, ++ TP_PROTO(struct ieee80211_local *local), ++ TP_ARGS(local) ++); + + TRACE_EVENT(drv_vif_cfg_changed, + TP_PROTO(struct ieee80211_local *local, +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -969,7 +969,8 @@ static bool ieee80211_set_sdata_offload_ + local->hw.wiphy->frag_threshold != (u32)-1) + flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED; + +- if (local->monitors) ++ if (local->monitors && ++ !ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) + flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED; + } else { + flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED; +--- a/net/mac80211/Kconfig ++++ b/net/mac80211/Kconfig +@@ -104,6 +104,15 @@ menuconfig MAC80211_DEBUG_MENU + help + This option collects various mac80211 debug settings. + ++config MAC80211_NSS_SUPPORT ++ bool "QTI mac80211 nss support" ++ depends on ATH11K_NSS_SUPPORT ++ default n ++ ---help--- ++ Enables NSS offload support for ATH11K driver ++ ++ If unsure, say Y to enable NSS offload support. ++ + config MAC80211_NOINLINE + bool "Do not inline TX/RX handlers" + depends on MAC80211_DEBUG_MENU +--- a/local-symbols ++++ b/local-symbols +@@ -65,6 +65,7 @@ MAC80211_MESH_PS_DEBUG= + MAC80211_TDLS_DEBUG= + MAC80211_DEBUG_COUNTERS= + MAC80211_STA_HASH_MAX_SIZE= ++MAC80211_NSS_SUPPORT= + QCOM_AOSS_QMP= + QCOM_COMMAND_DB= + QCOM_CPR= +@@ -174,6 +175,7 @@ ATH11K_DEBUGFS= + ATH11K_TRACING= + ATH11K_SPECTRAL= + ATH11K_THERMAL= ++ATH11K_MEM_PROFILE_512M= + ATH12K= + ATH12K_DEBUG= + ATH12K_TRACING= diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch b/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch new file mode 100644 index 00000000000000..d9be673c93f5f9 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch @@ -0,0 +1,3008 @@ +From 0fa55ca418c8afd6da242407a184c23548c553dc Mon Sep 17 00:00:00 2001 +From: Sriram R +Date: Fri, 5 Jun 2020 12:21:15 +0530 +Subject: [PATCH 2/3] ath11k: Add nss driver interface + +This patch adds interface support for accessing nss driver with +support for initialization, teardown, vap up/down, peer create/delete, +tx/rx. NSS Stats addition is not part of this version. + +Signed-off-by: Sriram R +--- + drivers/net/wireless/ath/ath11k/Kconfig | 9 + + drivers/net/wireless/ath/ath11k/Makefile | 1 + + drivers/net/wireless/ath/ath11k/nss.c | 1762 ++++++++++++++++++++++++++++++ + drivers/net/wireless/ath/ath11k/nss.h | 217 ++++ + 4 files changed, 1989 insertions(+) + create mode 100644 drivers/net/wireless/ath/ath11k/nss.c + create mode 100644 drivers/net/wireless/ath/ath11k/nss.h + +--- a/drivers/net/wireless/ath/ath11k/Kconfig ++++ b/drivers/net/wireless/ath/ath11k/Kconfig +@@ -13,6 +13,16 @@ config ATH11K + + If you choose to build a module, it'll be called ath11k. + ++config ATH11K_NSS_SUPPORT ++ bool "QCA ath11k nss support" ++ depends on ATH11K ++ default n ++ select MAC80211_NSS_SUPPORT ++ ---help--- ++ Enables NSS offload support for ATH11K driver ++ ++ If unsure, say Y to enable NSS offload support. ++ + config ATH11K_AHB + tristate "Atheros ath11k AHB support" + depends on m +--- a/drivers/net/wireless/ath/ath11k/Makefile ++++ b/drivers/net/wireless/ath/ath11k/Makefile +@@ -25,6 +25,7 @@ ath11k-$(CPTCFG_ATH11K_TRACING) += trace + ath11k-$(CPTCFG_ATH11K_THERMAL) += thermal.o + ath11k-$(CPTCFG_ATH11K_SPECTRAL) += spectral.o + ath11k-$(CONFIG_PM) += wow.o ++ath11k-$(CPTCFG_ATH11K_NSS_SUPPORT) += nss.o + + obj-$(CPTCFG_ATH11K_AHB) += ath11k_ahb.o + ath11k_ahb-y += ahb.o +--- /dev/null ++++ b/drivers/net/wireless/ath/ath11k/nss.c +@@ -0,0 +1,2392 @@ ++// SPDX-License-Identifier: BSD-3-Clause-Clear ++/* ++ * Copyright (c) 2020 The Linux Foundation. All rights reserved. ++ */ ++ ++#include "debug.h" ++#include "mac.h" ++#include "nss.h" ++#include "core.h" ++#include "peer.h" ++#include "hif.h" ++#include "wmi.h" ++#include "../../../../../net/mac80211/sta_info.h" ++ ++/*-----------------------------ATH11K-NSS Helpers--------------------------*/ ++ ++static enum ath11k_nss_opmode ++ath11k_nss_get_vdev_opmode(struct ath11k_vif *arvif) ++{ ++ switch (arvif->vdev_type) { ++ case WMI_VDEV_TYPE_AP: ++ return ATH11K_NSS_OPMODE_AP; ++ case WMI_VDEV_TYPE_STA: ++ return ATH11K_NSS_OPMODE_STA; ++ default: ++ ath11k_warn(arvif->ar->ab, "unsupported nss vdev type %d\n", ++ arvif->vdev_type); ++ } ++ ++ return ATH11K_NSS_OPMODE_UNKNOWN; ++} ++ ++static void ath11k_nss_wifili_stats_sync(struct ath11k_base *ab, ++ struct nss_wifili_stats_sync_msg *wlsoc_stats) ++{ ++ struct nss_wifili_device_stats *devstats = &wlsoc_stats->stats; ++ struct ath11k_soc_dp_stats *soc_stats = &ab->soc_stats; ++ int i; ++ ++ spin_lock_bh(&ab->base_lock); ++ ++ soc_stats->err_ring_pkts += devstats->rxwbm_stats.err_src_rxdma; ++ soc_stats->invalid_rbm += devstats->rxwbm_stats.invalid_buf_mgr; ++ ++ for (i = 0; i < HAL_REO_ENTR_RING_RXDMA_ECODE_MAX; i++) ++ soc_stats->rxdma_error[i] += devstats->rxwbm_stats.err_dma_codes[i]; ++ ++ for (i = 0; i < HAL_REO_DEST_RING_ERROR_CODE_MAX; i++) ++ soc_stats->reo_error[i] += devstats->rxwbm_stats.err_reo_codes[i]; ++ ++ for (i = 0; i < DP_REO_DST_RING_MAX; i++) ++ soc_stats->hal_reo_error[i] += devstats->rxreo_stats[i].ring_error; ++ ++ for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) ++ soc_stats->tx_err.desc_na[i] += devstats->tcl_stats[i].tcl_ring_full; ++ ++ ++ for (i = 0; i < NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG; i++) ++ atomic_add(devstats->txcomp_stats[i].invalid_bufsrc ++ + devstats->txcomp_stats[i].invalid_cookie ++ + devstats->tx_sw_pool_stats[i].desc_alloc_fail ++ + devstats->tx_ext_sw_pool_stats[i].desc_alloc_fail, ++ &soc_stats->tx_err.misc_fail); ++ ++ for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) ++ atomic_add(devstats->tx_data_stats[i].tx_send_fail_cnt, ++ &soc_stats->tx_err.misc_fail); ++ ++ spin_unlock_bh(&ab->base_lock); ++} ++ ++static void ath11k_nss_get_peer_stats(struct ath11k_base *ab, struct nss_wifili_peer_stats *stats) ++{ ++ struct ath11k_peer *peer; ++ struct nss_wifili_peer_ctrl_stats *pstats = NULL; ++ int i, j; ++ u64 tx_packets, tx_bytes, tx_dropped = 0; ++ u64 rx_packets, rx_bytes, rx_dropped; ++ ++ if (!ab->nss.stats_enabled) ++ return; ++ ++ for (i = 0; i < stats->npeers; i++) { ++ pstats = &stats->wpcs[i]; ++ ++ rcu_read_lock(); ++ spin_lock_bh(&ab->base_lock); ++ ++ peer = ath11k_peer_find_by_id(ab, pstats->peer_id); ++ if (!peer || !peer->sta) { ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "nss wifili: unable to find peer %d\n", pstats->peer_id); ++ spin_unlock_bh(&ab->base_lock); ++ rcu_read_unlock(); ++ continue; ++ } ++ ++ if (!peer->nss.nss_stats) { ++ spin_unlock_bh(&ab->base_lock); ++ rcu_read_unlock(); ++ return; ++ } ++ ++ if (pstats->tx.tx_success_cnt) ++ peer->nss.nss_stats->last_ack = jiffies; ++ ++ if (pstats->rx.rx_recvd) { ++ peer->nss.nss_stats->last_rx = jiffies; ++ } ++ ++ tx_packets = pstats->tx.tx_mcast_cnt + ++ pstats->tx.tx_ucast_cnt + ++ pstats->tx.tx_bcast_cnt; ++ peer->nss.nss_stats->tx_packets += tx_packets; ++ tx_bytes = pstats->tx.tx_mcast_bytes + ++ pstats->tx.tx_ucast_bytes + ++ pstats->tx.tx_bcast_bytes; ++ peer->nss.nss_stats->tx_bytes += tx_bytes; ++ peer->nss.nss_stats->tx_retries += pstats->tx.retries; ++ ++ for (j = 0; j < NSS_WIFILI_TQM_RR_MAX; j++) ++ tx_dropped += pstats->tx.dropped.drop_stats[j]; ++ ++ peer->nss.nss_stats->tx_failed += tx_dropped; ++ ++ ATH11K_NSS_TXRX_NETDEV_STATS(tx, peer->vif, tx_bytes, tx_packets); ++ ++ rx_packets = pstats->rx.rx_recvd; ++ peer->nss.nss_stats->rx_packets += rx_packets; ++ rx_bytes = pstats->rx.rx_recvd_bytes; ++ peer->nss.nss_stats->rx_bytes += rx_bytes; ++ rx_dropped = pstats->rx.err.mic_err + ++ 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); ++ ++ spin_unlock_bh(&ab->base_lock); ++ rcu_read_unlock(); ++ } ++} ++ ++void ath11k_nss_ext_rx_stats(struct ath11k_base *ab, struct htt_rx_ring_tlv_filter *tlv_filter) ++{ ++ if (ab->nss.enabled) ++ tlv_filter->rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS; ++} ++ ++static u32 ath11k_nss_cipher_type(struct ath11k_base *ab, u32 cipher) ++{ ++ switch (cipher) { ++ case WLAN_CIPHER_SUITE_CCMP: ++ return PEER_SEC_TYPE_AES_CCMP; ++ case WLAN_CIPHER_SUITE_TKIP: ++ return PEER_SEC_TYPE_TKIP; ++ case WLAN_CIPHER_SUITE_CCMP_256: ++ return PEER_SEC_TYPE_AES_CCMP_256; ++ case WLAN_CIPHER_SUITE_GCMP: ++ return PEER_SEC_TYPE_AES_GCMP; ++ case WLAN_CIPHER_SUITE_GCMP_256: ++ return PEER_SEC_TYPE_AES_GCMP_256; ++ default: ++ ath11k_warn(ab, "unknown cipher type %d\n", cipher); ++ return PEER_SEC_TYPE_NONE; ++ } ++} ++ ++static void ath11k_nss_tx_encap_nwifi(struct sk_buff *skb) ++{ ++ struct ieee80211_hdr *hdr = (void *)skb->data; ++ u8 *qos_ctl; ++ ++ if (!ieee80211_is_data_qos(hdr->frame_control)) ++ return; ++ ++ qos_ctl = ieee80211_get_qos_ctl(hdr); ++ memmove(skb->data + IEEE80211_QOS_CTL_LEN, ++ skb->data, (void *)qos_ctl - (void *)skb->data); ++ skb_pull(skb, IEEE80211_QOS_CTL_LEN); ++ ++ hdr = (void *)skb->data; ++ hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA); ++} ++ ++static void ath11k_nss_tx_encap_raw(struct sk_buff *skb) ++{ ++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); ++ struct ieee80211_hdr *hdr = (void *)skb->data; ++ u32 cipher; ++ ++ if (!ieee80211_has_protected(hdr->frame_control) || !info->control.hw_key) ++ return; ++ ++ /* Include length for MIC */ ++ skb_put(skb, IEEE80211_CCMP_MIC_LEN); ++ ++ /* Include length for ICV if TKIP is used */ ++ cipher = info->control.hw_key->cipher; ++ if (cipher == WLAN_CIPHER_SUITE_TKIP) ++ skb_put(skb, IEEE80211_TKIP_ICV_LEN); ++} ++ ++static void ath11k_nss_peer_mem_free(struct ath11k_base *ab, u32 peer_id) ++{ ++ struct ath11k_peer *peer; ++ ++ spin_lock_bh(&ab->base_lock); ++ ++ 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); ++ return; ++ } ++ ++ dma_unmap_single(ab->dev, peer->nss.paddr, ++ WIFILI_NSS_PEER_BYTE_SIZE, DMA_FROM_DEVICE); ++ ++ kfree(peer->nss.vaddr); ++ if (peer->nss.nss_stats) { ++ kfree(peer->nss.nss_stats); ++ peer->nss.nss_stats = NULL; ++ } ++ ++ complete(&peer->nss.complete); ++ spin_unlock_bh(&ab->base_lock); ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "nss peer %d mem freed\n", peer_id); ++} ++ ++/*-----------------------------Events/Callbacks------------------------------*/ ++ ++void ath11k_nss_wifili_event_receive(struct ath11k_base *ab, struct nss_wifili_msg *msg) ++{ ++ u32 msg_type = msg->cm.type; ++ enum nss_cmn_response response = msg->cm.response; ++ u32 error = msg->cm.error; ++ u32 peer_id; ++ struct nss_wifili_peer_stats *peer_stats; ++ ++ if (!ab) ++ return; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "nss wifili event received %d response %d error %d\n", ++ msg_type, response, error); ++ ++ switch (msg_type) { ++ case NSS_WIFILI_INIT_MSG: ++ case NSS_WIFILI_PDEV_INIT_MSG: ++ case NSS_WIFILI_START_MSG: ++ case NSS_WIFILI_SOC_RESET_MSG: ++ case NSS_WIFILI_STOP_MSG: ++ case NSS_WIFILI_PDEV_DEINIT_MSG: ++ ab->nss.response = response; ++ complete(&ab->nss.complete); ++ break; ++ ++ case NSS_WIFILI_PEER_CREATE_MSG: ++ if (response != NSS_CMN_RESPONSE_EMSG) ++ break; ++ ++ peer_id = (&msg->msg.peermsg)->peer_id; ++ ++ /* free peer memory allocated during peer create due to failure */ ++ ath11k_nss_peer_mem_free(ab, peer_id); ++ break; ++ case NSS_WIFILI_PEER_DELETE_MSG: ++ peer_id = (&msg->msg.peermsg)->peer_id; ++ ++ if (response == NSS_CMN_RESPONSE_EMSG) ++ ath11k_warn(ab, "ath11k_nss: peer delete failed%d\n", ++ peer_id); ++ ++ /* free peer memory allocated during peer create irrespective of ++ * delete status ++ */ ++ ath11k_nss_peer_mem_free(ab, peer_id); ++ break; ++ case NSS_WIFILI_PEER_SECURITY_TYPE_MSG: ++ if (response == NSS_CMN_RESPONSE_EMSG) ++ ath11k_warn(ab, "peer securty config failed\n"); ++ ++ break; ++ case NSS_WIFILI_PEER_UPDATE_AUTH_FLAG: ++ if (response == NSS_CMN_RESPONSE_EMSG) ++ ath11k_warn(ab, "peer authorize config failed\n"); ++ ++ break; ++ case NSS_WIFILI_STATS_MSG: ++ if (response == NSS_CMN_RESPONSE_EMSG) { ++ ath11k_warn(ab, "soc_dp_stats failed to get updated\n"); ++ break; ++ } ++ ath11k_nss_wifili_stats_sync(ab, &msg->msg.wlsoc_stats); ++ break; ++ case NSS_WIFILI_PEER_STATS_MSG: ++ peer_stats = &msg->msg.peer_stats.stats; ++ if (response == NSS_CMN_RESPONSE_EMSG) { ++ ath11k_warn(ab, "peer stats msg failed with error = %u\n", error); ++ break; ++ } ++ ath11k_nss_get_peer_stats(ab, peer_stats); ++ break; ++ case NSS_WIFILI_TID_REOQ_SETUP_MSG: ++ /* TODO setup tidq */ ++ break; ++ default: ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "unhandled event %d\n", msg_type); ++ break; ++ } ++} ++ ++void ath11k_nss_process_mic_error(struct ath11k_base *ab, struct sk_buff *skb) ++{ ++ struct ath11k_vif *arvif; ++ struct ath11k_peer *peer = NULL; ++ struct hal_rx_desc *desc = (struct hal_rx_desc *)skb->data; ++ struct wireless_dev *wdev; ++ u16 peer_id; ++ u8 peer_addr[ETH_ALEN]; ++ u8 ucast_keyidx, mcast_keyidx; ++ bool is_mcbc; ++ ++ if (!ath11k_dp_rx_h_msdu_end_first_msdu(ab, desc)) ++ goto fail; ++ ++ is_mcbc = ath11k_dp_rx_h_attn_is_mcbc(ab, desc); ++ peer_id = ath11k_dp_rx_h_mpdu_start_peer_id(ab, desc); ++ ++ spin_lock_bh(&ab->base_lock); ++ peer = ath11k_peer_find_by_id(ab, peer_id); ++ if (!peer) { ++ ath11k_info(ab, "ath11k_nss:peer not found"); ++ spin_unlock_bh(&ab->base_lock); ++ goto fail; ++ } ++ ++ if (!peer->vif) { ++ ath11k_warn(ab, "ath11k_nss:vif not found"); ++ spin_unlock_bh(&ab->base_lock); ++ goto fail; ++ } ++ ++ ether_addr_copy(peer_addr, peer->addr); ++ mcast_keyidx = peer->mcast_keyidx; ++ ucast_keyidx = peer->ucast_keyidx; ++ arvif = ath11k_vif_to_arvif(peer->vif); ++ spin_unlock_bh(&ab->base_lock); ++ ++ if (!arvif->is_started) { ++ ath11k_warn(ab, "ath11k_nss:arvif not started"); ++ goto fail; ++ } ++ ++ wdev = ieee80211_vif_to_wdev_relaxed(arvif->vif); ++ if (!wdev) { ++ ath11k_warn(ab, "ath11k_nss: wdev is null\n"); ++ goto fail; ++ } ++ ++ if (!wdev->netdev) { ++ ath11k_warn(ab, "ath11k_nss: netdev is null\n"); ++ goto fail; ++ } ++ ++ cfg80211_michael_mic_failure(wdev->netdev, peer_addr, ++ is_mcbc ? NL80211_KEYTYPE_GROUP : ++ NL80211_KEYTYPE_PAIRWISE, ++ is_mcbc ? mcast_keyidx : ucast_keyidx, ++ NULL, GFP_ATOMIC); ++ dev_kfree_skb_any(skb); ++ return; ++ ++fail: ++ dev_kfree_skb_any(skb); ++ ath11k_warn(ab, "ath11k_nss: Failed to handle mic error\n"); ++ return; ++} ++ ++static void ++ath11k_nss_wifili_ext_callback_fn(struct ath11k_base *ab, struct sk_buff *skb, ++ __attribute__((unused)) struct napi_struct *napi) ++{ ++ struct nss_wifili_soc_per_packet_metadata *wepm; ++ ++ wepm = (struct nss_wifili_soc_per_packet_metadata *)(skb->head + ++ NSS_WIFILI_SOC_PER_PACKET_METADATA_OFFSET); ++ ++ switch (wepm->pkt_type) { ++ case NSS_WIFILI_SOC_EXT_DATA_PKT_MIC_ERROR: ++ ath11k_nss_process_mic_error(ab, skb); ++ break; ++ default: ++ kfree(skb); ++ break; ++ } ++} ++ ++void ath11k_nss_vdev_cfg_cb(void *app_data, struct nss_cmn_msg *msg) ++{ ++ struct ath11k_vif *arvif = (struct ath11k_vif *)app_data; ++ ++ if (!arvif) ++ return; ++ ++ ath11k_dbg(arvif->ar->ab, ATH11K_DBG_NSS, "vdev cfg msg callback received msg:%d rsp:%d\n", ++ msg->type, msg->response); ++ ++ complete(&arvif->nss.complete); ++} ++ ++static void ath11k_nss_vdev_event_receive(void *dev, struct nss_cmn_msg *vdev_msg) ++{ ++ /*TODO*/ ++} ++ ++static void ++ath11k_nss_vdev_special_data_receive(struct net_device *dev, struct sk_buff *skb, ++ __attribute__((unused)) struct napi_struct *napi) ++{ ++ /* TODO */ ++} ++ ++/* 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) ++{ ++ struct sk_buff_head subframe_list; ++ struct ieee80211_hdr *hdr; ++ struct sk_buff *subframe; ++ struct net_device *dev; ++ int hdr_len; ++ u8 *qc; ++ ++ dev = skb->dev; ++ ++ if (eth) ++ goto deliver_msdu; ++ ++ hdr = (struct ieee80211_hdr *)skb->data; ++ hdr_len = ieee80211_hdrlen(hdr->frame_control); ++ ++ if (ieee80211_is_data_qos(hdr->frame_control)) { ++ qc = ieee80211_get_qos_ctl(hdr); ++ if (*qc & IEEE80211_QOS_CTL_A_MSDU_PRESENT) ++ goto deliver_amsdu; ++ } ++ ++ if (ieee80211_data_to_8023_exthdr(skb, NULL, vif->addr, vif->type, ++ data_offs - hdr_len, false)) { ++ dev_kfree_skb_any(skb); ++ return -EINVAL; ++ } ++ ++deliver_msdu: ++ skb->protocol = eth_type_trans(skb, dev); ++ napi_gro_receive(napi, skb); ++ return 0; ++ ++deliver_amsdu: ++ /* Move to the start of the first subframe */ ++ skb_pull(skb, data_offs); ++ ++ __skb_queue_head_init(&subframe_list); ++ ++ /* create list containing all the subframes */ ++ ieee80211_amsdu_to_8023s(skb, &subframe_list, NULL, ++ vif->type, 0, NULL, NULL); ++ ++ /* This shouldn't happen, indicating error during defragmentation */ ++ if (skb_queue_empty(&subframe_list)) ++ return -EINVAL; ++ ++ while (!skb_queue_empty(&subframe_list)) { ++ subframe = __skb_dequeue(&subframe_list); ++ subframe->protocol = eth_type_trans(subframe, dev); ++ napi_gro_receive(napi, subframe); ++ } ++ ++ return 0; ++} ++ ++static int ath11k_nss_undecap_raw(struct ath11k_vif *arvif, struct sk_buff *skb, ++ int *data_offset) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ struct ath11k *ar = arvif->ar; ++ enum hal_encrypt_type enctype; ++ struct ath11k_peer *peer = NULL; ++ struct ieee80211_hdr *hdr; ++ int hdr_len; ++ ++ hdr = (struct ieee80211_hdr *)skb->data; ++ hdr_len = ieee80211_hdrlen(hdr->frame_control); ++ ++ *data_offset = hdr_len; ++ ++ /* FCS is included in the raw mode skb, we can trim it, fcs error ++ * packets are not expected to be received in this path ++ */ ++ skb_trim(skb, skb->len - FCS_LEN); ++ ++ spin_lock_bh(&ab->base_lock); ++ ++ peer = ath11k_peer_find_by_addr(ab, hdr->addr2); ++ if (!peer) { ++ ath11k_warn(ab, "peer not found for raw/nwifi undecap, drop this packet\n"); ++ spin_unlock_bh(&ab->base_lock); ++ return -EINVAL; ++ } ++ enctype = peer->sec_type; ++ ++ spin_unlock_bh(&ab->base_lock); ++ ++ *data_offset += ath11k_dp_rx_crypto_param_len(ar, enctype); ++ ++ /* Strip ICV, MIC, MMIC */ ++ skb_trim(skb, skb->len - ++ ath11k_dp_rx_crypto_mic_len(ar, enctype)); ++ ++ skb_trim(skb, skb->len - ++ ath11k_dp_rx_crypto_icv_len(ar, enctype)); ++ ++ if (enctype == HAL_ENCRYPT_TYPE_TKIP_MIC) ++ skb_trim(skb, skb->len - IEEE80211_CCMP_MIC_LEN); ++ ++ return 0; ++} ++ ++static int ath11k_nss_undecap_nwifi(struct ath11k_vif *arvif, struct sk_buff *skb, ++ int *data_offset) ++{ ++ struct ieee80211_hdr *hdr; ++ int hdr_len; ++ ++ hdr = (struct ieee80211_hdr *)skb->data; ++ hdr_len = ieee80211_hdrlen(hdr->frame_control); ++ ++ *data_offset = hdr_len; ++ ++ /* We dont receive the IV from nss host on slow path ++ * hence we can return only the header length as offset. ++ **/ ++ return 0; ++} ++ ++static void ++ath11k_nss_vdev_data_receive(struct net_device *dev, struct sk_buff *skb, ++ __attribute__((unused)) struct napi_struct *napi) ++{ ++ enum ath11k_hw_txrx_mode decap_type; ++ 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) { ++ 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; ++ if (!arvif) { ++ dev_kfree_skb_any(skb); ++ return; ++ } ++ ++ 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: ", ++ skb->data, skb->len); ++ ++ decap_type = arvif->nss.decap; ++ ++ switch (decap_type) { ++ case ATH11K_HW_TXRX_RAW: ++ ret = ath11k_nss_undecap_raw(arvif, skb, &data_offs); ++ break; ++ case ATH11K_HW_TXRX_NATIVE_WIFI: ++ ret = ath11k_nss_undecap_nwifi(arvif, skb, &data_offs); ++ break; ++ case ATH11K_HW_TXRX_ETHERNET: ++ /* no changes required for ethernet decap */ ++ ret = 0; ++ eth_decap = true; ++ break; ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ ++ if (ret) { ++ ath11k_warn(ab, "error in nss rx undecap, type %d err %d\n", decap_type, ++ ret); ++ dev_kfree_skb_any(skb); ++ return; ++ } ++ ++ ath11k_nss_deliver_rx(arvif->vif, skb, eth_decap, data_offs, napi); ++} ++ ++int ath11k_nss_tx(struct ath11k_vif *arvif, struct sk_buff *skb) ++{ ++ struct ath11k *ar = arvif->ar; ++ 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; ++ ++ 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; ++ } ++ ++ if (encap_type == HAL_TCL_ENCAP_TYPE_ETHERNET) ++ goto send; ++ ++ if (encap_type == HAL_TCL_ENCAP_TYPE_RAW) ++ ath11k_nss_tx_encap_raw(skb); ++ else ++ ath11k_nss_tx_encap_nwifi(skb); ++ ++send: ++ ath11k_dbg_dump(ar->ab, ATH11K_DBG_DP_TX, "", "nss tx msdu: ", ++ 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), ++ "nss tx failure: %d\n", status); ++ atomic_inc(&soc_stats->tx_err.nss_tx_fail); ++ } ++ ++ return status; ++drop: ++ atomic_inc(&soc_stats->tx_err.misc_fail); ++ WARN_ON_ONCE(1); ++ return -EINVAL; ++} ++ ++int ath11k_nss_vdev_set_cmd(struct ath11k_vif *arvif, int cmd, int val) ++{ ++ struct nss_wifi_vdev_msg *vdev_msg = NULL; ++ struct nss_wifi_vdev_cmd_msg *vdev_cmd; ++ struct ath11k *ar = arvif->ar; ++ nss_tx_status_t status; ++ ++ if (!ar->ab->nss.enabled) ++ return 0; ++ ++ /* Monitor interface is not offloaded to nss */ ++ if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) ++ return 0; ++ ++ vdev_msg = kzalloc(sizeof(*vdev_msg), GFP_ATOMIC); ++ if (!vdev_msg) ++ return -ENOMEM; ++ ++ /* TODO: Convert to function for conversion in case of many ++ * such commands ++ */ ++ if (cmd == NSS_WIFI_VDEV_SECURITY_TYPE_CMD) ++ val = ath11k_nss_cipher_type(ar->ab, val); ++ ++ if (cmd == NSS_WIFI_VDEV_ENCAP_TYPE_CMD) ++ arvif->nss.encap = val; ++ else if (cmd == NSS_WIFI_VDEV_DECAP_TYPE_CMD) ++ arvif->nss.decap = val; ++ ++ vdev_cmd = &vdev_msg->msg.vdev_cmd; ++ vdev_cmd->cmd = cmd; ++ vdev_cmd->value = val; ++ ++ nss_wifi_vdev_msg_init(vdev_msg, arvif->nss.if_num, ++ NSS_WIFI_VDEV_INTERFACE_CMD_MSG, ++ sizeof(struct nss_wifi_vdev_cmd_msg), ++ NULL, NULL); ++ ++ status = nss_wifi_vdev_tx_msg(ar->nss.ctx, vdev_msg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "nss vdev set cmd failure cmd:%d val:%d", ++ cmd, val); ++ goto free; ++ } ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss vdev set cmd success cmd:%d val:%d\n", ++ cmd, val); ++free: ++ kfree(vdev_msg); ++ return status; ++} ++ ++static int ath11k_nss_vdev_configure(struct ath11k_vif *arvif) ++{ ++ struct ath11k *ar = arvif->ar; ++ struct nss_wifi_vdev_msg *vdev_msg; ++ struct nss_wifi_vdev_config_msg *vdev_cfg; ++ nss_tx_status_t status; ++ int ret; ++ ++ vdev_msg = kzalloc(sizeof(struct nss_wifi_vdev_msg), GFP_ATOMIC); ++ if (!vdev_msg) ++ return -ENOMEM; ++ ++ vdev_cfg = &vdev_msg->msg.vdev_config; ++ ++ vdev_cfg->radio_ifnum = ar->nss.if_num; ++ vdev_cfg->vdev_id = arvif->vdev_id; ++ ++ vdev_cfg->opmode = ath11k_nss_get_vdev_opmode(arvif); ++ ++ ether_addr_copy(vdev_cfg->mac_addr, arvif->vif->addr); ++ ++ reinit_completion(&arvif->nss.complete); ++ ++ nss_wifi_vdev_msg_init(vdev_msg, arvif->nss.if_num, ++ NSS_WIFI_VDEV_INTERFACE_CONFIGURE_MSG, ++ sizeof(struct nss_wifi_vdev_config_msg), ++ (nss_wifi_vdev_msg_callback_t *)ath11k_nss_vdev_cfg_cb, ++ arvif); ++ ++ status = nss_wifi_vdev_tx_msg(ar->nss.ctx, vdev_msg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "failed to configure nss vdev nss_err:%d\n", ++ status); ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ ret = wait_for_completion_timeout(&arvif->nss.complete, ++ msecs_to_jiffies(ATH11K_NSS_MSG_TIMEOUT_MS)); ++ if (!ret) { ++ ath11k_warn(ar->ab, "timeout in receiving nss vdev cfg response\n"); ++ ret = -ETIMEDOUT; ++ goto free; ++ } ++ ++ ret = 0; ++free: ++ kfree(vdev_msg); ++ ++ return ret; ++} ++ ++static void ath11k_nss_vdev_unregister(struct ath11k_vif *arvif) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ ++ switch (arvif->vif->type) { ++ case NL80211_IFTYPE_AP: ++ case NL80211_IFTYPE_STATION: ++ nss_unregister_wifi_vdev_if(arvif->nss.if_num); ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "unregistered nss vdev %d \n", ++ arvif->nss.if_num); ++ break; ++ default: ++ ath11k_warn(ab, "unsupported interface type %d for nss vdev unregister\n", ++ arvif->vif->type); ++ return; ++ } ++} ++ ++static int ath11k_nss_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; ++ ++ switch (arvif->vif->type) { ++ case NL80211_IFTYPE_AP: ++ case NL80211_IFTYPE_STATION: ++ status = nss_register_wifi_vdev_if(ar->nss.ctx, ++ arvif->nss.if_num, ++ ath11k_nss_vdev_data_receive, ++ ath11k_nss_vdev_special_data_receive, ++ ath11k_nss_vdev_event_receive, ++ netdev, features); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "failed to register nss vdev if_num %d nss_err:%d\n", ++ arvif->nss.if_num, status); ++ return -EINVAL; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "registered nss vdev if_num %d\n", ++ arvif->nss.if_num); ++ ++ break; ++ default: ++ ath11k_warn(ab, "unsupported interface type %d for nss vdev register\n", ++ arvif->vif->type); ++ return -ENOTSUPP; ++ } ++ ++ return 0; ++} ++ ++void ath11k_nss_vdev_free(struct ath11k_vif *arvif) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ nss_tx_status_t status; ++ ++ switch (arvif->vif->type) { ++ case NL80211_IFTYPE_AP: ++ case NL80211_IFTYPE_STATION: ++ 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 vdev nss_err:%d\n", ++ status); ++ else ++ ath11k_dbg(ab, ATH11K_DBG_NSS, ++ "nss vdev interface deallocated\n"); ++ ++ return; ++ default: ++ ath11k_warn(ab, "unsupported interface type %d for nss vdev dealloc\n", ++ arvif->vif->type); ++ return; ++ } ++} ++ ++static int ath11k_nss_vdev_alloc(struct ath11k_vif *arvif) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ enum nss_dynamic_interface_type if_type; ++ int if_num; ++ ++ /* Initialize completion for verifying NSS message response */ ++ init_completion(&arvif->nss.complete); ++ ++ switch (arvif->vif->type) { ++ case NL80211_IFTYPE_AP: ++ case NL80211_IFTYPE_STATION: ++ if_type = NSS_DYNAMIC_INTERFACE_TYPE_VAP; ++ /* allocate interface context with NSS driver for the new vdev */ ++ if_num = nss_dynamic_interface_alloc_node(if_type); ++ if (if_num < 0) { ++ ath11k_warn(ab, "failed to allocate nss vdev\n"); ++ return -EINVAL; ++ } ++ ++ arvif->nss.if_num = if_num; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "allocated nss vdev if_num %d\n", ++ arvif->nss.if_num); ++ ++ break; ++ default: ++ ath11k_warn(ab, "unsupported interface type %d for nss vdev alloc\n", ++ arvif->vif->type); ++ return -ENOTSUPP; ++ } ++ ++ return 0; ++} ++ ++int ath11k_nss_vdev_create(struct ath11k_vif *arvif) ++{ ++ struct ath11k *ar = arvif->ar; ++ struct ath11k_base *ab = ar->ab; ++ struct wireless_dev *wdev; ++ int ret; ++ ++ if (!ab->nss.enabled) ++ return 0; ++ ++ /* Monitor interface is not offloaded to nss */ ++ if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) ++ return 0; ++ ++ if (arvif->nss.created) ++ return 0; ++ ++ 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; ++ } ++ ++ ret = ath11k_nss_vdev_alloc(arvif); ++ if (ret) ++ return ret; ++ ++ ret = ath11k_nss_vdev_register(arvif, wdev->netdev); ++ if (ret) ++ goto free_vdev; ++ ++ switch (arvif->vif->type) { ++ case NL80211_IFTYPE_AP: ++ case NL80211_IFTYPE_STATION: ++ ret = ath11k_nss_vdev_configure(arvif); ++ if (ret) ++ goto unregister_vdev; ++ ++ break; ++ default: ++ ret = -ENOTSUPP; ++ goto unregister_vdev; ++ } ++ ++ arvif->nss.created = true; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, ++ "nss vdev interface created ctx %pK, ifnum %d\n", ++ ar->nss.ctx, arvif->nss.if_num); ++ ++ return ret; ++ ++unregister_vdev: ++ ath11k_nss_vdev_unregister(arvif); ++free_vdev: ++ ath11k_nss_vdev_free(arvif); ++ ++ return ret; ++} ++ ++void ath11k_nss_vdev_delete(struct ath11k_vif *arvif) ++{ ++ if (!arvif->ar->ab->nss.enabled) ++ return; ++ ++ /* Monitor interface is not offloaded to nss */ ++ if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) ++ return; ++ ++ if (!arvif->nss.created) ++ return; ++ ++ ath11k_nss_vdev_unregister(arvif); ++ ++ ath11k_nss_vdev_free(arvif); ++ ++ arvif->nss.created = false; ++} ++ ++int ath11k_nss_vdev_up(struct ath11k_vif *arvif) ++{ ++ struct nss_wifi_vdev_msg *vdev_msg = NULL; ++ struct nss_wifi_vdev_enable_msg *vdev_en; ++ struct ath11k *ar = arvif->ar; ++ nss_tx_status_t status; ++ int ret = 0; ++ ++ if (!ar->ab->nss.enabled) ++ return 0; ++ ++ /* Monitor interface is not offloaded to nss */ ++ if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) ++ return 0; ++ ++ vdev_msg = kzalloc(sizeof(struct nss_wifi_vdev_msg), GFP_ATOMIC); ++ if (!vdev_msg) ++ return -ENOMEM; ++ ++ vdev_en = &vdev_msg->msg.vdev_enable; ++ ++ ether_addr_copy(vdev_en->mac_addr, arvif->vif->addr); ++ ++ nss_wifi_vdev_msg_init(vdev_msg, arvif->nss.if_num, ++ NSS_WIFI_VDEV_INTERFACE_UP_MSG, ++ sizeof(struct nss_wifi_vdev_enable_msg), ++ NULL, NULL); ++ ++ status = nss_wifi_vdev_tx_msg(ar->nss.ctx, vdev_msg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "nss vdev up tx msg error %d\n", status); ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss vdev up tx msg success\n"); ++free: ++ kfree(vdev_msg); ++ return ret; ++} ++ ++int ath11k_nss_vdev_down(struct ath11k_vif *arvif) ++{ ++ struct nss_wifi_vdev_msg *vdev_msg = NULL; ++ struct ath11k *ar = arvif->ar; ++ nss_tx_status_t status; ++ int ret = 0; ++ ++ if (!ar->ab->nss.enabled) ++ return 0; ++ ++ /* Monitor interface is not offloaded to nss */ ++ if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) ++ return 0; ++ ++ vdev_msg = kzalloc(sizeof(struct nss_wifi_vdev_msg), GFP_ATOMIC); ++ if (!vdev_msg) ++ return -ENOMEM; ++ ++ nss_wifi_vdev_msg_init(vdev_msg, arvif->nss.if_num, ++ NSS_WIFI_VDEV_INTERFACE_DOWN_MSG, ++ sizeof(struct nss_wifi_vdev_disable_msg), ++ NULL, NULL); ++ ++ status = nss_wifi_vdev_tx_msg(ar->nss.ctx, vdev_msg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "nss vdev down tx msg error %d\n", status); ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss vdev down tx msg success\n"); ++free: ++ kfree(vdev_msg); ++ return ret; ++} ++ ++/*----------------------------Peer Setup/Config -----------------------------*/ ++ ++int ath11k_nss_set_peer_sec_type(struct ath11k *ar, ++ struct ath11k_peer *peer, ++ struct ieee80211_key_conf *key_conf) ++{ ++ struct nss_wifili_peer_security_type_msg *sec_msg; ++ nss_wifili_msg_callback_t msg_cb; ++ struct nss_wifili_msg *wlmsg; ++ nss_tx_status_t status; ++ u8 *mic_key; ++ ++ if (!ar->ab->nss.enabled) ++ return 0; ++ ++ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); ++ if (!wlmsg) ++ return -ENOMEM; ++ ++ sec_msg = &wlmsg->msg.securitymsg; ++ sec_msg->peer_id = peer->peer_id; ++ ++ /* 0 -unicast , 1 - mcast/unicast */ ++ sec_msg->pkt_type = !(key_conf->flags & IEEE80211_KEY_FLAG_PAIRWISE); ++ ++ sec_msg->security_type = ath11k_nss_cipher_type(ar->ab, ++ key_conf->cipher); ++ ++ if (sec_msg->security_type == PEER_SEC_TYPE_TKIP) { ++ mic_key = &key_conf->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; ++ memcpy(&sec_msg->mic_key[0], mic_key, NSS_WIFILI_MIC_KEY_LEN); ++ } ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ar->ab->nss.if_num, ++ NSS_WIFILI_PEER_SECURITY_TYPE_MSG, ++ sizeof(struct nss_wifili_peer_security_type_msg), ++ msg_cb, NULL); ++ ++ status = nss_wifili_tx_msg(ar->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "nss peer %d security cfg fail %d\n", ++ peer->peer_id, status); ++ goto free; ++ } ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss peer id %d security cfg complete\n", ++ peer->peer_id); ++free: ++ kfree(wlmsg); ++ return status; ++} ++ ++int ath11k_nss_set_peer_authorize(struct ath11k *ar, u16 peer_id) ++{ ++ struct nss_wifili_peer_update_auth_flag *auth_msg; ++ nss_wifili_msg_callback_t msg_cb; ++ struct nss_wifili_msg *wlmsg; ++ nss_tx_status_t status; ++ ++ if (!ar->ab->nss.enabled) ++ return 0; ++ ++ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); ++ if (!wlmsg) ++ return -ENOMEM; ++ ++ auth_msg = &wlmsg->msg.peer_auth; ++ auth_msg->peer_id = peer_id; ++ auth_msg->auth_flag = 1; ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ar->ab->nss.if_num, ++ NSS_WIFILI_PEER_UPDATE_AUTH_FLAG, ++ sizeof(struct nss_wifili_peer_update_auth_flag), ++ msg_cb, NULL); ++ ++ status = nss_wifili_tx_msg(ar->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "nss peer %d auth cfg fail %d\n", ++ peer_id, status); ++ goto free; ++ } ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss peer id %d auth cfg complete\n", ++ peer_id); ++free: ++ kfree(wlmsg); ++ return status; ++} ++ ++void ath11k_nss_update_sta_stats(struct station_info *sinfo, ++ struct ieee80211_sta *sta, ++ struct ath11k_sta *arsta) ++{ ++ struct sta_info *stainfo; ++ struct ath11k_peer *peer; ++ int tid_idx; ++ struct ath11k *ar = arsta->arvif->ar; ++ struct ath11k_base *ab = ar->ab; ++ ++ if (!ab->nss.enabled) ++ return; ++ ++ spin_lock_bh(&ab->base_lock); ++ peer = ath11k_peer_find_by_addr(arsta->arvif->ar->ab, sta->addr); ++ if (!peer) { ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "unable to find peer %pM\n", ++ sta->addr); ++ goto exit; ++ } ++ ++ if (!peer->nss.nss_stats) ++ goto exit; ++ ++ stainfo = container_of(sta, struct sta_info, sta); ++ if (peer->nss.nss_stats->last_rx && ++ time_after((unsigned long)peer->nss.nss_stats->last_rx, stainfo->deflink.rx_stats.last_rx)) ++ stainfo->deflink.rx_stats.last_rx = peer->nss.nss_stats->last_rx; ++ ++ if (peer->nss.nss_stats->last_ack && ++ time_after((unsigned long)peer->nss.nss_stats->last_ack, stainfo->deflink.status_stats.last_ack)) ++ stainfo->deflink.status_stats.last_ack = peer->nss.nss_stats->last_ack; ++ ++ stainfo->deflink.rx_stats.dropped += peer->nss.nss_stats->rx_dropped - ++ peer->nss.nss_stats->last_rxdrop; ++ peer->nss.nss_stats->last_rxdrop = peer->nss.nss_stats->rx_dropped; ++ ++ sinfo->tx_packets = 0; ++ /* Add only ac-0 count as mgmt packets uses WME_AC_BE */ ++ sinfo->tx_packets += stainfo->deflink.tx_stats.packets[WME_AC_BE]; ++ sinfo->tx_packets += peer->nss.nss_stats->tx_packets; ++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS); ++ sinfo->tx_bytes = 0; ++ ++ /* Add only ac-0 count as mgmt packets uses WME_AC_BE */ ++ sinfo->tx_bytes += stainfo->deflink.tx_stats.bytes[WME_AC_BE]; ++ sinfo->tx_bytes += peer->nss.nss_stats->tx_bytes; ++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES); ++ ++ sinfo->tx_failed = stainfo->deflink.status_stats.retry_failed + ++ peer->nss.nss_stats->tx_failed; ++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); ++ ++ sinfo->tx_retries = stainfo->deflink.status_stats.retry_count + ++ peer->nss.nss_stats->tx_retries; ++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); ++ ++ sinfo->rx_packets = stainfo->deflink.rx_stats.packets + ++ peer->nss.nss_stats->rx_packets; ++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS); ++ ++ sinfo->rx_bytes = stainfo->deflink.rx_stats.bytes + ++ peer->nss.nss_stats->rx_bytes; ++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES); ++ ++ if (peer->nss.nss_stats->rxrate.legacy || peer->nss.nss_stats->rxrate.nss) { ++ if (peer->nss.nss_stats->rxrate.legacy) { ++ sinfo->rxrate.legacy = peer->nss.nss_stats->rxrate.legacy; ++ } else { ++ sinfo->rxrate.mcs = peer->nss.nss_stats->rxrate.mcs; ++ sinfo->rxrate.nss = peer->nss.nss_stats->rxrate.nss; ++ sinfo->rxrate.bw = peer->nss.nss_stats->rxrate.bw; ++ sinfo->rxrate.he_gi = peer->nss.nss_stats->rxrate.he_gi; ++ sinfo->rxrate.he_dcm = peer->nss.nss_stats->rxrate.he_dcm; ++ sinfo->rxrate.he_ru_alloc = peer->nss.nss_stats->rxrate.he_ru_alloc; ++ } ++ sinfo->rxrate.flags = peer->nss.nss_stats->rxrate.flags; ++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE); ++ } ++ ++exit: ++ spin_unlock_bh(&ab->base_lock); ++} ++ ++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) ++{ ++ struct ath11k_sta *arsta = (struct ath11k_sta *)peer->sta->drv_priv; ++ u16 ath11k_hal_rx_legacy_rates[] = ++ { 10, 20, 55, 60, 90, 110, 120, 180, 240, 360, 480, 540 }; ++ u16 rate = 0; ++ u32 preamble_type; ++ u8 mcs, nss; ++ struct ath11k *ar = arsta->arvif->ar; ++ struct ath11k_base *ab = ar->ab; ++ ++ if (!ab->nss.enabled) ++ return; ++ ++ if (!peer->nss.nss_stats) ++ return; ++ ++ if (user_stats) { ++ mcs = user_stats->mcs; ++ nss = user_stats->nss; ++ preamble_type = user_stats->preamble_type; ++ } else { ++ mcs = ppdu_info->mcs; ++ nss = ppdu_info->nss; ++ preamble_type = ppdu_info->preamble_type; ++ } ++ ++ if ((preamble_type == WMI_RATE_PREAMBLE_CCK || ++ preamble_type == WMI_RATE_PREAMBLE_OFDM) && ++ (ppdu_info->rate < ATH11K_LEGACY_NUM)) { ++ rate = ath11k_hal_rx_legacy_rates[ppdu_info->rate]; ++ } ++ ++ memset(&peer->nss.nss_stats->rxrate, 0, sizeof(peer->nss.nss_stats->rxrate)); ++ ++ switch (preamble_type) { ++ case WMI_RATE_PREAMBLE_OFDM: ++ peer->nss.nss_stats->rxrate.legacy = rate; ++ break; ++ case WMI_RATE_PREAMBLE_CCK: ++ peer->nss.nss_stats->rxrate.legacy = rate; ++ break; ++ case WMI_RATE_PREAMBLE_HT: ++ if (mcs >= ATH11K_HT_MCS_NUM) { ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS, ++ "Received invalid mcs in HT mode %d\n", mcs); ++ return; ++ } ++ peer->nss.nss_stats->rxrate.mcs = mcs; ++ peer->nss.nss_stats->rxrate.flags = RATE_INFO_FLAGS_MCS; ++ if (ppdu_info->gi) ++ peer->nss.nss_stats->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI; ++ break; ++ case WMI_RATE_PREAMBLE_VHT: ++ if (mcs > ATH11K_VHT_MCS_MAX) { ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS, ++ "Received invalid mcs in VHT mode %d\n", mcs); ++ return; ++ } ++ peer->nss.nss_stats->rxrate.mcs = mcs; ++ peer->nss.nss_stats->rxrate.flags = RATE_INFO_FLAGS_VHT_MCS; ++ if (ppdu_info->gi) ++ peer->nss.nss_stats->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI; ++ break; ++ case WMI_RATE_PREAMBLE_HE: ++ if (mcs > ATH11K_HE_MCS_MAX) { ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS, ++ "Received invalid mcs in HE mode %d\n", mcs); ++ return; ++ } ++ 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; ++ peer->nss.nss_stats->rxrate.he_gi = ath11k_he_gi_to_nl80211_he_gi(ppdu_info->gi); ++ peer->nss.nss_stats->rxrate.he_ru_alloc = ppdu_info->ru_alloc; ++ break; ++ } ++ ++ peer->nss.nss_stats->rxrate.nss = nss; ++ peer->nss.nss_stats->rxrate.bw = ath11k_mac_bw_to_mac80211_bw(ppdu_info->bw); ++} ++ ++int ath11k_nss_peer_delete(struct ath11k_base *ab, const u8 *addr) ++{ ++ struct nss_wifili_peer_msg *peer_msg; ++ struct nss_wifili_msg *wlmsg = NULL; ++ struct ath11k_peer *peer; ++ nss_wifili_msg_callback_t msg_cb; ++ nss_tx_status_t status; ++ int ret; ++ ++ if (!ab->nss.enabled) ++ return 0; ++ ++ spin_lock_bh(&ab->base_lock); ++ ++ peer = ath11k_peer_find_by_addr(ab, addr); ++ if (!peer) { ++ ath11k_warn(ab, "peer not found for nss peer delete\n"); ++ spin_unlock_bh(&ab->base_lock); ++ return -EINVAL; ++ } ++ ++ if (!peer->nss.vaddr) { ++ ath11k_warn(ab, "peer already deleted or peer create failed %pM\n", ++ addr); ++ spin_unlock_bh(&ab->base_lock); ++ return -EINVAL; ++ } ++ ++ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); ++ if (!wlmsg) { ++ ath11k_warn(ab, "nss send peer delete msg alloc failure\n"); ++ ret = -ENOMEM; ++ goto free_peer; ++ } ++ ++ peer_msg = &wlmsg->msg.peermsg; ++ ++ peer_msg->vdev_id = peer->vdev_id; ++ peer_msg->peer_id = peer->peer_id; ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_PEER_DELETE_MSG, ++ sizeof(struct nss_wifili_peer_msg), ++ msg_cb, NULL); ++ ++ reinit_completion(&peer->nss.complete); ++ ++ status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "nss send peer (%pM) delete msg tx error %d\n", ++ addr, status); ++ ret = -EINVAL; ++ kfree(wlmsg); ++ goto free_peer; ++ } else { ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "nss peer delete message success : peer_id %d\n", ++ peer->peer_id); ++ ret = 0; ++ } ++ ++ spin_unlock_bh(&ab->base_lock); ++ ++ kfree(wlmsg); ++ ++ /* No need to return failure or free up here, since the msg was tx succesfully ++ * the peer delete response would be received from NSS which will free up ++ * the allocated memory ++ */ ++ ret = wait_for_completion_timeout(&peer->nss.complete, ++ msecs_to_jiffies(ATH11K_NSS_MSG_TIMEOUT_MS)); ++ if (!ret) ++ ath11k_warn(ab, "timeout while waiting for nss peer delete msg response\n"); ++ ++ return 0; ++ ++free_peer: ++ dma_unmap_single(ab->dev, peer->nss.paddr, ++ WIFILI_NSS_PEER_BYTE_SIZE, DMA_FROM_DEVICE); ++ kfree(peer->nss.vaddr); ++ if (peer->nss.nss_stats) { ++ kfree(peer->nss.nss_stats); ++ peer->nss.nss_stats = NULL; ++ } ++ spin_unlock_bh(&ab->base_lock); ++ return ret; ++} ++ ++int ath11k_nss_peer_create(struct ath11k_base *ab, struct ath11k_peer *peer) ++{ ++ struct nss_wifili_peer_msg *peer_msg; ++ struct nss_wifili_msg *wlmsg = NULL; ++ nss_wifili_msg_callback_t msg_cb; ++ nss_tx_status_t status; ++ int ret; ++ ++ if (!ab->nss.enabled) ++ return -ENOTSUPP; ++ ++ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); ++ if (!wlmsg) ++ return -ENOMEM; ++ ++ peer_msg = &wlmsg->msg.peermsg; ++ ++ peer_msg->vdev_id = peer->vdev_id; ++ peer_msg->peer_id = peer->peer_id; ++ peer_msg->hw_ast_idx = peer->hw_peer_id; ++ peer_msg->tx_ast_hash = peer->ast_hash; ++ ether_addr_copy(peer_msg->peer_mac_addr, peer->addr); ++ ++ peer->nss.vaddr = kzalloc(WIFILI_NSS_PEER_BYTE_SIZE, GFP_ATOMIC); ++ ++ /* Initialize completion for verifying Peer NSS message response */ ++ init_completion(&peer->nss.complete); ++ ++ if (!peer->nss.vaddr) { ++ ath11k_warn(ab, "failed to allocate memory for nss peer info\n"); ++ kfree(wlmsg); ++ return -ENOMEM; ++ } ++ ++ peer->nss.paddr = dma_map_single(ab->dev, peer->nss.vaddr, ++ WIFILI_NSS_PEER_BYTE_SIZE, DMA_TO_DEVICE); ++ ++ ret = dma_mapping_error(ab->dev, peer->nss.paddr); ++ if (ret) { ++ ath11k_warn(ab, "error during nss peer info memalloc\n"); ++ kfree(peer->nss.vaddr); ++ ret = -ENOMEM; ++ goto msg_free; ++ } ++ ++ peer_msg->nss_peer_mem = peer->nss.paddr; ++ peer_msg->psta_vdev_id = peer->vdev_id; ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_PEER_CREATE_MSG, ++ sizeof(struct nss_wifili_peer_msg), ++ msg_cb, NULL); ++ ++ status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ret = -EINVAL; ++ ath11k_warn(ab, "nss send peer (%pM) create msg tx error\n", ++ peer->addr); ++ goto peer_mem_free; ++ } ++ ++ ret = 0; ++ ath11k_dbg(ab, ATH11K_DBG_NSS, ++ "nss peer_create msg success mac:%pM vdev:%d peer_id:%d hw_ast_idx:%d ast_hash:%d\n", ++ peer_msg->peer_mac_addr, peer_msg->vdev_id, peer_msg->peer_id, ++ peer_msg->hw_ast_idx, peer_msg->tx_ast_hash); ++ ++ peer->nss.nss_stats = kzalloc(sizeof(*peer->nss.nss_stats), GFP_ATOMIC); ++ if (!peer->nss.nss_stats) { ++ ret = -ENOMEM; ++ ath11k_warn(ab, "Unable to create nss stats memory\n"); ++ goto peer_mem_free; ++ } ++ ++ goto msg_free; ++ ++peer_mem_free: ++ dma_unmap_single(ab->dev, peer->nss.paddr, ++ WIFILI_NSS_PEER_BYTE_SIZE, DMA_FROM_DEVICE); ++ kfree(peer->nss.vaddr); ++msg_free: ++ kfree(wlmsg); ++ return ret; ++} ++ ++/*-------------------------------INIT/DEINIT---------------------------------*/ ++ ++static int ath11k_nss_radio_buf_cfg(struct ath11k *ar, int range, int buf_sz) ++{ ++ struct nss_wifili_radio_buf_cfg_msg *buf_cfg; ++ struct nss_wifili_radio_cfg_msg *radio_buf_cfg_msg; ++ struct nss_wifili_msg *wlmsg = NULL; ++ nss_tx_status_t status; ++ int ret = 0; ++ ++ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); ++ if (!wlmsg) ++ return -ENOMEM; ++ ++ radio_buf_cfg_msg = &wlmsg->msg.radiocfgmsg; ++ ++ radio_buf_cfg_msg->radio_if_num = ar->nss.if_num; ++ buf_cfg = &wlmsg->msg.radiocfgmsg.radiomsg.radiobufcfgmsg; ++ buf_cfg->range = range; ++ buf_cfg->buf_cnt = buf_sz; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ar->ab->nss.if_num, ++ NSS_WIFILI_RADIO_BUF_CFG, ++ sizeof(struct nss_wifili_radio_buf_cfg_msg), ++ NULL, NULL); ++ ++ status = nss_wifili_tx_msg(ar->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "nss radio buf cfg send failed %d\n", status); ++ ret = -EINVAL; ++ } else { ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS, ++ "nss radio cfg message range:%d buf_sz:%d if_num:%d ctx:%p\n", ++ range, buf_sz, ar->nss.if_num, ar->nss.ctx); ++ } ++ ++ kfree(wlmsg); ++ return ret; ++} ++ ++static void ath11k_nss_fill_srng_info(struct ath11k_base *ab, int ring_id, ++ struct nss_wifili_hal_srng_info *hsi) ++{ ++ struct ath11k_hal *hal = &ab->hal; ++ struct hal_srng *srng; ++ u32 offset; ++ int i; ++ ++ if (ring_id < 0) { ++ ath11k_warn(ab, "Invalid ring id used for nss init\n"); ++ WARN_ON(1); ++ return; ++ } ++ ++ srng = &hal->srng_list[ring_id]; ++ ++ hsi->ring_id = srng->ring_id; ++ hsi->ring_dir = srng->ring_dir; ++ hsi->ring_base_paddr = srng->ring_base_paddr; ++ hsi->entry_size = srng->entry_size; ++ hsi->num_entries = srng->num_entries; ++ hsi->flags = srng->flags; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, ++ "Ring info to send to nss - ring_id:%d ring_dir:%d ring_paddr:%d entry_size:%d num_entries:%d flags:%d\n", ++ hsi->ring_id, hsi->ring_dir, hsi->ring_base_paddr, ++ hsi->entry_size, hsi->num_entries, hsi->flags); ++ ++ for (i = 0; i < HAL_SRNG_NUM_REG_GRP; i++) { ++ offset = srng->hwreg_base[i]; ++ ++ /* For PCI based devices, get the umac ring base address offset ++ * based on window register configuration. ++ */ ++ if (!(srng->flags & HAL_SRNG_FLAGS_LMAC_RING)) ++ offset = ath11k_hif_get_window_offset(ab, srng->hwreg_base[i]); ++ ++ hsi->hwreg_base[i] = (u32)ab->mem_pa + offset; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "SRNG Register %d address %d\n", ++ i, hsi->hwreg_base[i]); ++ } ++} ++ ++static void ath11k_nss_tx_desc_mem_free(struct ath11k_base *ab) ++{ ++ int i; ++ ++ for (i = 0; i < ATH11K_NSS_MAX_NUMBER_OF_PAGE; i++) { ++ if (!ab->nss.tx_desc_paddr[i]) ++ continue; ++ ++ dma_free_coherent(ab->dev, ++ ab->nss.tx_desc_size[i], ++ ab->nss.tx_desc_vaddr[i], ++ ab->nss.tx_desc_paddr[i]); ++ ab->nss.tx_desc_vaddr[i] = NULL; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "allocated tx desc mem freed\n"); ++} ++ ++static int ath11k_nss_tx_desc_mem_alloc(struct ath11k_base *ab, u32 required_size, u32 *page_idx) ++{ ++ int i, alloc_size; ++ int curr_page_idx; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "tx desc mem alloc size: %d\n", required_size); ++ ++ curr_page_idx = *page_idx; ++ ++ for (i = 0, alloc_size = 0; i < required_size; i += alloc_size) { ++ alloc_size = required_size - i; ++ ++ if (alloc_size > WIFILI_NSS_MAX_MEM_PAGE_SIZE) ++ alloc_size = WIFILI_NSS_MAX_MEM_PAGE_SIZE; ++ ++ ab->nss.tx_desc_vaddr[curr_page_idx] = ++ dma_alloc_coherent(ab->dev, alloc_size, ++ &ab->nss.tx_desc_paddr[curr_page_idx], ++ GFP_KERNEL); ++ ++ if (!ab->nss.tx_desc_vaddr[curr_page_idx]) ++ return -ENOMEM; ++ ++ ab->nss.tx_desc_size[curr_page_idx] = alloc_size; ++ curr_page_idx++; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, ++ "curr page %d, allocated %d, total allocated %d\n", ++ curr_page_idx, alloc_size, i + alloc_size); ++ ++ if (curr_page_idx == ATH11K_NSS_MAX_NUMBER_OF_PAGE) { ++ ath11k_warn(ab, "max page number reached while tx desc mem allocation\n"); ++ return -EINVAL; ++ } ++ } ++ *page_idx = curr_page_idx; ++ return 0; ++} ++ ++static int ath11k_nss_fill_tx_desc_info(struct ath11k_base *ab, ++ struct nss_wifili_init_msg *wim) ++{ ++ struct nss_wifili_tx_desc_addtnl_mem_msg *dam; ++ u32 required_size, required_size_ext; ++ struct nss_wifili_tx_desc_init_msg *dim; ++ u32 tx_desc_limit_0 = 0; ++ u32 tx_desc_limit_1 = 0; ++ u32 tx_desc_limit_2 = 0; ++ u32 dam_page_idx = 0; ++ int page_idx = 0; ++ int i; ++ ++ wim->tx_sw_internode_queue_size = ATH11K_WIFIILI_MAX_TX_PROCESSQ; ++ ++ dim = &wim->wtdim; ++ dam = &wim->wtdam; ++ ++ dim->num_pool = ab->num_radios; ++ dim->num_tx_device_limit = ATH11K_WIFILI_MAX_TX_DESC; ++ ++ //TODO Revisit below calc based on platform/mem cfg ++ switch (dim->num_pool) { ++ case 1: ++ tx_desc_limit_0 = ATH11K_WIFILI_DBDC_NUM_TX_DESC; ++ break; ++ case 2: ++ tx_desc_limit_0 = ATH11K_WIFILI_DBDC_NUM_TX_DESC; ++ tx_desc_limit_1 = ATH11K_WIFILI_DBDC_NUM_TX_DESC; ++ break; ++ case 3: ++ tx_desc_limit_0 = ATH11K_WIFILI_DBTC_NUM_TX_DESC; ++ tx_desc_limit_1 = ATH11K_WIFILI_DBTC_NUM_TX_DESC; ++ tx_desc_limit_2 = ATH11K_WIFILI_DBTC_NUM_TX_DESC; ++ break; ++ default: ++ ath11k_warn(ab, "unexpected num radios during tx desc alloc\n"); ++ return -EINVAL; ++ } ++ ++ dim->num_tx_desc = tx_desc_limit_0; ++ dim->num_tx_desc_ext = tx_desc_limit_0; ++ dim->num_tx_desc_2 = tx_desc_limit_1; ++ dim->num_tx_desc_ext_2 = tx_desc_limit_1; ++ dim->num_tx_desc_3 = tx_desc_limit_2; ++ dim->num_tx_desc_ext_3 = tx_desc_limit_2; ++ ++ required_size = (dim->num_tx_desc + dim->num_tx_desc_2 + ++ dim->num_tx_desc_3 + ++ dim->num_pool) * WIFILI_NSS_TX_DESC_SIZE; ++ ++ required_size_ext = (dim->num_tx_desc_ext + dim->num_tx_desc_ext_2 + ++ dim->num_tx_desc_ext_3 + ++ dim->num_pool) * WIFILI_NSS_TX_EXT_DESC_SIZE; ++ ++ if (ath11k_nss_tx_desc_mem_alloc(ab, required_size, &page_idx)) { ++ ath11k_warn(ab, "memory allocation for tx desc of size %d failed\n", ++ required_size); ++ return -ENOMEM; ++ } ++ ++ /* Fill the page number from where extension tx descriptor is available */ ++ dim->ext_desc_page_num = page_idx; ++ ++ if (ath11k_nss_tx_desc_mem_alloc(ab, required_size_ext, &page_idx)) { ++ ath11k_warn(ab, "memory allocation for extension tx desc of size %d failed\n", ++ required_size_ext); ++ return -ENOMEM; ++ } ++ ++ for (i = 0; i < page_idx; i++) { ++ if (i < NSS_WIFILI_MAX_NUMBER_OF_PAGE_MSG) { ++ dim->memory_addr[i] = (u32)ab->nss.tx_desc_paddr[i]; ++ dim->memory_size[i] = (u32)ab->nss.tx_desc_size[i]; ++ dim->num_memaddr++; ++ } else { ++ dam_page_idx = i - NSS_WIFILI_MAX_NUMBER_OF_PAGE_MSG; ++ dam->addtnl_memory_addr[dam_page_idx] = (u32)ab->nss.tx_desc_paddr[i]; ++ dam->addtnl_memory_size[dam_page_idx] = (u32)ab->nss.tx_desc_size[i]; ++ dam->num_addtnl_addr++; ++ } ++ } ++ ++ if (i > NSS_WIFILI_MAX_NUMBER_OF_PAGE_MSG) ++ wim->flags |= WIFILI_ADDTL_MEM_SEG_SET; ++ ++ return 0; ++} ++ ++static int ath11k_nss_get_target_type(struct ath11k_base *ab) ++{ ++ switch (ab->hw_rev) { ++ case ATH11K_HW_IPQ8074: ++ return ATH11K_WIFILI_TARGET_TYPE_QCA8074V2; ++ case ATH11K_HW_IPQ6018_HW10: ++ return ATH11K_WIFILI_TARGET_TYPE_QCA6018; ++ case ATH11K_HW_QCN9074_HW10: ++ return ATH11K_WIFILI_TARGET_TYPE_QCN9074; ++ default: ++ ath11k_warn(ab, "NSS Offload not supported for this HW\n"); ++ return ATH11K_WIFILI_TARGET_TYPE_UNKNOWN; ++ } ++} ++ ++static int ath11k_nss_get_interface_type(struct ath11k_base *ab) ++{ ++ switch (ab->hw_rev) { ++ case ATH11K_HW_IPQ8074: ++ case ATH11K_HW_IPQ6018_HW10: ++ return NSS_WIFILI_INTERNAL_INTERFACE; ++ case ATH11K_HW_QCN9074_HW10: ++ return nss_get_available_wifili_external_if(); ++ default: ++ /* This can't happen since we validated target type earlier */ ++ WARN_ON(1); ++ return NSS_MAX_NET_INTERFACES; ++ } ++} ++ ++static int ath11k_nss_get_dynamic_interface_type(struct ath11k_base *ab) ++{ ++ switch (ab->nss.if_num) { ++ case NSS_WIFILI_INTERNAL_INTERFACE: ++ return NSS_DYNAMIC_INTERFACE_TYPE_WIFILI_INTERNAL; ++ case NSS_WIFILI_EXTERNAL_INTERFACE0: ++ return NSS_DYNAMIC_INTERFACE_TYPE_WIFILI_EXTERNAL0; ++ case NSS_WIFILI_EXTERNAL_INTERFACE1: ++ return NSS_DYNAMIC_INTERFACE_TYPE_WIFILI_EXTERNAL1; ++ default: ++ ath11k_warn(ab, "NSS Offload invalid interface\n"); ++ return NSS_DYNAMIC_INTERFACE_TYPE_NONE; ++ } ++} ++ ++static int ath11k_nss_init(struct ath11k_base *ab) ++{ ++ struct nss_wifili_init_msg *wim = NULL; ++ struct nss_wifili_msg *wlmsg = NULL; ++ struct nss_ctx_instance *nss_contex; ++ nss_wifili_msg_callback_t msg_cb; ++ u32 target_type; ++ u32 features = 0; ++ nss_tx_status_t status; ++ struct ath11k_dp *dp; ++ int i, ret; ++ ++ dp = &ab->dp; ++ ++ target_type = ath11k_nss_get_target_type(ab); ++ ++ if (target_type == ATH11K_WIFILI_TARGET_TYPE_UNKNOWN) ++ return -ENOTSUPP; ++ ++ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); ++ if (!wlmsg) ++ return -ENOMEM; ++ ++ wim = &wlmsg->msg.init; ++ ++ wim->target_type = target_type; ++ ++ /* fill rx parameters to initialize rx context */ ++ wim->wrip.tlv_size = ab->hw_params.hal_desc_sz; ++ wim->wrip.rx_buf_len = DP_RX_BUFFER_SIZE; ++ ++ /* fill hal srng message */ ++ wim->hssm.dev_base_addr = (u32)ab->mem_pa; ++ wim->hssm.shadow_rdptr_mem_addr = (u32)ab->hal.rdp.paddr; ++ wim->hssm.shadow_wrptr_mem_addr = (u32)ab->hal.wrp.paddr; ++ wim->hssm.lmac_rings_start_id = HAL_SRNG_RING_ID_LMAC1_ID_START; ++ ++ /* fill TCL data/completion ring info */ ++ wim->num_tcl_data_rings = DP_TCL_NUM_RING_MAX; ++ for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { ++ ath11k_nss_fill_srng_info(ab, dp->tx_ring[i].tcl_data_ring.ring_id, ++ &wim->tcl_ring_info[i]); ++ ath11k_nss_fill_srng_info(ab, dp->tx_ring[i].tcl_comp_ring.ring_id, ++ &wim->tx_comp_ring[i]); ++ } ++ ++ /* allocate tx desc memory for NSS and fill corresponding info */ ++ ret = ath11k_nss_fill_tx_desc_info(ab, wim); ++ if (ret) ++ goto free; ++ ++ /* fill reo dest ring info */ ++ wim->num_reo_dest_rings = DP_REO_DST_RING_MAX; ++ for (i = 0; i < DP_REO_DST_RING_MAX; i++) { ++ ath11k_nss_fill_srng_info(ab, dp->reo_dst_ring[i].ring_id, ++ &wim->reo_dest_ring[i]); ++ } ++ ++ /* fill reo reinject ring info */ ++ ath11k_nss_fill_srng_info(ab, dp->reo_reinject_ring.ring_id, ++ &wim->reo_reinject_ring); ++ ++ /* fill reo release ring info */ ++ ath11k_nss_fill_srng_info(ab, dp->rx_rel_ring.ring_id, ++ &wim->rx_rel_ring); ++ ++ /* fill reo exception ring info */ ++ ath11k_nss_fill_srng_info(ab, dp->reo_except_ring.ring_id, ++ &wim->reo_exception_ring); ++ ++ ab->nss.if_num = ath11k_nss_get_interface_type(ab); ++ ++ ath11k_info(ab, "nss init soc nss if_num %d userpd_id %d\n", ab->nss.if_num, ab->userpd_id); ++ ++ if (ab->nss.if_num >= NSS_MAX_NET_INTERFACES) { ++ ath11k_warn(ab, "NSS invalid interface\n"); ++ goto free; ++ } ++ ++ /* register callbacks for events and exceptions with nss */ ++ nss_contex = nss_register_wifili_if(ab->nss.if_num, NULL, ++ (nss_wifili_callback_t)ath11k_nss_wifili_ext_callback_fn, ++ (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive, ++ (struct net_device *)ab, features); ++ ++ if (!nss_contex) { ++ ath11k_warn(ab, "nss wifili register failure\n"); ++ goto free; ++ } ++ ++ if (nss_cmn_get_state(nss_contex) != NSS_STATE_INITIALIZED) { ++ ath11k_warn(ab, "nss state in default init state\n"); ++ goto free; ++ } ++ ++ /* The registered soc context is stored in ab, and will be used for ++ * all soc related messages with nss ++ */ ++ ab->nss.ctx = nss_contex; ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ /* Initialize the common part of the wlmsg */ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_INIT_MSG, ++ sizeof(struct nss_wifili_init_msg), ++ msg_cb, NULL); ++ ++ reinit_completion(&ab->nss.complete); ++ ++ /* Note: response is contention free during init sequence */ ++ ab->nss.response = ATH11K_NSS_MSG_ACK; ++ ++ status = nss_wifili_tx_msg(nss_contex, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "failure to send nss init msg\n"); ++ goto unregister; ++ } ++ ++ 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 nss init msg response\n"); ++ goto unregister; ++ } ++ ++ /* Check if the response is success from the callback */ ++ if (ab->nss.response != ATH11K_NSS_MSG_ACK) ++ goto unregister; ++ ++ kfree(wlmsg); ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "NSS Init Message TX Success %p %d\n", ++ ab->nss.ctx, ab->nss.if_num); ++ return 0; ++ ++unregister: ++ nss_unregister_wifili_if(ab->nss.if_num); ++free: ++ ath11k_nss_tx_desc_mem_free(ab); ++ kfree(wlmsg); ++ return -EINVAL; ++} ++ ++static int ath11k_nss_stats_cfg(struct ath11k *ar, int nss_msg, int enable) ++{ ++ struct nss_wifili_msg *wlmsg = NULL; ++ struct nss_wifili_stats_cfg_msg *stats_cfg; ++ nss_wifili_msg_callback_t msg_cb; ++ nss_tx_status_t status; ++ struct ath11k_base *ab = ar->ab; ++ int ret = 0; ++ ++ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); ++ if (!wlmsg) ++ return -ENOMEM; ++ ++ stats_cfg = &wlmsg->msg.scm; ++ stats_cfg->cfg = enable; ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ nss_msg, ++ sizeof(struct nss_wifili_stats_cfg_msg), ++ msg_cb, NULL); ++ ++ status = nss_wifili_tx_msg(ar->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "nss stats cfg %d msg tx failure\n", nss_msg); ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "nss stats %d enable %d\n", nss_msg, enable); ++ ++free: ++ kfree(wlmsg); ++ return ret; ++} ++ ++static void ath11k_nss_sojourn_stats_disable(struct ath11k *ar) ++{ ++ ath11k_nss_stats_cfg(ar, NSS_WIFILI_STATS_V2_CFG_MSG, ++ ATH11K_NSS_STATS_DISABLE); ++} ++ ++void ath11k_nss_peer_stats_disable(struct ath11k *ar) ++{ ++ ath11k_nss_stats_cfg(ar, NSS_WIFILI_STATS_CFG_MSG, ++ ATH11K_NSS_STATS_DISABLE); ++} ++ ++void ath11k_nss_peer_stats_enable(struct ath11k *ar) ++{ ++ ath11k_nss_stats_cfg(ar, NSS_WIFILI_STATS_CFG_MSG, ++ ATH11K_NSS_STATS_ENABLE); ++} ++ ++int ath11k_nss_pdev_init(struct ath11k_base *ab, int radio_id) ++{ ++ struct ath11k *ar = ab->pdevs[radio_id].ar; ++ struct nss_wifili_pdev_init_msg *pdevmsg; ++ struct nss_wifili_msg *wlmsg = NULL; ++ nss_wifili_msg_callback_t msg_cb; ++ nss_tx_status_t status; ++ int radio_if_num = -1; ++ int refill_ring_id; ++ int features = 0; ++ int dyn_if_type; ++ int ret, i; ++ ++ dyn_if_type = ath11k_nss_get_dynamic_interface_type(ab); ++ ++ /* Allocate a node for dynamic interface */ ++ radio_if_num = nss_dynamic_interface_alloc_node(dyn_if_type); ++ ++ if (radio_if_num < 0) ++ return -EINVAL; ++ ++ /* The ifnum and registered radio context is stored in ar and used ++ * for messages related to vdev/radio ++ */ ++ ar->nss.if_num = radio_if_num; ++ ++ /* No callbacks are registered for radio specific events/data */ ++ ar->nss.ctx = nss_register_wifili_radio_if((u32)radio_if_num, NULL, ++ NULL, NULL, (struct net_device *)ar, ++ features); ++ ++ if (!ar->nss.ctx) { ++ ath11k_warn(ab, "failure during nss pdev register\n"); ++ ret = -EINVAL; ++ goto dealloc; ++ } ++ ++ 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); ++ ++ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); ++ if (!wlmsg) { ++ ret = -ENOMEM; ++ goto unregister; ++ } ++ ++ pdevmsg = &wlmsg->msg.pdevmsg; ++ ++ pdevmsg->radio_id = radio_id; ++ 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; ++ ++ /* Store rxdma ring info to the message */ ++ refill_ring_id = ar->dp.rx_refill_buf_ring.refill_buf_ring.ring_id; ++ ath11k_nss_fill_srng_info(ab, refill_ring_id, &pdevmsg->rxdma_ring); ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_PDEV_INIT_MSG, ++ sizeof(struct nss_wifili_pdev_init_msg), ++ msg_cb, NULL); ++ ++ reinit_completion(&ab->nss.complete); ++ ++ /* Note: response is contention free during init sequence */ ++ ab->nss.response = ATH11K_NSS_MSG_ACK; ++ ++ status = nss_wifili_tx_msg(ar->nss.ctx, wlmsg); ++ ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "nss send pdev msg tx error : %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 pdev init msg response\n"); ++ ret = -ETIMEDOUT; ++ goto free; ++ } ++ ++ /* Check if the response is success from the callback */ ++ if (ab->nss.response != ATH11K_NSS_MSG_ACK) { ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ kfree(wlmsg); ++ ++ /* Disable nss sojourn stats by default */ ++ ath11k_nss_sojourn_stats_disable(ar); ++ /* Enable nss wifili peer stats by default */ ++ ath11k_nss_peer_stats_enable(ar); ++ ++ /*TODO CFG Tx buffer limit as per no clients range per radio ++ * this needs to be based on target/mem cfg ++ * similar to tx desc cfg at soc init per radio ++ */ ++ ++ for (i = 0; i < ATH11K_NSS_RADIO_TX_LIMIT_RANGE; i++) ++ ath11k_nss_radio_buf_cfg(ar, i, ATH11K_NSS_RADIO_TX_LIMIT_RANGE3); ++ ++ return 0; ++ ++free: ++ kfree(wlmsg); ++unregister: ++ nss_unregister_wifili_radio_if(ar->nss.if_num); ++dealloc: ++ nss_dynamic_interface_dealloc_node(ar->nss.if_num, dyn_if_type); ++ return ret; ++} ++ ++/* TODO : Check if start, reset and stop messages can be done using single function as ++ * body is similar, having it now for clarity */ ++ ++int ath11k_nss_start(struct ath11k_base *ab) ++{ ++ struct nss_wifili_msg *wlmsg = NULL; ++ nss_wifili_msg_callback_t msg_cb; ++ nss_tx_status_t status; ++ int ret; ++ ++ 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; ++ ++ /* Empty message for NSS Start message */ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_START_MSG, ++ 0, ++ msg_cb, NULL); ++ ++ reinit_completion(&ab->nss.complete); ++ ++ /* Note: response is contention free during init sequence */ ++ ab->nss.response = ATH11K_NSS_MSG_ACK; ++ ++ status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg); ++ ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "nss send start msg tx error %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 response for nss start msg\n"); ++ ret = -ETIMEDOUT; ++ goto free; ++ } ++ ++ /* Check if the response is success from the callback */ ++ if (ab->nss.response != ATH11K_NSS_MSG_ACK) { ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ /* NSS Start success */ ++ ret = 0; ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "nss start success\n"); ++ ++free: ++ kfree(wlmsg); ++ return ret; ++} ++ ++static void ath11k_nss_reset(struct ath11k_base *ab) ++{ ++ struct nss_wifili_msg *wlmsg = NULL; ++ nss_wifili_msg_callback_t msg_cb; ++ nss_tx_status_t status; ++ int ret; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "NSS reset\n"); ++ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); ++ if (!wlmsg) { ++ ath11k_warn(ab, "mem allocation failure during nss reset\n"); ++ return; ++ } ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ /* Empty message for NSS Reset message */ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_SOC_RESET_MSG, ++ 0, ++ msg_cb, NULL); ++ ++ reinit_completion(&ab->nss.complete); ++ ++ /* Note: response is contention free during deinit sequence */ ++ ab->nss.response = ATH11K_NSS_MSG_ACK; ++ ++ status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg); ++ ++ /* Add a retry mechanism to reset nss until success */ ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "nss send reset msg tx error %d\n", status); ++ 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 response for nss reset msg\n"); ++ goto free; ++ } ++ ++ /* Check if the response is success from the callback */ ++ if (ab->nss.response != ATH11K_NSS_MSG_ACK) { ++ ath11k_warn(ab, "failure response during nss reset %d\n", ab->nss.response); ++ goto free; ++ } ++ ++ /* Unregister wifili interface */ ++ nss_unregister_wifili_if(ab->nss.if_num); ++ ++free: ++ kfree(wlmsg); ++} ++ ++static int ath11k_nss_stop(struct ath11k_base *ab) ++{ ++ struct nss_wifili_msg *wlmsg = NULL; ++ nss_wifili_msg_callback_t msg_cb; ++ nss_tx_status_t status; ++ int ret; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "NSS stop\n"); ++ 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; ++ ++ /* Empty message for Stop command */ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_STOP_MSG, ++ 0, ++ msg_cb, NULL); ++ ++ reinit_completion(&ab->nss.complete); ++ ++ /* Note: response is contention free during deinit sequence */ ++ ab->nss.response = ATH11K_NSS_MSG_ACK; ++ ++ status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg); ++ ++ /* Add a retry mechanism to stop nss until success */ ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "nss send stop msg tx error %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 response for nss stop msg\n"); ++ ret = -ETIMEDOUT; ++ goto free; ++ } ++ ++ /* Check if the response is success from the callback */ ++ if (ab->nss.response != ATH11K_NSS_MSG_ACK) { ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ /* NSS Stop success */ ++ ret = 0; ++free: ++ kfree(wlmsg); ++ return ret; ++} ++ ++int ath11k_nss_pdev_deinit(struct ath11k_base *ab, int radio_id) ++{ ++ struct ath11k *ar = ab->pdevs[radio_id].ar; ++ struct nss_wifili_pdev_deinit_msg *deinit; ++ struct nss_wifili_msg *wlmsg = NULL; ++ nss_wifili_msg_callback_t msg_cb; ++ nss_tx_status_t status; ++ int dyn_if_type; ++ int ret; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "NSS pdev %d deinit\n", radio_id); ++ dyn_if_type = ath11k_nss_get_dynamic_interface_type(ab); ++ ++ /* Disable NSS wifili peer stats before teardown */ ++ if (ab->nss.stats_enabled) ++ ath11k_nss_peer_stats_disable(ar); ++ ++ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); ++ if (!wlmsg) ++ return -ENOMEM; ++ ++ deinit = &wlmsg->msg.pdevdeinit; ++ deinit->ifnum = radio_id; ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_PDEV_DEINIT_MSG, ++ sizeof(struct nss_wifili_pdev_deinit_msg), ++ msg_cb, NULL); ++ ++ reinit_completion(&ab->nss.complete); ++ ++ /* Note: response is contention free during deinit sequence */ ++ ab->nss.response = ATH11K_NSS_MSG_ACK; ++ ++ status = nss_wifili_tx_msg(ar->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "nss send pdev deinit msg tx error %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 pdev deinit msg response\n"); ++ ret = -ETIMEDOUT; ++ goto free; ++ } ++ ++ /* Check if the response is success from the callback */ ++ if (ab->nss.response != ATH11K_NSS_MSG_ACK) { ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ /* pdev deinit msg success, dealloc, deregister and return */ ++ ret = 0; ++ ++ nss_dynamic_interface_dealloc_node(ar->nss.if_num, dyn_if_type); ++ nss_unregister_wifili_radio_if(ar->nss.if_num); ++free: ++ kfree(wlmsg); ++ return ret; ++} ++ ++int ath11k_nss_teardown(struct ath11k_base *ab) ++{ ++ int i, ret; ++ ++ if (!ab->nss.enabled) ++ return 0; ++ ++ ath11k_nss_stop(ab); ++ ++ for (i = 0; i < ab->num_radios ; i++) { ++ ret = ath11k_nss_pdev_deinit(ab, i); ++ if (ret) ++ ath11k_warn(ab, "failure during pdev%d deinit\n", i); ++ } ++ ++ ath11k_nss_reset(ab); ++ ath11k_nss_tx_desc_mem_free(ab); ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "NSS Teardown Complete\n"); ++ ++ return 0; ++} ++ ++int ath11k_nss_setup(struct ath11k_base *ab) ++{ ++ int i; ++ int ret = 0; ++ u32 target_type; ++ ++ if (!ab->nss.enabled) ++ return 0; ++ ++ target_type = ath11k_nss_get_target_type(ab); ++ ++ if (target_type == ATH11K_WIFILI_TARGET_TYPE_UNKNOWN) ++ return -ENOTSUPP; ++ ++ /* Verify NSS support is enabled */ ++ if (nss_cmn_get_nss_enabled() == false) { ++ ath11k_warn(ab, "NSS offload support disabled, falling back to default mode\n"); ++ return -ENOTSUPP; ++ } ++ ++ /* Initialize completion for verifying NSS message response */ ++ init_completion(&ab->nss.complete); ++ ++ /* Setup common resources for NSS */ ++ ret = ath11k_nss_init(ab); ++ if (ret) { ++ ath11k_warn(ab, "NSS SOC Initialization Failed :%d\n", ret); ++ goto fail; ++ } ++ ++ /* Setup pdev related resources for NSS */ ++ for (i = 0; i < ab->num_radios; i++) { ++ ret = ath11k_nss_pdev_init(ab, i); ++ if (ret) { ++ ath11k_warn(ab, "NSS PDEV %d Initialization Failed :%d\n", i, ret); ++ goto pdev_deinit; ++ } ++ } ++ ++ /* Set the NSS statemachine to start */ ++ ret = ath11k_nss_start(ab); ++ if (ret) { ++ ath11k_warn(ab, "NSS Start Failed : %d\n", ret); ++ goto pdev_deinit; ++ } ++ ++ /* Default nexthop interface is set to ETH RX */ ++ ret = nss_wifi_vdev_base_set_next_hop(ab->nss.ctx, NSS_ETH_RX_INTERFACE); ++ if (ret != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "Failure to set default next hop : %d\n", ret); ++ goto stop; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "NSS Setup Complete\n"); ++ return ret; ++ ++stop: ++ ath11k_nss_stop(ab); ++ ++pdev_deinit: ++ for (i -= 1; i >= 0; i--) ++ ath11k_nss_pdev_deinit(ab, i); ++ ++ ath11k_nss_reset(ab); ++ ath11k_nss_tx_desc_mem_free(ab); ++fail: ++ return ret; ++} +--- /dev/null ++++ b/drivers/net/wireless/ath/ath11k/nss.h +@@ -0,0 +1,305 @@ ++/* SPDX-License-Identifier: BSD-3-Clause-Clear */ ++/* ++ * Copyright (c) 2020 The Linux Foundation. All rights reserved. ++ */ ++ ++#ifndef ATH11K_NSS_H ++#define ATH11K_NSS_H ++ ++#include "net/cfg80211.h" ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++#include ++#include ++ ++#endif ++struct ath11k; ++struct ath11k_base; ++struct ath11k_vif; ++struct ath11k_peer; ++struct ath11k_sta; ++struct hal_rx_mon_ppdu_info; ++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 0x80000000 ++ ++/* WIFILI Supported Target Types */ ++#define ATH11K_WIFILI_TARGET_TYPE_UNKNOWN 0xFF ++#define ATH11K_WIFILI_TARGET_TYPE_QCA8074 20 ++#define ATH11K_WIFILI_TARGET_TYPE_QCA8074V2 24 ++#define ATH11K_WIFILI_TARGET_TYPE_QCA6018 25 ++#define ATH11K_WIFILI_TARGET_TYPE_QCN9074 26 ++#define ATH11K_WIFILI_TARGET_TYPE_QCA5018 29 ++ ++/* Max limit for NSS Queue */ ++#define ATH11K_WIFIILI_MAX_TX_PROCESSQ 1024 ++ ++/* Max TX Desc limit */ ++#define ATH11K_WIFILI_MAX_TX_DESC 65536 ++ ++/* TX Desc related info */ ++/*TODO : Check this again during experiments for lowmem or ++ changes for platforms based on num radios supported */ ++#define ATH11K_WIFILI_DBDC_NUM_TX_DESC (1024 * 8) ++#define ATH11K_WIFILI_DBTC_NUM_TX_DESC (1024 * 8) ++ ++// TODO Revisit these page size calc ++#define WIFILI_NSS_TX_DESC_SIZE 20*4 ++#define WIFILI_NSS_TX_EXT_DESC_SIZE 40*4 ++/* Number of desc per page(12bit) should be<4096, page limit per 1024 byte is 80*3=240 */ ++#define WIFILI_NSS_TX_DESC_PAGE_LIMIT 240 ++#define WIFILI_NSS_MAX_MEM_PAGE_SIZE (WIFILI_NSS_TX_DESC_PAGE_LIMIT * 1024) ++#define WIFILI_NSS_MAX_EXT_MEM_PAGE_SIZE (WIFILI_NSS_TX_DESC_PAGE_LIMIT * 1024) ++#define WIFILI_RX_DESC_POOL_WEIGHT 3 ++ ++/* Status of the NSS messages sent from driver */ ++#define ATH11K_NSS_MSG_ACK 0 ++/* Timeout for waiting for response from NSS on TX msg */ ++#define ATH11K_NSS_MSG_TIMEOUT_MS 5000 ++ ++/* Init Flags */ ++#define WIFILI_NSS_CCE_DISABLED 0x1 ++#define WIFILI_ADDTL_MEM_SEG_SET 0x000000002 ++ ++/* ATH11K NSS PEER Info */ ++/* Host memory allocated for peer info storage in nss */ ++#define WIFILI_NSS_PEER_BYTE_SIZE NSS_WIFILI_PEER_SIZE ++ ++/* ATH11K NSS Stats */ ++#define ATH11K_NSS_STATS_ENABLE 1 ++#define ATH11K_NSS_STATS_DISABLE 0 ++ ++/* TX Buf cfg range */ ++#define ATH11K_NSS_RADIO_TX_LIMIT_RANGE 4 ++ ++/* TODO : Analysis based on platform */ ++/* TX Limit till 64 clients */ ++#define ATH11K_NSS_RADIO_TX_LIMIT_RANGE0 8192 ++/* TX Limit till 128 clients */ ++#define ATH11K_NSS_RADIO_TX_LIMIT_RANGE1 8192 ++/* TX Limit till 256 clients */ ++#define ATH11K_NSS_RADIO_TX_LIMIT_RANGE2 8192 ++/* TX Limit > 256 clients */ ++#define ATH11K_NSS_RADIO_TX_LIMIT_RANGE3 8192 ++ ++#define ATH11K_NSS_MAX_NUMBER_OF_PAGE 96 ++ ++#define NSS_TX_TID_MAX 8 ++ ++#define ATH11K_NSS_TXRX_NETDEV_STATS(txrx, vif, len, pkt_count) \ ++do { \ ++ struct wireless_dev *wdev = ieee80211_vif_to_wdev(vif); \ ++ struct pcpu_sw_netstats *tstats; \ ++ \ ++ if (!wdev) \ ++ break; \ ++ tstats = this_cpu_ptr(netdev_tstats(wdev->netdev)); \ ++ u64_stats_update_begin(&tstats->syncp); \ ++ u64_stats_add(&tstats->txrx ## _packets, pkt_count); \ ++ u64_stats_add(&tstats->txrx ## _bytes, len); \ ++ u64_stats_update_end(&tstats->syncp); \ ++} while (0) ++ ++enum ath11k_nss_opmode { ++ ATH11K_NSS_OPMODE_UNKNOWN, ++ ATH11K_NSS_OPMODE_AP, ++ ATH11K_NSS_OPMODE_IBSS, ++ ATH11K_NSS_OPMODE_STA, ++ ATH11K_NSS_OPMODE_MONITOR, ++}; ++ ++struct peer_stats { ++ u64 last_rx; ++ u64 last_ack; ++ u32 tx_packets; ++ u32 tx_bytes; ++ u32 tx_retries; ++ u32 tx_failed; ++ u32 rx_packets; ++ u32 rx_bytes; ++ u32 rx_dropped; ++ u32 last_rxdrop; ++ struct rate_info rxrate; ++}; ++ ++enum ath11k_nss_peer_sec_type { ++ PEER_SEC_TYPE_NONE, ++ PEER_SEC_TYPE_WEP128, ++ PEER_SEC_TYPE_WEP104, ++ PEER_SEC_TYPE_WEP40, ++ PEER_SEC_TYPE_TKIP, ++ PEER_SEC_TYPE_TKIP_NOMIC, ++ PEER_SEC_TYPE_AES_CCMP, ++ PEER_SEC_TYPE_WAPI, ++ PEER_SEC_TYPE_AES_CCMP_256, ++ PEER_SEC_TYPE_AES_GCMP, ++ PEER_SEC_TYPE_AES_GCMP_256, ++ PEER_SEC_TYPES_MAX ++}; ++ ++/* this holds the memory allocated for nss managed peer info */ ++struct ath11k_nss_peer { ++ uint32_t *vaddr; ++ dma_addr_t paddr; ++ struct peer_stats *nss_stats; ++ struct completion complete; ++}; ++ ++/* 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; ++ /* Used for completion status for vdev config nss messages */ ++ struct completion complete; ++ /* Keep the copy of encap type for nss */ ++ int encap; ++ /* Keep the copy of decap type for nss */ ++ int decap; ++ bool created; ++}; ++ ++/* Structure to hold the pdev/radio related info for nss offload support */ ++struct ath11k_nss { ++ /* dynamic ifnum allocated by nss driver for pdev */ ++ int if_num; ++ /* Radio/pdev Context obtained on pdev register */ ++ void* ctx; ++}; ++ ++/* Structure to hold the soc related info for nss offload support */ ++struct ath11k_soc_nss { ++ /* turn on/off nss offload support in ath11k */ ++ bool enabled; ++ /* turn on/off nss stats support in ath11k */ ++ bool stats_enabled; ++ /* soc nss ctx */ ++ void* ctx; ++ /* if_num to be used for soc related nss messages */ ++ int if_num; ++ /* Completion to nss message response */ ++ struct completion complete; ++ /* Response to nss messages are stored here on msg callback ++ * used only in contention free messages during init */ ++ int response; ++ /* Below is used for identifying allocated tx descriptors */ ++ dma_addr_t tx_desc_paddr[ATH11K_NSS_MAX_NUMBER_OF_PAGE]; ++ uint32_t * tx_desc_vaddr[ATH11K_NSS_MAX_NUMBER_OF_PAGE]; ++ uint32_t tx_desc_size[ATH11K_NSS_MAX_NUMBER_OF_PAGE]; ++}; ++ ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++int ath11k_nss_tx(struct ath11k_vif *arvif, struct sk_buff *skb); ++int ath11k_nss_vdev_set_cmd(struct ath11k_vif *arvif, int cmd, int val); ++int ath11k_nss_vdev_create(struct ath11k_vif *arvif); ++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); ++int ath11k_nss_peer_delete(struct ath11k_base *ab, const u8 *addr); ++int ath11k_nss_set_peer_authorize(struct ath11k *ar, u16 peer_id); ++int ath11k_nss_peer_create(struct ath11k_base *ab, struct ath11k_peer *peer); ++void ath11k_nss_peer_stats_enable(struct ath11k *ar); ++void ath11k_nss_peer_stats_disable(struct ath11k *ar); ++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, ++ struct ieee80211_sta *sta, ++ struct ath11k_sta *arsta); ++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); ++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); ++#else ++static inline int ath11k_nss_tx(struct ath11k_vif *arvif, struct sk_buff *skb) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_vdev_set_cmd(struct ath11k_vif *arvif, int cmd, int val) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_vdev_create(struct ath11k_vif *arvif) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_set_peer_authorize(struct ath11k *ar, u16 peer_id) ++{ ++ return 0; ++} ++ ++static inline void ath11k_nss_vdev_delete(struct ath11k_vif *arvif) ++{ ++} ++ ++static inline void ath11k_nss_update_sta_stats(struct station_info *sinfo, ++ struct ieee80211_sta *sta, ++ struct ath11k_sta *arsta) ++{ ++ return; ++} ++ ++static inline 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) ++{ ++ return; ++} ++ ++static inline int ath11k_nss_vdev_up(struct ath11k_vif *arvif) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_vdev_down(struct ath11k_vif *arvif) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_peer_delete(struct ath11k_base *ab, const u8 *addr) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_peer_create(struct ath11k_base *ab, struct ath11k_peer *peer) ++{ ++ return 0; ++} ++ ++static inline void ath11k_nss_peer_stats_enable(struct ath11k *ar) ++{ ++ return; ++} ++ ++static inline void ath11k_nss_peer_stats_disable(struct ath11k *ar) ++{ ++ return; ++} ++ ++static inline int ath11k_nss_set_peer_sec_type(struct ath11k *ar, struct ath11k_peer *peer, ++ struct ieee80211_key_conf *key_conf) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_setup(struct ath11k_base *ab) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_teardown(struct ath11k_base *ab) ++{ ++ return 0; ++} ++ ++static inline void ath11k_nss_ext_rx_stats(struct ath11k_base *ab, ++ struct htt_rx_ring_tlv_filter *tlv_filter) ++{ ++ return; ++} ++#endif /* CPTCFG_ATH11K_NSS_SUPPORT */ ++#endif +--- a/drivers/net/wireless/ath/ath11k/hif.h ++++ b/drivers/net/wireless/ath/ath11k/hif.h +@@ -30,6 +30,7 @@ struct ath11k_hif_ops { + void (*ce_irq_enable)(struct ath11k_base *ab); + void (*ce_irq_disable)(struct ath11k_base *ab); + void (*get_ce_msi_idx)(struct ath11k_base *ab, u32 ce_id, u32 *msi_idx); ++ u32 (*get_window_offset)(struct ath11k_base *ab, u32 offset); + }; + + static inline void ath11k_hif_ce_irq_enable(struct ath11k_base *ab) +@@ -136,6 +137,14 @@ static inline void ath11k_get_msi_addres + ab->hif.ops->get_msi_address(ab, msi_addr_lo, msi_addr_hi); + } + ++static inline u32 ath11k_hif_get_window_offset(struct ath11k_base *ab, u32 offset) ++{ ++ if (ab->hif.ops->get_window_offset) ++ return ab->hif.ops->get_window_offset(ab, offset); ++ ++ return offset; ++} ++ + static inline void ath11k_get_ce_msi_idx(struct ath11k_base *ab, u32 ce_id, + u32 *msi_data_idx) + { +--- a/drivers/net/wireless/ath/ath11k/pci.c ++++ b/drivers/net/wireless/ath/ath11k/pci.c +@@ -67,6 +67,20 @@ static u32 ath11k_pci_get_window_start(s + return ATH11K_PCI_WINDOW_START; + } + ++static inline u32 ath11k_pci_get_window_offset(struct ath11k_base *ab, ++ u32 offset) ++{ ++ u32 window_start; ++ ++ if (ab->hw_params.static_window_map) { ++ window_start = ath11k_pci_get_window_start(ab, offset); ++ ++ if (window_start) ++ offset = window_start + (offset & ATH11K_PCI_WINDOW_RANGE_MASK); ++ } ++ return offset; ++} ++ + 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 + .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, ++ .get_window_offset = ath11k_pci_get_window_offset, + .get_ce_msi_idx = ath11k_pcic_get_ce_msi_idx, + }; + +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -992,6 +992,29 @@ unlock_exit: + spin_unlock_bh(&ab->base_lock); + } + ++/* Sends WMI config to filter packets to route packets to WBM release ring */ ++int ath11k_dp_rx_pkt_type_filter(struct ath11k *ar, enum ath11k_routing_pkt_type pkt_type, u32 meta_data) ++{ ++ struct ath11k_wmi_pkt_route_param param; ++ int ret; ++ ++ /* Routing Eapol packets to CCE is only allowed now */ ++ if (pkt_type != ATH11K_PKT_TYPE_EAP) ++ return -EINVAL; ++ ++ param.opcode = ATH11K_WMI_PKTROUTE_ADD; ++ param.meta_data = meta_data; ++ param.dst_ring = ATH11K_ROUTE_WBM_RELEASE; ++ param.dst_ring_handler = ATH11K_WMI_PKTROUTE_USE_CCE; ++ param.route_type_bmap = 1 << pkt_type; ++ ++ ret = ath11k_wmi_send_pdev_pkt_route(ar, ¶m); ++ if (ret) ++ ath11k_warn(ar->ab, "failed to configure pkt route %d", ret); ++ ++ return ret; ++} ++ + 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) +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -1164,6 +1164,44 @@ int ath11k_wmi_send_pdev_set_regdomain(s + return ret; + } + ++int ath11k_wmi_send_pdev_pkt_route(struct ath11k *ar, struct ath11k_wmi_pkt_route_param *param) ++{ ++ struct ath11k_pdev_wmi *wmi = ar->wmi; ++ struct wmi_pdev_pkt_route_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_pkt_route_cmd *)skb->data; ++ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, ++ WMI_TAG_PDEV_UPDATE_PKT_ROUTING_CMD) | ++ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); ++ ++ cmd->pdev_id = ar->pdev->pdev_id; ++ cmd->opcode = param->opcode; ++ cmd->route_type_bmap = param->route_type_bmap; ++ cmd->dst_ring = param->dst_ring; ++ cmd->meta_data = param->meta_data; ++ cmd->dst_ring_handler = param->dst_ring_handler; ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, ++ "WMI pdev pkt route opcode %d route_bmap %d dst_ring %d meta_datan %d dst_ringg_handler %d\n", ++ param->opcode, param->route_type_bmap, ++ param->dst_ring, param->meta_data, param->dst_ring_handler); ++ ++ ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PDEV_UPDATE_PKT_ROUTING_CMDID); ++ if (ret) { ++ ath11k_warn(ar->ab, ++ "failed to send WMI_PDEV_UPDATE_PKT_ROUTING cmd\n"); ++ dev_kfree_skb(skb); ++ } ++ ++ return ret; ++} ++ + int ath11k_wmi_set_peer_param(struct ath11k *ar, const u8 *peer_addr, + u32 vdev_id, u32 param_id, u32 param_val) + { +--- a/drivers/net/wireless/ath/ath11k/wmi.h ++++ b/drivers/net/wireless/ath/ath11k/wmi.h +@@ -2873,6 +2873,27 @@ struct pdev_set_regdomain_params { + u32 pdev_id; + }; + ++ /* Defines various options for routing policy */ ++enum wmi_pdev_dest_ring_handler_type { ++ ATH11K_WMI_PKTROUTE_USE_CCE = 0, ++ ATH11K_WMI_PKTROUTE_USE_ASPT = 1, ++ ATH11K_WMI_PKTROUTE_USE_FSE = 2, ++ ATH11K_WMI_PKTROUTE_USE_CCE2 = 3, ++}; ++ ++enum ath11k_wmi_pkt_route_opcode { ++ ATH11K_WMI_PKTROUTE_ADD, ++ ATH11K_WMI_PKTROUTE_DEL, ++}; ++ ++struct ath11k_wmi_pkt_route_param { ++ enum ath11k_wmi_pkt_route_opcode opcode; ++ u32 route_type_bmap; ++ u32 dst_ring_handler; ++ u32 dst_ring; ++ u32 meta_data; ++}; ++ + struct rx_reorder_queue_remove_params { + u8 *peer_macaddr; + u16 vdev_id; +@@ -3121,6 +3142,16 @@ struct wmi_pdev_set_regdomain_cmd { + u32 dfs_domain; + } __packed; + ++struct wmi_pdev_pkt_route_cmd { ++ u32 tlv_header; ++ u32 pdev_id; ++ u32 opcode; ++ u32 route_type_bmap; ++ u32 dst_ring; ++ u32 meta_data; ++ u32 dst_ring_handler; ++} __packed; ++ + struct wmi_peer_set_param_cmd { + u32 tlv_header; + u32 vdev_id; +@@ -6364,6 +6395,8 @@ int ath11k_wmi_send_peer_create_cmd(stru + int ath11k_wmi_vdev_set_param_cmd(struct ath11k *ar, u32 vdev_id, + u32 param_id, u32 param_value); + ++int ath11k_wmi_send_pdev_pkt_route(struct ath11k *ar, ++ struct ath11k_wmi_pkt_route_param *param); + int ath11k_wmi_set_sta_ps_param(struct ath11k *ar, u32 vdev_id, + u32 param, u32 param_value); + int ath11k_wmi_force_fw_hang_cmd(struct ath11k *ar, u32 type, u32 delay_time_ms); +--- a/drivers/net/wireless/ath/ath11k/dp_rx.h ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.h +@@ -20,6 +20,34 @@ + #define DP_RX_MPDU_ERR_MPDU_LEN BIT(6) + #define DP_RX_MPDU_ERR_UNENCRYPTED_FRAME BIT(7) + ++/* different supported pkt types for routing */ ++enum ath11k_routing_pkt_type { ++ ATH11K_PKT_TYPE_ARP_IPV4, ++ ATH11K_PKT_TYPE_NS_IPV6, ++ ATH11K_PKT_TYPE_IGMP_IPV4, ++ ATH11K_PKT_TYPE_MLD_IPV6, ++ ATH11K_PKT_TYPE_DHCP_IPV4, ++ ATH11K_PKT_TYPE_DHCP_IPV6, ++ ATH11K_PKT_TYPE_DNS_TCP_IPV4, ++ ATH11K_PKT_TYPE_DNS_TCP_IPV6, ++ ATH11K_PKT_TYPE_DNS_UDP_IPV4, ++ ATH11K_PKT_TYPE_DNS_UDP_IPV6, ++ ATH11K_PKT_TYPE_ICMP_IPV4, ++ ATH11K_PKT_TYPE_ICMP_IPV6, ++ ATH11K_PKT_TYPE_TCP_IPV4, ++ ATH11K_PKT_TYPE_TCP_IPV6, ++ ATH11K_PKT_TYPE_UDP_IPV4, ++ ATH11K_PKT_TYPE_UDP_IPV6, ++ ATH11K_PKT_TYPE_IPV4, ++ ATH11K_PKT_TYPE_IPV6, ++ ATH11K_PKT_TYPE_EAP, ++ ATH11K_PKT_TYPE_MAX ++}; ++ ++#define ATH11K_RX_PROTOCOL_TAG_START_OFFSET 128 ++#define ATH11K_ROUTE_WBM_RELEASE 5 ++#define ATH11K_ROUTE_EAP_METADATA (ATH11K_RX_PROTOCOL_TAG_START_OFFSET + ATH11K_PKT_TYPE_EAP) ++ + 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 + 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); ++int ath11k_dp_rx_pkt_type_filter(struct ath11k *ar, ++ enum ath11k_routing_pkt_type pkt_type, ++ u32 meta_data); + void ath11k_dp_htt_htc_t2h_msg_handler(struct ath11k_base *ab, + struct sk_buff *skb); + int ath11k_dp_pdev_reo_setup(struct ath11k_base *ab); +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -6365,6 +6365,16 @@ static int ath11k_mac_op_start(struct ie + goto err; + } + ++ /* nss offload requires eapol packets to be routed to wbm release ring */ ++ if (ab->nss.enabled) { ++ ret = ath11k_dp_rx_pkt_type_filter(ar, ATH11K_PKT_TYPE_EAP, ++ ATH11K_ROUTE_EAP_METADATA); ++ if (ret) { ++ ath11k_err(ar->ab, "failed to configure EAP pkt route: %d\n", ret); ++ goto err; ++ } ++ } ++ + __ath11k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask); + + /* TODO: Do we need to enable ANI? */ diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch b/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch new file mode 100644 index 00000000000000..72af89fd7cb4d6 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch @@ -0,0 +1,1271 @@ +From 65c511e3aeb9afb84a3c6c8ac34353af91b880e9 Mon Sep 17 00:00:00 2001 +From: Sriram R +Date: Fri, 10 Jul 2020 12:50:21 +0530 +Subject: [PATCH 3/3] ath11k: add nss support + + Add NSS Offload support for ath11k driver. + +Signed-off-by: Sriram R +--- + drivers/net/wireless/ath/ath11k/ahb.c | 18 ++++++-- + drivers/net/wireless/ath/ath11k/core.c | 24 ++++++++++ + drivers/net/wireless/ath/ath11k/core.h | 14 +++++- + drivers/net/wireless/ath/ath11k/dp.c | 21 ++++++--- + drivers/net/wireless/ath/ath11k/dp.h | 1 + + drivers/net/wireless/ath/ath11k/dp_rx.c | 17 +++++-- + drivers/net/wireless/ath/ath11k/dp_rx.h | 6 +++ + drivers/net/wireless/ath/ath11k/hal.h | 2 + + drivers/net/wireless/ath/ath11k/hal_rx.c | 10 +++- + drivers/net/wireless/ath/ath11k/mac.c | 78 +++++++++++++++++++++++++++++++- + drivers/net/wireless/ath/ath11k/peer.c | 9 +++- + drivers/net/wireless/ath/ath11k/peer.h | 6 ++- + local-symbols | 1 + + 13 files changed, 186 insertions(+), 21 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/ahb.c ++++ b/drivers/net/wireless/ath/ath11k/ahb.c +@@ -525,6 +525,12 @@ static int ath11k_ahb_config_ext_irq(str + int i, j; + int irq; + int ret; ++ bool nss_offload; ++ ++ /* TCL Completion, REO Dest, ERR, Exception and h2rxdma rings are offloaded ++ * to nss when its enabled, hence don't enable these interrupts ++ */ ++ nss_offload = ab->nss.enabled; + + for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { + struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; +@@ -537,20 +543,20 @@ static int ath11k_ahb_config_ext_irq(str + ath11k_ahb_ext_grp_napi_poll); + + for (j = 0; j < ATH11K_EXT_IRQ_NUM_MAX; j++) { +- if (ab->hw_params.ring_mask->tx[i] & BIT(j)) { ++ if (!nss_offload && ab->hw_params.ring_mask->tx[i] & BIT(j)) { + irq_grp->irqs[num_irq++] = + wbm2host_tx_completions_ring1 - j; + } + +- if (ab->hw_params.ring_mask->rx[i] & BIT(j)) { ++ if (!nss_offload && ab->hw_params.ring_mask->rx[i] & BIT(j)) { + irq_grp->irqs[num_irq++] = + reo2host_destination_ring1 - j; + } + +- if (ab->hw_params.ring_mask->rx_err[i] & BIT(j)) ++ if (!nss_offload && ab->hw_params.ring_mask->rx_err[i] & BIT(j)) + irq_grp->irqs[num_irq++] = reo2host_exception; + +- if (ab->hw_params.ring_mask->rx_wbm_rel[i] & BIT(j)) ++ if (!nss_offload && ab->hw_params.ring_mask->rx_wbm_rel[i] & BIT(j)) + irq_grp->irqs[num_irq++] = wbm2host_rx_release; + + if (ab->hw_params.ring_mask->reo_status[i] & BIT(j)) +@@ -563,7 +569,7 @@ static int ath11k_ahb_config_ext_irq(str + ath11k_hw_get_mac_from_pdev_id(hw, j); + } + +- if (ab->hw_params.ring_mask->host2rxdma[i] & BIT(j)) { ++ if (!nss_offload && ab->hw_params.ring_mask->host2rxdma[i] & BIT(j)) { + irq_grp->irqs[num_irq++] = + host2rxdma_host_buf_ring_mac1 - + ath11k_hw_get_mac_from_pdev_id(hw, j); +@@ -904,6 +910,7 @@ static int ath11k_ahb_setup_resources(st + } + + ab->mem = mem; ++ ab->mem_pa = mem_res->start; + ab->mem_len = resource_size(mem_res); + + return 0; +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -17,6 +17,12 @@ + #include "hif.h" + #include "wow.h" + ++unsigned int nss_offload; ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++module_param_named(nss_offload, nss_offload, uint, 0644); ++MODULE_PARM_DESC(nss_offload, "Enable NSS Offload support"); ++#endif ++ + unsigned int ath11k_debug_mask; + EXPORT_SYMBOL(ath11k_debug_mask); + module_param_named(debug_mask, ath11k_debug_mask, uint, 0644); +@@ -1528,10 +1534,16 @@ static int ath11k_core_pdev_create(struc + goto err_pdev_debug; + } + ++ ret = ath11k_nss_setup(ab); ++ if (ret) { ++ ath11k_err(ab, "failed to setup nss driver interface%d", ret); ++ goto err_dp_pdev_free; ++ } ++ + ret = ath11k_mac_register(ab); + if (ret) { + ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret); +- goto err_dp_pdev_free; ++ goto err_nss_tear; + } + + ret = ath11k_thermal_register(ab); +@@ -1553,6 +1565,8 @@ err_thermal_unregister: + ath11k_thermal_unregister(ab); + err_mac_unregister: + ath11k_mac_unregister(ab); ++err_nss_tear: ++ ath11k_nss_teardown(ab); + err_dp_pdev_free: + ath11k_dp_pdev_free(ab); + err_pdev_debug: +@@ -1566,6 +1580,10 @@ static void ath11k_core_pdev_destroy(str + ath11k_spectral_deinit(ab); + ath11k_thermal_unregister(ab); + ath11k_mac_unregister(ab); ++ ++ ath11k_nss_teardown(ab); ++ ab->nss.enabled = false; ++ + ath11k_hif_irq_disable(ab); + ath11k_dp_pdev_free(ab); + ath11k_debugfs_pdev_destroy(ab); +@@ -1772,6 +1790,10 @@ static int ath11k_core_reconfigure_on_cr + int ret; + + mutex_lock(&ab->core_lock); ++ ++ ath11k_nss_teardown(ab); ++ ab->nss.enabled = false; ++ + ath11k_thermal_unregister(ab); + ath11k_hif_irq_disable(ab); + ath11k_dp_pdev_free(ab); +@@ -2095,6 +2117,10 @@ int ath11k_core_pre_init(struct ath11k_b + ath11k_err(ab, "failed to get hw params: %d\n", ret); + return ret; + } ++ ab->nss.enabled = nss_offload; ++ ++ if (nss_offload) ++ ab->nss.stats_enabled = 1; + + return 0; + } +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -29,6 +29,7 @@ + #include "dbring.h" + #include "spectral.h" + #include "wow.h" ++#include "nss.h" + + #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) + +@@ -381,6 +382,9 @@ struct ath11k_vif { + #endif /* CPTCFG_ATH11K_DEBUGFS */ + + struct ath11k_mgmt_frame_stats mgmt_stats; ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ struct arvif_nss nss; ++#endif + }; + + struct ath11k_vif_iter { +@@ -520,6 +524,9 @@ struct ath11k_sta { + #endif + + bool use_4addr_set; ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ struct ath11k_nss_sta_stats *nss_stats; ++#endif + u16 tcl_metadata; + + /* Protected with ar->data_lock */ +@@ -610,6 +617,9 @@ struct ath11k { + struct ieee80211_hw *hw; + struct ieee80211_ops *ops; + struct ath11k_pdev_wmi *wmi; ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ struct ath11k_nss nss; ++#endif + 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 { + struct ath11k_htc htc; + + struct ath11k_dp dp; ++ struct ath11k_soc_nss nss; + + void __iomem *mem; + void __iomem *mem_ce; ++ dma_addr_t mem_pa; + unsigned long mem_len; + + struct { +--- a/drivers/net/wireless/ath/ath11k/dp.c ++++ b/drivers/net/wireless/ath/ath11k/dp.c +@@ -47,12 +47,17 @@ int ath11k_dp_peer_setup(struct ath11k * + struct ath11k_peer *peer; + u32 reo_dest; + int ret = 0, tid; ++ bool rx_hash_enable = DP_RX_HASH_ENABLE; ++ ++ /* RX Hash based steering is disabled for NSS Offload */ ++ if (ar->ab->nss.enabled) ++ rx_hash_enable = DP_RX_HASH_DISABLE; + + /* NOTE: reo_dest ring id starts from 1 unlike mac_id which starts from 0 */ + reo_dest = ar->dp.mac_id + 1; + ret = ath11k_wmi_set_peer_param(ar, addr, vdev_id, + WMI_PEER_SET_DEFAULT_ROUTING, +- DP_RX_HASH_ENABLE | (reo_dest << 1)); ++ rx_hash_enable | (reo_dest << 1)); + + if (ret) { + ath11k_warn(ab, "failed to set default routing %d peer :%pM vdev_id :%d\n", +@@ -132,6 +137,18 @@ static int ath11k_dp_srng_calculate_msi_ + { + const u8 *grp_mask; + ++ if (ab->nss.enabled) { ++ switch (type) { ++ case HAL_REO_STATUS: ++ case HAL_RXDMA_MONITOR_STATUS: ++ case HAL_RXDMA_MONITOR_DST: ++ case HAL_RXDMA_MONITOR_BUF: ++ break; ++ default: ++ return -ENOENT; ++ } ++ } ++ + switch (type) { + case HAL_WBM2SW_RELEASE: + if (ring_num == DP_RX_RELEASE_RING_NUM) { +@@ -778,14 +795,16 @@ int ath11k_dp_service_srng(struct ath11k + int work_done = 0; + int i, j; + int tot_work_done = 0; ++ bool nss_offload; + +- for (i = 0; i < ab->hw_params.max_tx_ring; i++) { +- if (BIT(ab->hw_params.hal_params->tcl2wbm_rbm_map[i].wbm_ring_num) & +- ab->hw_params.ring_mask->tx[grp_id]) +- ath11k_dp_tx_completion_handler(ab, i); ++ nss_offload = ab->nss.enabled; ++ ++ if (!nss_offload && ab->hw_params.ring_mask->tx[grp_id]) { ++ i = __fls(ab->hw_params.ring_mask->tx[grp_id]); ++ ath11k_dp_tx_completion_handler(ab, i); + } + +- if (ab->hw_params.ring_mask->rx_err[grp_id]) { ++ if (!nss_offload && ab->hw_params.ring_mask->rx_err[grp_id]) { + work_done = ath11k_dp_process_rx_err(ab, napi, budget); + budget -= work_done; + tot_work_done += work_done; +@@ -793,7 +812,7 @@ int ath11k_dp_service_srng(struct ath11k + goto done; + } + +- if (ab->hw_params.ring_mask->rx_wbm_rel[grp_id]) { ++ if (!nss_offload && ab->hw_params.ring_mask->rx_wbm_rel[grp_id]) { + work_done = ath11k_dp_rx_process_wbm_err(ab, + napi, + budget); +@@ -804,7 +823,7 @@ int ath11k_dp_service_srng(struct ath11k + goto done; + } + +- if (ab->hw_params.ring_mask->rx[grp_id]) { ++ if (!nss_offload && ab->hw_params.ring_mask->rx[grp_id]) { + i = fls(ab->hw_params.ring_mask->rx[grp_id]) - 1; + work_done = ath11k_dp_process_rx(ab, i, napi, + budget); +@@ -822,9 +841,10 @@ int ath11k_dp_service_srng(struct ath11k + if (ab->hw_params.ring_mask->rx_mon_status[grp_id] & + BIT(id)) { + work_done = +- ath11k_dp_rx_process_mon_rings(ab, +- id, +- napi, budget); ++ ath11k_dp_rx_process_mon_rings(ab, ++ id, ++ napi, ++ budget); + budget -= work_done; + tot_work_done += work_done; + +@@ -838,7 +858,7 @@ int ath11k_dp_service_srng(struct ath11k + if (ab->hw_params.ring_mask->reo_status[grp_id]) + ath11k_dp_process_reo_status(ab); + +- for (i = 0; i < ab->num_radios; i++) { ++ for (i = 0; !nss_offload && i < ab->num_radios; i++) { + for (j = 0; j < ab->hw_params.num_rxmda_per_pdev; j++) { + int id = i * ab->hw_params.num_rxmda_per_pdev + j; + +--- a/drivers/net/wireless/ath/ath11k/dp.h ++++ b/drivers/net/wireless/ath/ath11k/dp.h +@@ -194,6 +194,7 @@ struct ath11k_pdev_dp { + #define DP_AVG_MSDUS_PER_MPDU 4 + + #define DP_RX_HASH_ENABLE 1 /* Enable hash based Rx steering */ ++#define DP_RX_HASH_DISABLE 0 /* Disable hash based Rx steering */ + + #define DP_BA_WIN_SZ_MAX 256 + +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -17,6 +17,7 @@ + #include "hal_rx.h" + #include "dp_tx.h" + #include "peer.h" ++#include "nss.h" + + #define ATH11K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ) + +@@ -213,8 +214,8 @@ static inline u8 ath11k_dp_rx_h_mpdu_sta + return ab->hw_params.hw_ops->rx_desc_get_mpdu_tid(desc); + } + +-static inline u16 ath11k_dp_rx_h_mpdu_start_peer_id(struct ath11k_base *ab, +- struct hal_rx_desc *desc) ++u16 ath11k_dp_rx_h_mpdu_start_peer_id(struct ath11k_base *ab, ++ struct hal_rx_desc *desc) + { + return ab->hw_params.hw_ops->rx_desc_get_mpdu_peer_id(desc); + } +@@ -225,8 +226,8 @@ static inline u8 ath11k_dp_rx_h_msdu_end + return ab->hw_params.hw_ops->rx_desc_get_l3_pad_bytes(desc); + } + +-static inline bool ath11k_dp_rx_h_msdu_end_first_msdu(struct ath11k_base *ab, +- struct hal_rx_desc *desc) ++bool ath11k_dp_rx_h_msdu_end_first_msdu(struct ath11k_base *ab, ++ struct hal_rx_desc *desc) + { + return ab->hw_params.hw_ops->rx_desc_get_first_msdu(desc); + } +@@ -283,7 +284,7 @@ static inline void ath11k_dp_rxdesc_set_ + ab->hw_params.hw_ops->rx_desc_set_msdu_len(desc, len); + } + +-static bool ath11k_dp_rx_h_attn_is_mcbc(struct ath11k_base *ab, ++bool ath11k_dp_rx_h_attn_is_mcbc(struct ath11k_base *ab, + struct hal_rx_desc *desc) + { + struct rx_attention *attn = ath11k_dp_rx_get_attention(ab, desc); +@@ -498,7 +499,9 @@ static int ath11k_dp_rxdma_pdev_buf_setu + struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; + int i; + +- ath11k_dp_rxdma_ring_buf_setup(ar, rx_ring, HAL_RXDMA_BUF); ++ /* RXDMA BUF ring is offloaded to NSS */ ++ if (!ar->ab->nss.enabled) ++ ath11k_dp_rxdma_ring_buf_setup(ar, rx_ring, HAL_RXDMA_BUF); + + 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( + CHECKSUM_NONE : CHECKSUM_UNNECESSARY; + } + +-static int ath11k_dp_rx_crypto_mic_len(struct ath11k *ar, ++int ath11k_dp_rx_crypto_mic_len(struct ath11k *ar, + enum hal_encrypt_type enctype) + { + switch (enctype) { +@@ -1920,7 +1923,7 @@ static int ath11k_dp_rx_crypto_mic_len(s + return 0; + } + +-static int ath11k_dp_rx_crypto_param_len(struct ath11k *ar, ++int ath11k_dp_rx_crypto_param_len(struct ath11k *ar, + enum hal_encrypt_type enctype) + { + switch (enctype) { +@@ -1948,7 +1951,7 @@ static int ath11k_dp_rx_crypto_param_len + return 0; + } + +-static int ath11k_dp_rx_crypto_icv_len(struct ath11k *ar, ++int ath11k_dp_rx_crypto_icv_len(struct ath11k *ar, + enum hal_encrypt_type enctype) + { + switch (enctype) { +@@ -5239,7 +5242,7 @@ int ath11k_dp_rx_process_mon_status(stru + struct sk_buff *skb; + struct sk_buff_head skb_list; + struct ath11k_peer *peer; +- struct ath11k_sta *arsta; ++ struct ath11k_sta *arsta = NULL; + int num_buffs_reaped = 0; + u32 rx_buf_sz; + u16 log_type; +--- 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 + int ath11k_dp_rx_pktlog_start(struct ath11k_base *ab); + int ath11k_dp_rx_pktlog_stop(struct ath11k_base *ab, bool stop_timer); + ++int ath11k_dp_rx_crypto_mic_len(struct ath11k *ar, ++ enum hal_encrypt_type enctype); ++int ath11k_dp_rx_crypto_param_len(struct ath11k *ar, ++ enum hal_encrypt_type enctype); ++int ath11k_dp_rx_crypto_icv_len(struct ath11k *ar, ++ enum hal_encrypt_type enctype); ++bool ath11k_dp_rx_h_msdu_end_first_msdu(struct ath11k_base *ab, ++ struct hal_rx_desc *desc); ++bool ath11k_dp_rx_h_attn_is_mcbc(struct ath11k_base *ab, ++ struct hal_rx_desc *desc); ++u16 ath11k_dp_rx_h_mpdu_start_peer_id(struct ath11k_base *ab, ++ struct hal_rx_desc *desc); + #endif /* ATH11K_DP_RX_H */ +--- a/drivers/net/wireless/ath/ath11k/hal.h ++++ b/drivers/net/wireless/ath/ath11k/hal.h +@@ -424,6 +424,8 @@ enum hal_srng_ring_id { + #define HAL_SRNG_RING_ID_MAX (HAL_SRNG_RING_ID_UMAC_ID_END + \ + HAL_SRNG_NUM_LMAC_RINGS) + ++#define HAL_SRNG_REO_ALTERNATE_SELECT 0x7 ++ + enum hal_ring_type { + HAL_REO_DST, + HAL_REO_EXCEPTION, +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -24,6 +24,7 @@ + #include "debugfs_sta.h" + #include "hif.h" + #include "wow.h" ++#include "nss.h" + + #define CHAN2G(_channel, _freq, _flags) { \ + .band = NL80211_BAND_2GHZ, \ +@@ -1603,6 +1604,11 @@ static void ath11k_control_beaconing(str + lockdep_assert_held(&arvif->ar->conf_mutex); + + if (!info->enable_beacon) { ++ ++ ret = ath11k_nss_vdev_down(arvif); ++ if(ret) ++ ath11k_warn(ar->ab, "failure in nss vdev down %d\r\n",ret); ++ + ret = ath11k_wmi_vdev_down(ar, arvif->vdev_id); + if (ret) + ath11k_warn(ar->ab, "failed to down vdev_id %i: %d\n", +@@ -1642,6 +1648,12 @@ static void ath11k_control_beaconing(str + + arvif->is_up = true; + ++ ret = ath11k_nss_vdev_up(arvif); ++ if(ret) { ++ ath11k_warn(ar->ab, "failure in nss vdev up %d\r\n",ret); ++ return; ++ } ++ + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "vdev %d up\n", arvif->vdev_id); + } + +@@ -3075,6 +3087,12 @@ static void ath11k_bss_assoc(struct ieee + "vdev %d up (associated) bssid %pM aid %d\n", + arvif->vdev_id, bss_conf->bssid, vif->cfg.aid); + ++ ret = ath11k_nss_vdev_up(arvif); ++ if(ret) { ++ ath11k_warn(ar->ab, "failure in nss vdev up %d\r\n",ret); ++ return; ++ } ++ + spin_lock_bh(&ar->ab->base_lock); + + peer = ath11k_peer_find(ar->ab, arvif->vdev_id, arvif->bssid); +@@ -3117,6 +3135,10 @@ static void ath11k_bss_disassoc(struct i + + lockdep_assert_held(&ar->conf_mutex); + ++ ret = ath11k_nss_vdev_down(arvif); ++ if(ret) ++ ath11k_warn(ar->ab, "failure in nss vdev down %d\r\n",ret); ++ + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "vdev %i disassoc bssid %pM\n", + arvif->vdev_id, arvif->bssid); + +@@ -3397,6 +3419,28 @@ static int ath11k_mac_config_obss_pd(str + return 0; + } + ++static void ath11k_mac_op_nss_bss_info_changed(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ u32 changed) ++{ ++ struct ath11k *ar = hw->priv; ++ struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); ++ int ret = 0; ++ ++ mutex_lock(&ar->conf_mutex); ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "Setting ap_isolate %d to NSS\n", ++ arvif->vif->bss_conf.nss_ap_isolate); ++ if (changed & BSS_CHANGED_NSS_AP_ISOLATE) { ++ ret = ath11k_nss_vdev_set_cmd(arvif, ATH11K_NSS_WIFI_VDEV_CFG_AP_BRIDGE_CMD, ++ !arvif->vif->bss_conf.nss_ap_isolate); ++ if(ret) ++ ath11k_warn(ar->ab, "failed to set ap_isolate in nss %d\n", ret); ++ } ++ ++ mutex_unlock(&ar->conf_mutex); ++} ++ + static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info, +@@ -4293,6 +4337,26 @@ static int ath11k_mac_op_set_key(struct + + spin_lock_bh(&ab->base_lock); + peer = ath11k_peer_find(ab, arvif->vdev_id, peer_addr); ++ ++ /* TODO: Check if vdev specific security cfg is mandatory */ ++ ret = ath11k_nss_vdev_set_cmd(arvif, ATH11K_NSS_WIFI_VDEV_SECURITY_TYPE_CMD, key->cipher); ++ if (ret) { ++ ath11k_warn(ab, "failure to set vdev security type in nss"); ++ goto unlock; ++ } ++ ++ ret = ath11k_nss_set_peer_sec_type(ar, peer, key); ++ if (ret) { ++ ath11k_warn(ab, "failure to set peer security type in nss"); ++ goto unlock; ++ } ++ ++ ret = ath11k_nss_set_peer_authorize(ar, peer->peer_id); ++ if (ret) { ++ ath11k_warn(ab, "failure to authorize peer in nss"); ++ goto unlock; ++ } ++ + if (peer && cmd == SET_KEY) { + peer->keys[key->keyidx] = key; + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { +@@ -4331,9 +4395,8 @@ static int ath11k_mac_op_set_key(struct + break; + } + } +- ++unlock: + spin_unlock_bh(&ab->base_lock); +- + exit: + mutex_unlock(&ar->conf_mutex); + return ret; +@@ -6214,10 +6277,14 @@ static void ath11k_mac_op_tx(struct ieee + if (control->sta) + arsta = ath11k_sta_to_arsta(control->sta); + +- ret = ath11k_dp_tx(ar, arvif, arsta, skb); ++ if (ar->ab->nss.enabled) ++ ret = ath11k_nss_tx(arvif,skb); ++ else ++ ret = ath11k_dp_tx(ar, arvif, arsta, skb); + if (unlikely(ret)) { + ath11k_warn(ar->ab, "failed to transmit frame %d\n", ret); + ieee80211_free_txskb(ar->hw, skb); ++ return; + } + } + +@@ -6239,6 +6306,8 @@ static int ath11k_mac_config_mon_status_ + + if (enable) { + tlv_filter = ath11k_mac_mon_status_filter_default; ++ ath11k_nss_ext_rx_stats(ar->ab, &tlv_filter); ++ + if (ath11k_debugfs_rx_filter(ar)) + tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar); + } +@@ -6537,7 +6606,7 @@ static int ath11k_mac_setup_vdev_create_ + return 0; + } + +-static void ath11k_mac_op_update_vif_offload(struct ieee80211_hw *hw, ++static int ath11k_mac_op_update_vif_offload(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) + { + struct ath11k *ar = hw->priv; +@@ -6583,6 +6652,8 @@ static void ath11k_mac_op_update_vif_off + arvif->vdev_id, ret); + vif->offload_flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED; + } ++ ++ return ret; + } + + static bool ath11k_mac_vif_ap_active_any(struct ath11k_base *ab) +@@ -6713,6 +6784,8 @@ static int ath11k_mac_vdev_delete(struct + + reinit_completion(&ar->vdev_delete_done); + ++ ath11k_nss_vdev_delete(arvif); ++ + ret = ath11k_wmi_vdev_delete(ar, arvif->vdev_id); + if (ret) { + ath11k_warn(ar->ab, "failed to delete WMI vdev %d: %d\n", +@@ -6853,7 +6926,34 @@ static int ath11k_mac_op_add_interface(s + list_add(&arvif->list, &ar->arvifs); + spin_unlock_bh(&ar->data_lock); + +- ath11k_mac_op_update_vif_offload(hw, vif); ++ ret = ath11k_nss_vdev_create(arvif); ++ if(ret) { ++ ath11k_warn(ab, "failed to create nss vdev %d\n", ret); ++ goto err_vdev_del; ++ } ++ ++ if (ath11k_mac_op_update_vif_offload(hw, vif)) ++ goto err_vdev_del; ++ ++ if (vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) ++ param_value = ATH11K_HW_TXRX_ETHERNET; ++ else if (test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) ++ param_value = ATH11K_HW_TXRX_RAW; ++ else ++ param_value = ATH11K_HW_TXRX_NATIVE_WIFI; ++ ++ ret = ath11k_nss_vdev_set_cmd(arvif, ATH11K_NSS_WIFI_VDEV_ENCAP_TYPE_CMD, param_value); ++ ++ if(ret) { ++ ath11k_warn(ab, "failed to set encap type in nss %d\n", ret); ++ goto err_vdev_del; ++ } ++ ++ ret = ath11k_nss_vdev_set_cmd(arvif, ATH11K_NSS_WIFI_VDEV_DECAP_TYPE_CMD, param_value); ++ if(ret) { ++ ath11k_warn(ab, "failed to set decap type in nss %d\n", ret); ++ goto err_vdev_del; ++ } + + nss = get_num_chains(ar->cfg_tx_chainmask) ? : 1; + ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, +@@ -6977,6 +7077,7 @@ err_peer_del: + } + + err_vdev_del: ++ ath11k_nss_vdev_delete(arvif); + ath11k_mac_vdev_delete(ar, arvif); + spin_lock_bh(&ar->data_lock); + list_del(&arvif->list); +@@ -7487,6 +7588,10 @@ ath11k_mac_update_vif_chan(struct ath11k + arvif->vdev_id, ret); + continue; + } ++ ++ ret = ath11k_nss_vdev_up(arvif); ++ if(ret) ++ ath11k_warn(ar->ab, "failure in nss vdev up %d\r\n",ret); + } + + /* Restart the internal monitor vdev on new channel */ +@@ -8769,6 +8874,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); ++ ++ ath11k_nss_update_sta_stats(sinfo, sta, arsta); + } + + #if IS_ENABLED(CONFIG_IPV6) +@@ -9188,6 +9295,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, ++ .nss_bss_info_changed = ath11k_mac_op_nss_bss_info_changed, + .configure_filter = ath11k_mac_op_configure_filter, + .hw_scan = ath11k_mac_op_hw_scan, + .cancel_hw_scan = ath11k_mac_op_cancel_hw_scan, +@@ -9573,7 +9681,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); +- ieee80211_hw_set(ar->hw, USES_RSS); ++ if(!ab->nss.enabled) ++ ieee80211_hw_set(ar->hw, USES_RSS); + } + + ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; +@@ -9688,6 +9797,9 @@ static int __ath11k_mac_register(struct + ab->hw_params.bios_sar_capa) + ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa; + ++ if (ab->nss.enabled) ++ ieee80211_hw_set(ar->hw, SUPPORTS_NSS_OFFLOAD); ++ + ret = ieee80211_register_hw(ar->hw); + if (ret) { + ath11k_err(ar->ab, "ieee80211 registration failed: %d\n", ret); +--- a/drivers/net/wireless/ath/ath11k/peer.c ++++ b/drivers/net/wireless/ath/ath11k/peer.c +@@ -7,6 +7,7 @@ + #include "core.h" + #include "peer.h" + #include "debug.h" ++#include "nss.h" + + 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 + ether_addr_copy(peer->addr, mac_addr); + list_add(&peer->list, &ab->peers); + wake_up(&ab->peer_mapping_wq); ++ if (ab->nss.enabled) ++ ath11k_nss_peer_create(ab, peer); + } + + ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "peer map vdev %d peer %pM id %d\n", +@@ -332,6 +335,8 @@ static int __ath11k_peer_delete(struct a + + reinit_completion(&ar->peer_delete_done); + ++ ath11k_nss_peer_delete(ar->ab, addr); ++ + ret = ath11k_wmi_send_peer_delete_cmd(ar, addr, vdev_id); + if (ret) { + ath11k_warn(ab, +--- a/drivers/net/wireless/ath/ath11k/peer.h ++++ b/drivers/net/wireless/ath/ath11k/peer.h +@@ -17,6 +17,7 @@ struct ath11k_peer { + u16 ast_hash; + u8 pdev_idx; + u16 hw_peer_id; ++ struct ath11k_nss_peer nss; + + /* protected by ab->data_lock */ + struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; +--- a/drivers/net/wireless/ath/ath11k/pci.c ++++ b/drivers/net/wireless/ath/ath11k/pci.c +@@ -570,6 +570,7 @@ static int ath11k_pci_claim(struct ath11 + } + + ab->mem_ce = ab->mem; ++ ab->mem_pa = pci_resource_start(pdev, ATH11K_PCI_BAR_NUM); + + ath11k_dbg(ab, ATH11K_DBG_BOOT, "pci_mem 0x%p\n", ab->mem); + return 0; +--- a/drivers/net/wireless/ath/ath11k/debugfs.c ++++ b/drivers/net/wireless/ath/ath11k/debugfs.c +@@ -10,11 +10,10 @@ + #include "core.h" + #include "debug.h" + #include "wmi.h" +-#include "hal_rx.h" + #include "dp_tx.h" + #include "debugfs_htt_stats.h" +-#include "peer.h" + #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 + HTT_RX_FP_DATA_FILTER_FLASG3; + } else { + tlv_filter = ath11k_mac_mon_status_filter_default; ++ ath11k_nss_ext_rx_stats(ar->ab, &tlv_filter); + } + + ar->debug.rx_filter = tlv_filter.rx_filter; +@@ -1592,10 +1592,13 @@ static ssize_t ath11k_dump_mgmt_stats(st + size_t count, loff_t *ppos) + { + struct ath11k *ar = file->private_data; ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M ++ struct ath11k_base *ab = ar->ab; ++#endif + 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", +@@ -1669,72 +1672,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 +1914,144 @@ static const struct file_operations ath1 + .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; ++ int ret; ++ ++ if (!ab->nss.enabled) { ++ ath11k_warn(ab, "nss offload not enabled\n"); ++ return -EINVAL; ++ } ++ ++ if (kstrtouint_from_user(ubuf, count, 0, &nss_stats)) ++ return -EINVAL; ++ ++ mutex_lock(&ar->conf_mutex); ++ ++ if (ar->state != ATH11K_STATE_ON) { ++ ret = -ENETDOWN; ++ goto out; ++ } ++ ++ if (nss_stats == ab->nss.stats_enabled) { ++ ret = count; ++ goto out; ++ } ++ ++ if (nss_stats > 0) { ++ ab->nss.stats_enabled = 1; ++ ath11k_nss_peer_stats_enable(ar); ++ } else { ++ ab->nss.stats_enabled = 0; ++ ath11k_nss_peer_stats_disable(ar); ++ } ++ ++ ret = count; ++out: ++ mutex_unlock(&ar->conf_mutex); ++ return ret; ++} ++ ++static ssize_t ath11k_read_nss_stats(struct file *file, ++ char __user *ubuf, ++ size_t count, loff_t *ppos) ++ ++{ ++ char buf[32] = {0}; ++ struct ath11k *ar = file->private_data; ++ struct ath11k_base *ab = ar->ab; ++ int len = 0; ++ ++ mutex_lock(&ar->conf_mutex); ++ len = scnprintf(buf, sizeof(buf) - len, "%08x\n", ++ ab->nss.stats_enabled); ++ mutex_unlock(&ar->conf_mutex); ++ ++ return simple_read_from_buffer(ubuf, count, ppos, buf, len); ++} ++ ++static const struct file_operations fops_nss_stats = { ++ .read = ath11k_read_nss_stats, ++ .write = ath11k_write_nss_stats, ++ .open = simple_open, ++ .owner = THIS_MODULE, ++ .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); ++ } ++ ++ if (ab->nss.enabled) ++ debugfs_create_file("nss_peer_stats_config", 0644, ++ 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; +--- a/drivers/net/wireless/ath/ath11k/dp_tx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_tx.c +@@ -12,7 +12,7 @@ + #include "peer.h" + #include "mac.h" + +-static enum hal_tcl_encap_type ++enum hal_tcl_encap_type + ath11k_dp_tx_get_encap_type(struct ath11k_vif *arvif, struct sk_buff *skb) + { + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); +--- a/drivers/net/wireless/ath/ath11k/dp_tx.h ++++ b/drivers/net/wireless/ath/ath11k/dp_tx.h +@@ -38,6 +38,8 @@ int ath11k_dp_tx_htt_rx_filter_setup(str + int mac_id, enum hal_ring_type ring_type, + int rx_buf_size, + struct htt_rx_ring_tlv_filter *tlv_filter); ++enum hal_tcl_encap_type ++ath11k_dp_tx_get_encap_type(struct ath11k_vif *arvif, struct sk_buff *skb); + + int ath11k_dp_tx_htt_rx_full_mon_setup(struct ath11k_base *ab, int mac_id, + bool config); +--- a/drivers/net/wireless/ath/ath11k/nss.c ++++ b/drivers/net/wireless/ath/ath11k/nss.c +@@ -8,6 +8,8 @@ + #include "nss.h" + #include "core.h" + #include "peer.h" ++#include "dp_rx.h" ++#include "dp_tx.h" + #include "hif.h" + #include "wmi.h" + #include "../../../../../net/mac80211/sta_info.h" +@@ -465,7 +467,7 @@ deliver_amsdu: + + /* create list containing all the subframes */ + ieee80211_amsdu_to_8023s(skb, &subframe_list, NULL, +- vif->type, 0, NULL, NULL); ++ vif->type, 0, NULL, NULL, false); + + /* This shouldn't happen, indicating error during defragmentation */ + if (skb_queue_empty(&subframe_list)) +@@ -657,12 +659,14 @@ drop: + return -EINVAL; + } + +-int ath11k_nss_vdev_set_cmd(struct ath11k_vif *arvif, int cmd, int val) ++int ath11k_nss_vdev_set_cmd(struct ath11k_vif *arvif, enum ath11k_nss_vdev_cmd nss_cmd, ++ int val) + { + struct nss_wifi_vdev_msg *vdev_msg = NULL; + struct nss_wifi_vdev_cmd_msg *vdev_cmd; + struct ath11k *ar = arvif->ar; + nss_tx_status_t status; ++ int cmd; + + if (!ar->ab->nss.enabled) + return 0; +@@ -675,6 +679,22 @@ int ath11k_nss_vdev_set_cmd(struct ath11 + if (!vdev_msg) + return -ENOMEM; + ++ switch(nss_cmd) { ++ case ATH11K_NSS_WIFI_VDEV_CFG_AP_BRIDGE_CMD: ++ cmd = NSS_WIFI_VDEV_CFG_AP_BRIDGE_CMD; ++ break; ++ case ATH11K_NSS_WIFI_VDEV_SECURITY_TYPE_CMD: ++ cmd = NSS_WIFI_VDEV_SECURITY_TYPE_CMD; ++ break; ++ case ATH11K_NSS_WIFI_VDEV_ENCAP_TYPE_CMD: ++ cmd = NSS_WIFI_VDEV_ENCAP_TYPE_CMD; ++ break; ++ case ATH11K_NSS_WIFI_VDEV_DECAP_TYPE_CMD: ++ cmd = NSS_WIFI_VDEV_DECAP_TYPE_CMD; ++ break; ++ default: ++ return -EINVAL; ++ } + /* TODO: Convert to function for conversion in case of many + * such commands + */ +@@ -1136,7 +1156,6 @@ void ath11k_nss_update_sta_stats(struct + { + struct sta_info *stainfo; + struct ath11k_peer *peer; +- int tid_idx; + struct ath11k *ar = arsta->arvif->ar; + struct ath11k_base *ab = ar->ab; + +@@ -1230,6 +1249,9 @@ void ath11k_nss_update_sta_rxrate(struct + if (!ab->nss.enabled) + return; + ++ if (!ieee80211_is_data(__cpu_to_le16(ppdu_info->frame_control))) ++ return; ++ + if (!peer->nss.nss_stats) + return; + +@@ -1289,7 +1311,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; +- peer->nss.nss_stats->rxrate.he_gi = ath11k_he_gi_to_nl80211_he_gi(ppdu_info->gi); ++ peer->nss.nss_stats->rxrate.he_gi = ath11k_mac_he_gi_to_nl80211_he_gi(ppdu_info->gi); + peer->nss.nss_stats->rxrate.he_ru_alloc = ppdu_info->ru_alloc; + break; + } +--- a/drivers/net/wireless/ath/ath11k/nss.h ++++ b/drivers/net/wireless/ath/ath11k/nss.h +@@ -101,6 +101,13 @@ do { \ + u64_stats_update_end(&tstats->syncp); \ + } while (0) + ++enum ath11k_nss_vdev_cmd { ++ ATH11K_NSS_WIFI_VDEV_CFG_AP_BRIDGE_CMD, ++ ATH11K_NSS_WIFI_VDEV_SECURITY_TYPE_CMD, ++ ATH11K_NSS_WIFI_VDEV_ENCAP_TYPE_CMD, ++ ATH11K_NSS_WIFI_VDEV_DECAP_TYPE_CMD, ++}; ++ + enum ath11k_nss_opmode { + ATH11K_NSS_OPMODE_UNKNOWN, + ATH11K_NSS_OPMODE_AP, +@@ -190,7 +197,8 @@ struct ath11k_soc_nss { + + #ifdef CPTCFG_ATH11K_NSS_SUPPORT + int ath11k_nss_tx(struct ath11k_vif *arvif, struct sk_buff *skb); +-int ath11k_nss_vdev_set_cmd(struct ath11k_vif *arvif, int cmd, int val); ++int ath11k_nss_vdev_set_cmd(struct ath11k_vif *arvif, enum ath11k_nss_vdev_cmd cmd, ++ int val); + int ath11k_nss_vdev_create(struct ath11k_vif *arvif); + void ath11k_nss_vdev_delete(struct ath11k_vif *arvif); + int ath11k_nss_vdev_up(struct ath11k_vif *arvif); +@@ -217,7 +225,8 @@ static inline int ath11k_nss_tx(struct a + return 0; + } + +-static inline int ath11k_nss_vdev_set_cmd(struct ath11k_vif *arvif, int cmd, int val) ++static inline int ath11k_nss_vdev_set_cmd(struct ath11k_vif *arvif, enum ath11k_nss_vdev_cmd cmd, ++ int val) + { + return 0; + } +--- a/drivers/net/wireless/ath/ath11k/hw.c ++++ b/drivers/net/wireless/ath/ath11k/hw.c +@@ -104,8 +104,10 @@ static void ath11k_init_wmi_config_qca63 + + static void ath11k_hw_ipq8074_reo_setup(struct ath11k_base *ab) + { ++ u8 frag_dest_ring = HAL_SRNG_RING_ID_REO2SW1; + u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; + u32 val; ++ + /* Each hash entry uses three bits to map to a particular ring. */ + u32 ring_hash_map = HAL_HASH_ROUTING_RING_SW1 << 0 | + HAL_HASH_ROUTING_RING_SW2 << 3 | +@@ -116,11 +118,14 @@ static void ath11k_hw_ipq8074_reo_setup( + HAL_HASH_ROUTING_RING_SW3 << 18 | + HAL_HASH_ROUTING_RING_SW4 << 21; + ++ if (ab->nss.enabled) ++ frag_dest_ring = HAL_SRNG_REO_ALTERNATE_SELECT; ++ + val = ath11k_hif_read32(ab, reo_base + HAL_REO1_GEN_ENABLE); + + val &= ~HAL_REO1_GEN_ENABLE_FRAG_DST_RING; + val |= FIELD_PREP(HAL_REO1_GEN_ENABLE_FRAG_DST_RING, +- HAL_SRNG_RING_ID_REO2SW1) | ++ frag_dest_ring) | + FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_LIST_ENABLE, 1) | + FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_FLUSH_ENABLE, 1); + ath11k_hif_write32(ab, reo_base + HAL_REO1_GEN_ENABLE, val); +@@ -134,6 +139,10 @@ static void ath11k_hw_ipq8074_reo_setup( + ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_3(ab), + HAL_DEFAULT_REO_TIMEOUT_USEC); + ++ /* REO Dest ring setup is not required in NSS offload case */ ++ 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)); +@@ -758,8 +767,10 @@ static u8 *ath11k_hw_wcn6855_rx_desc_mpd + + static void ath11k_hw_wcn6855_reo_setup(struct ath11k_base *ab) + { ++ u8 frag_dest_ring = HAL_SRNG_RING_ID_REO2SW1; + u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; + u32 val; ++ + /* Each hash entry uses four bits to map to a particular ring. */ + u32 ring_hash_map = HAL_HASH_ROUTING_RING_SW1 << 0 | + HAL_HASH_ROUTING_RING_SW2 << 4 | +@@ -770,6 +781,9 @@ static void ath11k_hw_wcn6855_reo_setup( + HAL_HASH_ROUTING_RING_SW3 << 24 | + HAL_HASH_ROUTING_RING_SW4 << 28; + ++ if (ab->nss.enabled) ++ frag_dest_ring = HAL_SRNG_REO_ALTERNATE_SELECT; ++ + val = ath11k_hif_read32(ab, reo_base + HAL_REO1_GEN_ENABLE); + val |= FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_LIST_ENABLE, 1) | + FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_FLUSH_ENABLE, 1); +@@ -777,7 +791,7 @@ static void ath11k_hw_wcn6855_reo_setup( + + val = ath11k_hif_read32(ab, reo_base + HAL_REO1_MISC_CTL(ab)); + val &= ~HAL_REO1_MISC_CTL_FRAGMENT_DST_RING; +- val |= FIELD_PREP(HAL_REO1_MISC_CTL_FRAGMENT_DST_RING, HAL_SRNG_RING_ID_REO2SW1); ++ val |= FIELD_PREP(HAL_REO1_MISC_CTL_FRAGMENT_DST_RING, frag_dest_ring); + ath11k_hif_write32(ab, reo_base + HAL_REO1_MISC_CTL(ab), val); + + ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_0(ab), +@@ -789,6 +803,10 @@ static void ath11k_hw_wcn6855_reo_setup( + ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_3(ab), + HAL_DEFAULT_REO_TIMEOUT_USEC); + ++ /* REO Dest ring setup is not required in NSS offload case */ ++ 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, +--- a/drivers/net/wireless/ath/ath11k/pcic.c ++++ b/drivers/net/wireless/ath/ath11k/pcic.c +@@ -571,6 +571,12 @@ static int ath11k_pcic_ext_irq_config(st + netif_napi_add(&irq_grp->napi_ndev, &irq_grp->napi, + ath11k_pcic_ext_grp_napi_poll); + ++ /* tcl, reo, rx_err, wbm release, rxdma rings are offloaded to nss. */ ++ if (ab->nss.enabled && ++ !(ab->hw_params.ring_mask->reo_status[i] || ++ ab->hw_params.ring_mask->rx_mon_status[i])) ++ continue; ++ + if (ab->hw_params.ring_mask->tx[i] || + ab->hw_params.ring_mask->rx[i] || + ab->hw_params.ring_mask->rx_err[i] || +--- a/local-symbols ++++ b/local-symbols +@@ -170,6 +170,7 @@ WCN36XX_DEBUGFS= + ATH11K= + ATH11K_AHB= + ATH11K_PCI= ++ATH11K_NSS_SUPPORT= + ATH11K_DEBUG= + ATH11K_DEBUGFS= + ATH11K_TRACING= diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-004-ath10k-add-nss-driver-interface.patch b/package/kernel/mac80211/patches/ath11k_nss/199-004-ath10k-add-nss-driver-interface.patch new file mode 100644 index 00000000000000..bf116d15b2afb4 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/199-004-ath10k-add-nss-driver-interface.patch @@ -0,0 +1,20 @@ +--- 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,8 @@ 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/207-ath11k-Enable-512MB-profile-in-ath11k.patch b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-512MB-profile-in-ath11k.patch new file mode 100644 index 00000000000000..44ab73377b1232 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-512MB-profile-in-ath11k.patch @@ -0,0 +1,1009 @@ +From 1b402e444ff99efe84d09a084b96c39826783a8e Mon Sep 17 00:00:00 2001 +From: Ramya Gnanasekar +Date: Thu, 10 Sep 2020 13:33:55 +0530 +Subject: [PATCH] ath11k: Enable 512MB profile in ath11k + +Below changes are made to enable 512MB mem mode in ath11k + * Makefile changes to implement compilation flag when + 512MB mem profile is configured. + * Enabling 512MB mem profile by default from Makefile + for IPQ5018. This can be removed later once + 512MB profile config is supported. + * Update target_mem_mode, number of stations, peer and vap + during compile time + +Signed-off-by: Ramya Gnanasekar +--- + drivers/net/wireless/ath/ath11k/Kconfig | 7 +++++++ + drivers/net/wireless/ath/ath11k/hw.h | 14 +++++++++++--- + drivers/net/wireless/ath/ath11k/qmi.c | 2 +- + drivers/net/wireless/ath/ath11k/qmi.h | 6 +++++- + 4 files changed, 24 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/Kconfig ++++ b/drivers/net/wireless/ath/ath11k/Kconfig +@@ -23,6 +23,13 @@ config ATH11K_NSS_SUPPORT + + If unsure, say Y to enable NSS offload support. + ++config ATH11K_MEM_PROFILE_512M ++ bool "ath11k enable 512MB memory profile" ++ depends on ATH11K ++ default n ++ ---help--- ++ Enables 512MB memory profile for ath11k ++ + config ATH11K_AHB + tristate "Atheros ath11k AHB support" + depends on m +--- a/drivers/net/wireless/ath/ath11k/hw.h ++++ b/drivers/net/wireless/ath/ath11k/hw.h +@@ -11,11 +11,30 @@ + #include "wmi.h" + + /* Target configuration defines */ ++#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_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) + + #define TARGET_NUM_PEERS_PDEV(ab) (ab->hw_params.num_peers + TARGET_NUM_VDEVS(ab)) ++/* Max num of stations (per radio) */ ++#define TARGET_NUM_STATIONS(ab) (ab->hw_params.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_MON_STATUS_RING_SIZE 1024 ++#define ATH11K_DP_RXDMA_MONITOR_BUF_RING_SIZE 4096 ++#define ATH11K_DP_RXDMA_MONITOR_DST_RING_SIZE 2048 ++#endif + + /* Num of peers for Single Radio mode */ + #define TARGET_NUM_PEERS_SINGLE(ab) (TARGET_NUM_PEERS_PDEV(ab)) +@@ -26,9 +45,6 @@ + /* Num of peers for DBS_SBS */ + #define TARGET_NUM_PEERS_DBS_SBS(ab) (3 * TARGET_NUM_PEERS_PDEV(ab)) + +-/* Max num of stations (per radio) */ +-#define TARGET_NUM_STATIONS(ab) (ab->hw_params.num_peers) +- + #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) + \ +--- a/drivers/net/wireless/ath/ath11k/qmi.h ++++ b/drivers/net/wireless/ath/ath11k/qmi.h +@@ -29,6 +29,12 @@ + #define ATH11K_QMI_BDF_EXT_STR_LENGTH 0x20 + #define ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT 5 + ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M ++#define ATH11K_QMI_IPQ8074_M3_DUMP_ADDRESS 0x4E800000 ++#else ++#define ATH11K_QMI_IPQ8074_M3_DUMP_ADDRESS 0x51000000 ++#endif ++ + #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); + ++enum ath11k_target_mem_mode { ++ ATH11K_QMI_TARGET_MEM_MODE_DEFAULT = 0, ++ ATH11K_QMI_TARGET_MEM_MODE_512M, ++ ATH11K_QMI_TARGET_MEM_MODE_256M, ++}; ++ + #endif +--- a/local-symbols ++++ b/local-symbols +@@ -171,6 +171,7 @@ ATH11K= + ATH11K_AHB= + ATH11K_PCI= + ATH11K_NSS_SUPPORT= ++ATH11K_MEM_PROFILE_512M= + ATH11K_DEBUG= + ATH11K_DEBUGFS= + 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 { + u16 hw_rev; + }; + ++struct ath11k_num_vdevs_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 + ++ atomic_t num_max_allowed; ++ struct ath11k_num_vdevs_peers *num_vdevs_peers; ++ + /* 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 +@@ -206,8 +206,9 @@ struct ath11k_pdev_dp { + #define DP_WBM_RELEASE_RING_SIZE 64 + #define DP_TCL_DATA_RING_SIZE 512 + #define DP_TCL_DATA_RING_SIZE_WCN6750 2048 +-#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_TCL_CMD_RING_SIZE 32 + #define DP_TCL_STATUS_RING_SIZE 32 + #define DP_REO_DST_RING_MAX 4 +@@ -220,9 +221,9 @@ struct ath11k_pdev_dp { + #define DP_RXDMA_BUF_RING_SIZE 4096 + #define DP_RXDMA_REFILL_RING_SIZE 2048 + #define DP_RXDMA_ERR_DST_RING_SIZE 1024 +-#define DP_RXDMA_MON_STATUS_RING_SIZE 1024 +-#define DP_RXDMA_MONITOR_BUF_RING_SIZE 4096 +-#define DP_RXDMA_MONITOR_DST_RING_SIZE 2048 ++#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 ++#define DP_RXDMA_MONITOR_DST_RING_SIZE ATH11K_DP_RXDMA_MONITOR_BUF_RING_SIZE + #define DP_RXDMA_MONITOR_DESC_RING_SIZE 4096 + + #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: + skb->data, skb->len); + + atomic_inc(&ar->dp.num_tx_pending); ++ atomic_inc(&ab->num_max_allowed); + + return 0; + +@@ -309,6 +310,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); ++ atomic_dec(&ab->num_max_allowed); + } + + static void +@@ -342,6 +344,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); ++ atomic_dec(&ab->num_max_allowed); + + dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); + +@@ -769,6 +772,7 @@ void ath11k_dp_tx_completion_handler(str + wake_up(&ar->dp.tx_empty_waitq); + + ath11k_dp_tx_complete_msdu(ar, msdu, &ts); ++ atomic_dec(&ab->num_max_allowed); + } + } + +--- 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 +@@ -35,13 +37,16 @@ MODULE_PARM_DESC(crypto_mode, "crypto mo + /* frame mode values are mapped as per enum ath11k_hw_txrx_mode */ + unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_NATIVE_WIFI; + 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)"); ++MODULE_PARM_DESC( ++ frame_mode, ++ "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)"); + + 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"); + ++static const struct ath11k_num_vdevs_peers ath11k_vdevs_peers[]; ++ + static struct ath11k_hw_params ath11k_hw_params[] = { + { + .hw_rev = ATH11K_HW_IPQ8074, +@@ -177,7 +182,7 @@ static struct ath11k_hw_params ath11k_hw + .coldboot_cal_mm = true, + .coldboot_cal_ftm = true, + .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 +264,7 @@ static struct ath11k_hw_params ath11k_hw + .coldboot_cal_mm = false, + .coldboot_cal_ftm = false, + .cbcal_restart_fw = false, +- .fw_mem_mode = 0, ++ .fw_mem_mode = ATH11K_QMI_TARGET_MEM_MODE, + .num_vdevs = 16 + 1, + .num_peers = 512, + .supports_suspend = true, +@@ -426,7 +431,7 @@ static struct ath11k_hw_params ath11k_hw + .coldboot_cal_mm = false, + .coldboot_cal_ftm = false, + .cbcal_restart_fw = false, +- .fw_mem_mode = 0, ++ .fw_mem_mode = ATH11K_QMI_TARGET_MEM_MODE, + .num_vdevs = 16 + 1, + .num_peers = 512, + .supports_suspend = true, +@@ -509,7 +514,7 @@ static struct ath11k_hw_params ath11k_hw + .coldboot_cal_mm = false, + .coldboot_cal_ftm = false, + .cbcal_restart_fw = false, +- .fw_mem_mode = 0, ++ .fw_mem_mode = ATH11K_QMI_TARGET_MEM_MODE, + .num_vdevs = 16 + 1, + .num_peers = 512, + .supports_suspend = true, +@@ -593,7 +598,7 @@ static struct ath11k_hw_params ath11k_hw + .coldboot_cal_mm = true, + .coldboot_cal_ftm = true, + .cbcal_restart_fw = false, +- .fw_mem_mode = 0, ++ .fw_mem_mode = ATH11K_QMI_TARGET_MEM_MODE, + .num_vdevs = 16 + 1, + .num_peers = 512, + .supports_suspend = false, +@@ -672,7 +677,7 @@ static struct ath11k_hw_params ath11k_hw + .supports_monitor = false, + .supports_sta_ps = false, + .supports_shadow_regs = false, +- .fw_mem_mode = 0, ++ .fw_mem_mode = ATH11K_QMI_TARGET_MEM_MODE, + .num_vdevs = 16 + 1, + .num_peers = 512, + .supports_regdb = false, +@@ -710,7 +715,23 @@ static struct ath11k_hw_params ath11k_hw + }, + }; + +-static inline struct ath11k_pdev *ath11k_core_get_single_pdev(struct ath11k_base *ab) ++static const struct ath11k_num_vdevs_peers ath11k_vdevs_peers[] = { ++ { ++ .num_vdevs = (16 + 1), ++ .num_peers = 512, ++ }, ++ { ++ .num_vdevs = (8 + 1), ++ .num_peers = 128, ++ }, ++ { ++ .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); + +@@ -794,8 +815,10 @@ int ath11k_core_suspend(struct ath11k_ba + + ret = ath11k_dp_rx_pktlog_stop(ab, true); + if (ret) { +- ath11k_warn(ab, "failed to stop dp rx (and timer) pktlog during suspend: %d\n", +- ret); ++ ath11k_warn( ++ ab, ++ "failed to stop dp rx (and timer) pktlog during suspend: %d\n", ++ ret); + return ret; + } + +@@ -807,13 +830,15 @@ int ath11k_core_suspend(struct ath11k_ba + + ret = ath11k_wow_enable(ab); + if (ret) { +- ath11k_warn(ab, "failed to enable wow during suspend: %d\n", ret); ++ ath11k_warn(ab, "failed to enable wow during suspend: %d\n", ++ ret); + return ret; + } + + ret = ath11k_dp_rx_pktlog_stop(ab, false); + if (ret) { +- ath11k_warn(ab, "failed to stop dp rx pktlog during suspend: %d\n", ++ ath11k_warn(ab, ++ "failed to stop dp rx pktlog during suspend: %d\n", + ret); + return ret; + } +@@ -853,7 +878,8 @@ int ath11k_core_resume(struct ath11k_bas + + ret = ath11k_hif_resume(ab); + if (ret) { +- ath11k_warn(ab, "failed to resume hif during resume: %d\n", ret); ++ ath11k_warn(ab, "failed to resume hif during resume: %d\n", ++ ret); + return ret; + } + +@@ -869,7 +895,8 @@ int ath11k_core_resume(struct ath11k_bas + + ret = ath11k_wow_wakeup(ab); + if (ret) { +- ath11k_warn(ab, "failed to wakeup wow during resume: %d\n", ret); ++ ath11k_warn(ab, "failed to wakeup wow during resume: %d\n", ++ ret); + return ret; + } + +@@ -877,7 +904,8 @@ int ath11k_core_resume(struct ath11k_bas + } + EXPORT_SYMBOL(ath11k_core_resume); + +-static void ath11k_core_check_cc_code_bdfext(const struct dmi_header *hdr, void *data) ++static void ath11k_core_check_cc_code_bdfext(const struct dmi_header *hdr, ++ void *data) + { + struct ath11k_base *ab = data; + const char *magic = ATH11K_SMBIOS_BDF_EXT_MAGIC; +@@ -914,7 +942,8 @@ static void ath11k_core_check_cc_code_bd + ath11k_dbg(ab, ATH11K_DBG_BOOT, "smbios worldwide regdomain\n"); + break; + default: +- ath11k_dbg(ab, ATH11K_DBG_BOOT, "ignore smbios country code setting %d\n", ++ ath11k_dbg(ab, ATH11K_DBG_BOOT, ++ "ignore smbios country code setting %d\n", + smbios->country_code_flag); + break; + } +@@ -922,7 +951,8 @@ static void ath11k_core_check_cc_code_bd + spin_unlock_bh(&ab->base_lock); + + if (!smbios->bdf_enabled) { +- ath11k_dbg(ab, ATH11K_DBG_BOOT, "bdf variant name not found.\n"); ++ ath11k_dbg(ab, ATH11K_DBG_BOOT, ++ "bdf variant name not found.\n"); + return; + } + +@@ -933,22 +963,26 @@ static void ath11k_core_check_cc_code_bd + return; + } + +- len = min_t(size_t, +- strlen(smbios->bdf_ext), sizeof(ab->qmi.target.bdf_ext)); ++ len = min_t(size_t, strlen(smbios->bdf_ext), ++ sizeof(ab->qmi.target.bdf_ext)); + for (i = 0; i < len; i++) { +- if (!isascii(smbios->bdf_ext[i]) || !isprint(smbios->bdf_ext[i])) { +- ath11k_dbg(ab, ATH11K_DBG_BOOT, +- "bdf variant name contains non ascii chars.\n"); ++ if (!isascii(smbios->bdf_ext[i]) || ++ !isprint(smbios->bdf_ext[i])) { ++ ath11k_dbg( ++ ab, ATH11K_DBG_BOOT, ++ "bdf variant name contains non ascii chars.\n"); + return; + } + } + + /* Copy extension name without magic prefix */ +- copied = strscpy(ab->qmi.target.bdf_ext, smbios->bdf_ext + strlen(magic), ++ copied = strscpy(ab->qmi.target.bdf_ext, ++ smbios->bdf_ext + strlen(magic), + sizeof(ab->qmi.target.bdf_ext)); + if (copied < 0) { +- ath11k_dbg(ab, ATH11K_DBG_BOOT, +- "bdf variant string is longer than the buffer can accommodate\n"); ++ ath11k_dbg( ++ ab, ATH11K_DBG_BOOT, ++ "bdf variant string is longer than the buffer can accommodate\n"); + return; + } + +@@ -984,9 +1018,10 @@ int ath11k_core_check_dt(struct ath11k_b + return -ENODATA; + + if (strscpy(ab->qmi.target.bdf_ext, variant, max_len) < 0) +- ath11k_dbg(ab, ATH11K_DBG_BOOT, +- "bdf variant string is longer than the buffer can accommodate (variant: %s)\n", +- variant); ++ ath11k_dbg( ++ ab, ATH11K_DBG_BOOT, ++ "bdf variant string is longer than the buffer can accommodate (variant: %s)\n", ++ variant); + + return 0; + } +@@ -1012,24 +1047,20 @@ static int __ath11k_core_create_board_na + case ATH11K_BDF_SEARCH_BUS_AND_BOARD: + switch (name_type) { + case ATH11K_BDF_NAME_FULL: +- scnprintf(name, name_len, +- "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x,qmi-chip-id=%d,qmi-board-id=%d%s", +- ath11k_bus_str(ab->hif.bus), +- ab->id.vendor, ab->id.device, +- ab->id.subsystem_vendor, +- ab->id.subsystem_device, +- ab->qmi.target.chip_id, +- ab->qmi.target.board_id, +- variant); ++ scnprintf( ++ name, name_len, ++ "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x,qmi-chip-id=%d,qmi-board-id=%d%s", ++ ath11k_bus_str(ab->hif.bus), ab->id.vendor, ++ ab->id.device, ab->id.subsystem_vendor, ++ ab->id.subsystem_device, ab->qmi.target.chip_id, ++ ab->qmi.target.board_id, variant); + break; + case ATH11K_BDF_NAME_BUS_NAME: +- scnprintf(name, name_len, +- "bus=%s", ++ scnprintf(name, name_len, "bus=%s", + ath11k_bus_str(ab->hif.bus)); + break; + case ATH11K_BDF_NAME_CHIP_ID: +- scnprintf(name, name_len, +- "bus=%s,qmi-chip-id=%d", ++ scnprintf(name, name_len, "bus=%s,qmi-chip-id=%d", + ath11k_bus_str(ab->hif.bus), + ab->qmi.target.chip_id); + break; +@@ -1038,8 +1069,7 @@ static int __ath11k_core_create_board_na + default: + scnprintf(name, name_len, + "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s", +- ath11k_bus_str(ab->hif.bus), +- ab->qmi.target.chip_id, ++ ath11k_bus_str(ab->hif.bus), ab->qmi.target.chip_id, + ab->qmi.target.board_id, variant); + break; + } +@@ -1056,22 +1086,22 @@ static int ath11k_core_create_board_name + ATH11K_BDF_NAME_FULL); + } + +-static int ath11k_core_create_fallback_board_name(struct ath11k_base *ab, char *name, +- size_t name_len) ++static int ath11k_core_create_fallback_board_name(struct ath11k_base *ab, ++ char *name, size_t name_len) + { + return __ath11k_core_create_board_name(ab, name, name_len, false, + ATH11K_BDF_NAME_FULL); + } + +-static int ath11k_core_create_bus_type_board_name(struct ath11k_base *ab, char *name, +- size_t name_len) ++static int ath11k_core_create_bus_type_board_name(struct ath11k_base *ab, ++ char *name, size_t name_len) + { + return __ath11k_core_create_board_name(ab, name, name_len, false, + ATH11K_BDF_NAME_BUS_NAME); + } + +-static int ath11k_core_create_chip_id_board_name(struct ath11k_base *ab, char *name, +- size_t name_len) ++static int ath11k_core_create_chip_id_board_name(struct ath11k_base *ab, ++ char *name, size_t name_len) + { + return __ath11k_core_create_board_name(ab, name, name_len, false, + ATH11K_BDF_NAME_CHIP_ID); +@@ -1093,8 +1123,8 @@ const struct firmware *ath11k_core_firmw + if (ret) + return ERR_PTR(ret); + +- ath11k_dbg(ab, ATH11K_DBG_BOOT, "firmware request %s size %zu\n", +- path, fw->size); ++ ath11k_dbg(ab, ATH11K_DBG_BOOT, "firmware request %s size %zu\n", path, ++ fw->size); + + return fw; + } +@@ -1110,10 +1140,8 @@ void ath11k_core_free_bdf(struct ath11k_ + static int ath11k_core_parse_bd_ie_board(struct ath11k_base *ab, + struct ath11k_board_data *bd, + const void *buf, size_t buf_len, +- const char *boardname, +- int ie_id, +- int name_id, +- int data_id) ++ const char *boardname, int ie_id, ++ int name_id, int data_id) + { + const struct ath11k_fw_ie *hdr; + bool name_match_found; +@@ -1135,8 +1163,8 @@ static int ath11k_core_parse_bd_ie_board + + if (buf_len < ALIGN(board_ie_len, 4)) { + ath11k_err(ab, "invalid %s length: %zu < %zu\n", +- ath11k_bd_ie_type_str(ie_id), +- buf_len, ALIGN(board_ie_len, 4)); ++ ath11k_bd_ie_type_str(ie_id), buf_len, ++ ALIGN(board_ie_len, 4)); + ret = -EINVAL; + goto out; + } +@@ -1148,24 +1176,22 @@ static int ath11k_core_parse_bd_ie_board + if (board_ie_len != strlen(boardname)) + goto next; + +- ret = memcmp(board_ie_data, boardname, strlen(boardname)); ++ ret = memcmp(board_ie_data, boardname, ++ strlen(boardname)); + if (ret) + goto next; + + name_match_found = true; + ath11k_dbg(ab, ATH11K_DBG_BOOT, + "found match %s for name '%s'", +- ath11k_bd_ie_type_str(ie_id), +- boardname); ++ ath11k_bd_ie_type_str(ie_id), boardname); + } else if (board_ie_id == data_id) { + if (!name_match_found) + /* no match found */ + goto next; + +- ath11k_dbg(ab, ATH11K_DBG_BOOT, +- "found %s for '%s'", +- ath11k_bd_ie_type_str(ie_id), +- boardname); ++ ath11k_dbg(ab, ATH11K_DBG_BOOT, "found %s for '%s'", ++ ath11k_bd_ie_type_str(ie_id), boardname); + + bd->data = board_ie_data; + bd->len = board_ie_len; +@@ -1174,8 +1200,7 @@ static int ath11k_core_parse_bd_ie_board + goto out; + } else { + ath11k_warn(ab, "unknown %s id found: %d\n", +- ath11k_bd_ie_type_str(ie_id), +- board_ie_id); ++ ath11k_bd_ie_type_str(ie_id), board_ie_id); + } + next: + /* jump over the padding */ +@@ -1195,8 +1220,7 @@ out: + static int ath11k_core_fetch_board_data_api_n(struct ath11k_base *ab, + struct ath11k_board_data *bd, + const char *boardname, +- int ie_id_match, +- int name_id, ++ int ie_id_match, int name_id, + int data_id) + { + size_t len, magic_len; +@@ -1217,14 +1241,16 @@ static int ath11k_core_fetch_board_data_ + data = bd->fw->data; + len = bd->fw->size; + +- ath11k_core_create_firmware_path(ab, filename, +- filepath, sizeof(filepath)); ++ ath11k_core_create_firmware_path(ab, filename, filepath, ++ sizeof(filepath)); + + /* magic has extra null byte padded */ + magic_len = strlen(ATH11K_BOARD_MAGIC) + 1; + if (len < magic_len) { +- ath11k_err(ab, "failed to find magic value in %s, file too short: %zu\n", +- filepath, len); ++ ath11k_err( ++ ab, ++ "failed to find magic value in %s, file too short: %zu\n", ++ filepath, len); + ret = -EINVAL; + goto err; + } +@@ -1238,8 +1264,10 @@ static int ath11k_core_fetch_board_data_ + /* magic is padded to 4 bytes */ + magic_len = ALIGN(magic_len, 4); + if (len < magic_len) { +- ath11k_err(ab, "failed: %s too small to contain board data, len: %zu\n", +- filepath, len); ++ ath11k_err( ++ ab, ++ "failed: %s too small to contain board data, len: %zu\n", ++ filepath, len); + ret = -EINVAL; + goto err; + } +@@ -1256,19 +1284,19 @@ static int ath11k_core_fetch_board_data_ + data = hdr->data; + + if (len < ALIGN(ie_len, 4)) { +- ath11k_err(ab, "invalid length for board ie_id %d ie_len %zu len %zu\n", +- ie_id, ie_len, len); ++ ath11k_err( ++ ab, ++ "invalid length for board ie_id %d ie_len %zu len %zu\n", ++ ie_id, ie_len, len); + ret = -EINVAL; + goto err; + } + + if (ie_id == ie_id_match) { + ret = ath11k_core_parse_bd_ie_board(ab, bd, data, +- ie_len, +- boardname, ++ ie_len, boardname, + ie_id_match, +- name_id, +- data_id); ++ name_id, data_id); + if (ret == -ENOENT) + /* no match found, continue */ + goto next; +@@ -1290,8 +1318,8 @@ out: + if (!bd->data || !bd->len) { + ath11k_dbg(ab, ATH11K_DBG_BOOT, + "failed to fetch %s for %s from %s\n", +- ath11k_bd_ie_type_str(ie_id_match), +- boardname, filepath); ++ ath11k_bd_ie_type_str(ie_id_match), boardname, ++ filepath); + ret = -ENODATA; + goto err; + } +@@ -1321,7 +1349,8 @@ int ath11k_core_fetch_board_data_api_1(s + #define BOARD_NAME_SIZE 200 + int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd) + { +- char *boardname = NULL, *fallback_boardname = NULL, *chip_id_boardname = NULL; ++ char *boardname = NULL, *fallback_boardname = NULL, ++ *chip_id_boardname = NULL; + char *filename, filepath[100]; + int ret = 0; + +@@ -1388,15 +1417,18 @@ int ath11k_core_fetch_bdf(struct ath11k_ + goto exit; + + ab->bd_api = 1; +- ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_DEFAULT_BOARD_FILE); ++ ret = ath11k_core_fetch_board_data_api_1(ab, bd, ++ ATH11K_DEFAULT_BOARD_FILE); + if (ret) { +- ath11k_core_create_firmware_path(ab, filename, +- filepath, sizeof(filepath)); ++ ath11k_core_create_firmware_path(ab, filename, filepath, ++ sizeof(filepath)); + ath11k_err(ab, "failed to fetch board data for %s from %s\n", + boardname, filepath); + if (memcmp(boardname, fallback_boardname, strlen(boardname))) +- ath11k_err(ab, "failed to fetch board data for %s from %s\n", +- fallback_boardname, filepath); ++ ath11k_err( ++ ab, ++ "failed to fetch board data for %s from %s\n", ++ fallback_boardname, filepath); + + ath11k_err(ab, "failed to fetch board data for %s from %s\n", + chip_id_boardname, filepath); +@@ -1411,12 +1443,14 @@ exit: + kfree(chip_id_boardname); + + if (!ret) +- ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board api %d\n", ab->bd_api); ++ ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board api %d\n", ++ ab->bd_api); + + return ret; + } + +-int ath11k_core_fetch_regdb(struct ath11k_base *ab, struct ath11k_board_data *bd) ++int ath11k_core_fetch_regdb(struct ath11k_base *ab, ++ struct ath11k_board_data *bd) + { + char boardname[BOARD_NAME_SIZE], default_boardname[BOARD_NAME_SIZE]; + int ret; +@@ -1439,7 +1473,8 @@ int ath11k_core_fetch_regdb(struct ath11 + BOARD_NAME_SIZE); + if (ret) { + ath11k_dbg(ab, ATH11K_DBG_BOOT, +- "failed to create default board name for regdb: %d", ret); ++ "failed to create default board name for regdb: %d", ++ ret); + goto exit; + } + +@@ -1450,7 +1485,8 @@ int ath11k_core_fetch_regdb(struct ath11 + if (!ret) + goto exit; + +- ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_REGDB_FILE_NAME); ++ ret = ath11k_core_fetch_board_data_api_1(ab, bd, ++ ATH11K_REGDB_FILE_NAME); + if (ret) + ath11k_dbg(ab, ATH11K_DBG_BOOT, "failed to fetch %s from %s\n", + ATH11K_REGDB_FILE_NAME, ab->hw_params.fw.dir); +@@ -1542,14 +1578,14 @@ static int ath11k_core_pdev_create(struc + + ret = ath11k_mac_register(ab); + if (ret) { +- ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret); ++ ath11k_err(ab, "failed register the radio with mac80211: %d\n", ++ ret); + goto err_nss_tear; + } + + ret = ath11k_thermal_register(ab); + if (ret) { +- ath11k_err(ab, "could not register thermal device: %d\n", +- ret); ++ ath11k_err(ab, "could not register thermal device: %d\n", ret); + goto err_mac_unregister; + } + +@@ -1637,14 +1673,16 @@ static int ath11k_core_start(struct ath1 + + ret = ath11k_wmi_wait_for_service_ready(ab); + if (ret) { +- ath11k_err(ab, "failed to receive wmi service ready event: %d\n", ++ ath11k_err(ab, ++ "failed to receive wmi service ready event: %d\n", + ret); + goto err_hif_stop; + } + + ret = ath11k_mac_allocate(ab); + if (ret) { +- ath11k_err(ab, "failed to create new hw device with mac80211 :%d\n", ++ ath11k_err(ab, ++ "failed to create new hw device with mac80211 :%d\n", + ret); + goto err_hif_stop; + } +@@ -1653,7 +1691,9 @@ static int ath11k_core_start(struct ath1 + + ret = ath11k_dp_pdev_reo_setup(ab); + if (ret) { +- ath11k_err(ab, "failed to initialize reo destination rings: %d\n", ret); ++ ath11k_err(ab, ++ "failed to initialize reo destination rings: %d\n", ++ ret); + goto err_mac_destroy; + } + +@@ -1665,13 +1705,15 @@ static int ath11k_core_start(struct ath1 + + ret = ath11k_wmi_wait_for_unified_ready(ab); + if (ret) { +- ath11k_err(ab, "failed to receive wmi unified ready event: %d\n", ++ ath11k_err(ab, ++ "failed to receive wmi unified ready event: %d\n", + ret); + goto err_reo_cleanup; + } + + /* put hardware to DBS mode */ +- if (ab->hw_params.single_pdev_only && ab->hw_params.num_rxmda_per_pdev > 1) { ++ if (ab->hw_params.single_pdev_only && ++ ab->hw_params.num_rxmda_per_pdev > 1) { + ret = ath11k_wmi_set_hw_mode(ab, WMI_HOST_HW_MODE_DBS); + if (ret) { + ath11k_err(ab, "failed to send dbs mode: %d\n", ret); +@@ -1681,7 +1723,8 @@ static int ath11k_core_start(struct ath1 + + ret = ath11k_dp_tx_htt_h2t_ver_req_msg(ab); + if (ret) { +- ath11k_err(ab, "failed to send htt version request message: %d\n", ++ ath11k_err(ab, ++ "failed to send htt version request message: %d\n", + ret); + goto err_reo_cleanup; + } +@@ -1749,7 +1792,8 @@ int ath11k_core_qmi_firmware_ready(struc + clear_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags); + break; + default: +- ath11k_info(ab, "invalid crypto_mode: %d\n", ath11k_crypto_mode); ++ ath11k_info(ab, "invalid crypto_mode: %d\n", ++ ath11k_crypto_mode); + return -EINVAL; + } + +@@ -1850,7 +1894,8 @@ void ath11k_core_halt(struct ath11k *ar) + + static void ath11k_update_11d(struct work_struct *work) + { +- struct ath11k_base *ab = container_of(work, struct ath11k_base, update_11d_work); ++ struct ath11k_base *ab = ++ container_of(work, struct ath11k_base, update_11d_work); + struct ath11k *ar; + struct ath11k_pdev *pdev; + struct wmi_set_current_country_params set_current_param = {}; +@@ -1861,19 +1906,20 @@ static void ath11k_update_11d(struct wor + spin_unlock_bh(&ab->base_lock); + + ath11k_dbg(ab, ATH11K_DBG_WMI, "update 11d new cc %c%c\n", +- set_current_param.alpha2[0], +- set_current_param.alpha2[1]); ++ set_current_param.alpha2[0], set_current_param.alpha2[1]); + + for (i = 0; i < ab->num_radios; i++) { + pdev = &ab->pdevs[i]; + ar = pdev->ar; + + memcpy(&ar->alpha2, &set_current_param.alpha2, 2); +- ret = ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param); ++ ret = ath11k_wmi_send_set_current_country_cmd( ++ ar, &set_current_param); + if (ret) +- ath11k_warn(ar->ab, +- "pdev id %d failed set current country code: %d\n", +- i, ret); ++ ath11k_warn( ++ ar->ab, ++ "pdev id %d failed set current country code: %d\n", ++ i, ret); + } + } + +@@ -1910,8 +1956,8 @@ void ath11k_core_pre_reconfigure_recover + complete(&ar->thermal.wmi_sync); + + wake_up(&ar->dp.tx_empty_waitq); +- idr_for_each(&ar->txmgmt_idr, +- ath11k_mac_tx_mgmt_pending_free, ar); ++ idr_for_each(&ar->txmgmt_idr, ath11k_mac_tx_mgmt_pending_free, ++ ar); + idr_destroy(&ar->txmgmt_idr); + wake_up(&ar->txmgmt_empty_waitq); + +@@ -1947,9 +1993,10 @@ static void ath11k_core_post_reconfigure + ieee80211_restart_hw(ar->hw); + break; + case ATH11K_STATE_OFF: +- ath11k_warn(ab, +- "cannot restart radio %d that hasn't been started\n", +- i); ++ ath11k_warn( ++ ab, ++ "cannot restart radio %d that hasn't been started\n", ++ i); + break; + case ATH11K_STATE_RESTARTING: + break; +@@ -1957,8 +2004,10 @@ static void ath11k_core_post_reconfigure + ar->state = ATH11K_STATE_WEDGED; + fallthrough; + case ATH11K_STATE_WEDGED: +- ath11k_warn(ab, +- "device is wedged, will not restart radio %d\n", i); ++ ath11k_warn( ++ ab, ++ "device is wedged, will not restart radio %d\n", ++ i); + break; + case ATH11K_STATE_FTM: + ath11k_dbg(ab, ATH11K_DBG_TESTMODE, +@@ -1973,12 +2022,14 @@ static void ath11k_core_post_reconfigure + + static void ath11k_core_restart(struct work_struct *work) + { +- struct ath11k_base *ab = container_of(work, struct ath11k_base, restart_work); ++ struct ath11k_base *ab = ++ container_of(work, struct ath11k_base, restart_work); + int ret; + + ret = ath11k_core_reconfigure_on_crash(ab); + if (ret) { +- ath11k_err(ab, "failed to reconfigure driver on crash recovery\n"); ++ ath11k_err(ab, ++ "failed to reconfigure driver on crash recovery\n"); + return; + } + +@@ -1991,12 +2042,14 @@ static void ath11k_core_restart(struct w + + static void ath11k_core_reset(struct work_struct *work) + { +- struct ath11k_base *ab = container_of(work, struct ath11k_base, reset_work); ++ struct ath11k_base *ab = ++ container_of(work, struct ath11k_base, reset_work); + int reset_count, fail_cont_count; + long time_left; + + if (!(test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))) { +- ath11k_warn(ab, "ignore reset dev flags 0x%lx\n", ab->dev_flags); ++ ath11k_warn(ab, "ignore reset dev flags 0x%lx\n", ++ ab->dev_flags); + return; + } + +@@ -2022,8 +2075,8 @@ static void ath11k_core_reset(struct wor + ath11k_warn(ab, "already resetting count %d\n", reset_count); + + reinit_completion(&ab->reset_complete); +- time_left = wait_for_completion_timeout(&ab->reset_complete, +- ATH11K_RESET_TIMEOUT_HZ); ++ time_left = wait_for_completion_timeout( ++ &ab->reset_complete, ATH11K_RESET_TIMEOUT_HZ); + + if (time_left) { + ath11k_dbg(ab, ATH11K_DBG_BOOT, "to skip reset\n"); +@@ -2050,8 +2103,8 @@ static void ath11k_core_reset(struct wor + + ath11k_dbg(ab, ATH11K_DBG_BOOT, "waiting recovery start...\n"); + +- time_left = wait_for_completion_timeout(&ab->recovery_start, +- ATH11K_RECOVER_START_TIMEOUT_HZ); ++ time_left = wait_for_completion_timeout( ++ &ab->recovery_start, ATH11K_RECOVER_START_TIMEOUT_HZ); + + ath11k_hif_power_down(ab); + ath11k_hif_power_up(ab); +@@ -2073,22 +2126,21 @@ static int ath11k_init_hw_params(struct + } + + if (i == ARRAY_SIZE(ath11k_hw_params)) { +- ath11k_err(ab, "Unsupported hardware version: 0x%x\n", ab->hw_rev); ++ ath11k_err(ab, "Unsupported hardware version: 0x%x\n", ++ ab->hw_rev); + return -EINVAL; + } + + ab->hw_params = *hw_params; + + ret = of_property_read_u32(ab->dev->of_node, +- "qcom,ath11k-fw-memory-mode", +- &fw_mem_mode); ++ "qcom,ath11k-fw-memory-mode", &fw_mem_mode); + if (!ret) { + if (fw_mem_mode == 0) { + ab->hw_params.fw_mem_mode = 0; + ab->hw_params.num_vdevs = 16 + 1; + ab->hw_params.num_peers = 512; +- } +- else if (fw_mem_mode == 1) { ++ } else if (fw_mem_mode == 1) { + ab->hw_params.fw_mem_mode = 1; + ab->hw_params.num_vdevs = 8; + ab->hw_params.num_peers = 128; +@@ -2099,7 +2151,8 @@ static int ath11k_init_hw_params(struct + ab->hw_params.coldboot_cal_mm = false; + ab->hw_params.coldboot_cal_ftm = false; + } else +- ath11k_info(ab, "Unsupported FW memory mode: %u\n", fw_mem_mode); ++ ath11k_info(ab, "Unsupported FW memory mode: %u\n", ++ fw_mem_mode); + } + + ath11k_info(ab, "%s\n", ab->hw_params.name); +@@ -2215,5 +2268,6 @@ err_sc_free: + } + EXPORT_SYMBOL(ath11k_core_alloc); + +-MODULE_DESCRIPTION("Core module for Qualcomm Atheros 802.11ax wireless LAN cards."); ++MODULE_DESCRIPTION( ++ "Core module for Qualcomm Atheros 802.11ax wireless LAN cards."); + MODULE_LICENSE("Dual BSD/GPL"); diff --git a/package/kernel/mac80211/patches/ath11k_nss/214-ath11k-qos-null-frame-tx-over-wmi.patch b/package/kernel/mac80211/patches/ath11k_nss/214-ath11k-qos-null-frame-tx-over-wmi.patch new file mode 100644 index 00000000000000..a388aa24b7aab2 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/214-ath11k-qos-null-frame-tx-over-wmi.patch @@ -0,0 +1,520 @@ +From 0e29b669153f100b60107d5f6b3fe407b71ba79a Mon Sep 17 00:00:00 2001 +From: Sowmiya Sree Elavalagan +Date: Wed, 30 Sep 2020 22:33:42 +0530 +Subject: [PATCH] ath11k: QOS null frame tx over wmi + +Added support to send qos null frame through FW. +NSS driver does not support QOS null frame tx. +Hence this is brought for nss offload case to send +qos null frame. QOS null packet queued from mac80211 +is sent to FW through wmi interface. This happens only if FW supports +qos null tx, this is based on service bit received in ext2 service +event from FW. On successful transmission of QOS null frame status +is set 0 in the event received for this wmi message. This is status +is sent to mac80211 for further handling. + +Signed-off-by: Sowmiya Sree Elavalagan +--- + drivers/net/wireless/ath/ath11k/mac.c | 28 ++++- + drivers/net/wireless/ath/ath11k/wmi.c | 200 ++++++++++++++++++++++++++-------- + drivers/net/wireless/ath/ath11k/wmi.h | 46 +++++++- + 3 files changed, 220 insertions(+), 54 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -6127,6 +6127,16 @@ static int ath11k_mac_mgmt_tx_wmi(struct + + ATH11K_SKB_CB(skb)->paddr = paddr; + ++ if (ieee80211_is_qos_nullfunc(hdr->frame_control)) { ++ ret = ath11k_wmi_qos_null_send(ar, arvif->vdev_id, buf_id, skb); ++ if (ret) { ++ ath11k_warn(ar->ab, "failed to send qos null frame over wmi: %d\n", ret); ++ goto err_unmap_buf; ++ } ++ ++ return 0; ++ } ++ + ret = ath11k_wmi_mgmt_send(ar, arvif->vdev_id, buf_id, skb); + if (ret) { + ath11k_warn(ar->ab, "failed to send mgmt frame: %d\n", ret); +@@ -6194,8 +6204,8 @@ static void ath11k_mgmt_over_wmi_tx_work + } + } + +-static int ath11k_mac_mgmt_tx(struct ath11k *ar, struct sk_buff *skb, +- bool is_prb_rsp) ++static int ath11k_mac_tx_over_wmi(struct ath11k *ar, struct sk_buff *skb, ++ bool is_prb_rsp) + { + struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue; + +@@ -6257,7 +6267,7 @@ static void ath11k_mac_op_tx(struct ieee + } else if (ieee80211_is_mgmt(hdr->frame_control)) { + frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, hdr->frame_control); + is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control); +- ret = ath11k_mac_mgmt_tx(ar, skb, is_prb_rsp); ++ ret = ath11k_mac_tx_over_wmi(ar, skb, is_prb_rsp); + if (ret) { + if (ret != -EBUSY) + ath11k_warn(ar->ab, "failed to queue management frame %d\n", +@@ -6272,6 +6282,20 @@ static void ath11k_mac_op_tx(struct ieee + spin_unlock_bh(&ar->data_lock); + } + return; ++ } else if (ar->ab->nss.enabled && ++ ieee80211_is_qos_nullfunc(hdr->frame_control) && ++ test_bit(WMI_TLV_SERVICE_QOS_NULL_FRAME_TX_OVER_WMI, ++ ar->ab->wmi_ab.svc_map)) { ++ /* NSS driver does not support tx qos null pkt hence it is offload ++ * to fw via wmi path similar to mgmt frames ++ */ ++ ret = ath11k_mac_tx_over_wmi(ar, skb, false); ++ if (ret) { ++ ath11k_warn(ar->ab, "failed to queue qos null frame %d\n", ++ ret); ++ ieee80211_free_txskb(ar->hw, skb); ++ } ++ return; + } + + 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" }, + [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" }, + [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" }, + [WMI_TAG_SCAN_EVENT] +- = { .min_len = sizeof(struct wmi_scan_event) }, ++ = { .min_len = sizeof(struct wmi_scan_event), .policy = "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 * + return ret; + } + ++int ath11k_wmi_qos_null_send(struct ath11k *ar, u32 vdev_id, u32 buf_id, ++ struct sk_buff *frame) ++{ ++ struct ath11k_pdev_wmi *wmi = ar->wmi; ++ struct wmi_qos_null_tx_cmd *cmd; ++ struct wmi_tlv *frame_tlv; ++ struct sk_buff *skb; ++ u32 buf_len; ++ int len, ret = 0; ++ ++ buf_len = frame->len < WMI_QOS_NULL_SEND_BUF_LEN ? ++ frame->len : WMI_QOS_NULL_SEND_BUF_LEN; ++ ++ len = sizeof(*cmd) + sizeof(*frame_tlv) + roundup(buf_len, 4); ++ ++ skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); ++ if (!skb) ++ return -ENOMEM; ++ ++ cmd = (struct wmi_qos_null_tx_cmd *)skb->data; ++ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_QOS_NULL_FRAME_TX_SEND) | ++ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); ++ cmd->vdev_id = vdev_id; ++ cmd->desc_id = buf_id; ++ cmd->paddr_lo = lower_32_bits(ATH11K_SKB_CB(frame)->paddr); ++ cmd->paddr_hi = upper_32_bits(ATH11K_SKB_CB(frame)->paddr); ++ cmd->frame_len = frame->len; ++ cmd->buf_len = buf_len; ++ ++ frame_tlv = (struct wmi_tlv *)(skb->data + sizeof(*cmd)); ++ frame_tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) | ++ FIELD_PREP(WMI_TLV_LEN, buf_len); ++ ++ memcpy(frame_tlv->value, frame->data, buf_len); ++ ++ ath11k_ce_byte_swap(frame_tlv->value, buf_len); ++ ++ ret = ath11k_wmi_cmd_send(wmi, skb, WMI_QOS_NULL_FRAME_TX_SEND_CMDID); ++ if (ret) { ++ ath11k_warn(ar->ab, ++ "failed to submit WMI_QOS_NULL_FRAME_TX_SEND_CMDID cmd\n"); ++ dev_kfree_skb(skb); ++ } ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, ++ "wmi QOS null tx send cmd sent successfully\n"); ++ return ret; ++} ++ + 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 + return 0; + } + +-static int wmi_process_mgmt_tx_comp(struct ath11k *ar, +- struct wmi_mgmt_tx_compl_event *tx_compl_param) ++static int wmi_process_tx_comp(struct ath11k *ar, ++ struct wmi_tx_compl_event *tx_compl_param) + { + struct sk_buff *msdu; + struct ieee80211_tx_info *info; +@@ -5895,6 +5944,11 @@ static int wmi_process_mgmt_tx_comp(stru + info->status.ack_signal = tx_compl_param->ack_rssi; + } + ++ /* dont update rates in this path, qos null data tx completions also can ++ * take this path in case of nss offload and can update invalid rates. ++ */ ++ info->status.rates[0].idx = -1; ++ + 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 + 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]++; ++ 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: +@@ -5938,12 +5995,13 @@ skip_mgmt_stats: + return 0; + } + +-static int ath11k_pull_mgmt_tx_compl_param_tlv(struct ath11k_base *ab, +- struct sk_buff *skb, +- struct wmi_mgmt_tx_compl_event *param) ++static int ath11k_pull_tx_compl_param_tlv(struct ath11k_base *ab, ++ struct sk_buff *skb, ++ struct wmi_tx_compl_event *param, ++ int event_id) + { + const void **tb; +- const struct wmi_mgmt_tx_compl_event *ev; ++ const struct wmi_tx_compl_event *ev; + 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 + return ret; + } + +- ev = tb[WMI_TAG_MGMT_TX_COMPL_EVENT]; ++ ev = tb[event_id]; + if (!ev) { + ath11k_warn(ab, "failed to fetch mgmt tx compl ev"); + kfree(tb); +@@ -7730,10 +7788,11 @@ exit: + + static void ath11k_mgmt_tx_compl_event(struct ath11k_base *ab, struct sk_buff *skb) + { +- struct wmi_mgmt_tx_compl_event tx_compl_param = {0}; ++ struct wmi_tx_compl_event tx_compl_param = {0}; + struct ath11k *ar; + +- if (ath11k_pull_mgmt_tx_compl_param_tlv(ab, skb, &tx_compl_param) != 0) { ++ if (ath11k_pull_tx_compl_param_tlv(ab, skb, &tx_compl_param, ++ WMI_TAG_MGMT_TX_COMPL_EVENT) != 0) { + ath11k_warn(ab, "failed to extract mgmt tx compl event"); + return; + } +@@ -7746,7 +7805,7 @@ static void ath11k_mgmt_tx_compl_event(s + goto exit; + } + +- wmi_process_mgmt_tx_comp(ar, &tx_compl_param); ++ wmi_process_tx_comp(ar, &tx_compl_param); + + 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: + rcu_read_unlock(); + } + ++static void ath11k_qos_null_compl_event(struct ath11k_base *ab, struct sk_buff *skb) ++{ ++ struct wmi_tx_compl_event tx_compl_param = {0}; ++ struct ath11k *ar; ++ ++ if (ath11k_pull_tx_compl_param_tlv(ab, skb, &tx_compl_param, ++ WMI_TAG_QOS_NULL_FRAME_TX_STATUS) != 0) { ++ ath11k_warn(ab, "failed to extract qos null tx compl event"); ++ return; ++ } ++ ++ rcu_read_lock(); ++ ar = ath11k_mac_get_ar_by_pdev_id(ab, tx_compl_param.pdev_id); ++ if (!ar) { ++ ath11k_warn(ab, "invalid pdev id %d in qos_null_tx_compl_event\n", ++ tx_compl_param.pdev_id); ++ goto exit; ++ } ++ ++ wmi_process_tx_comp(ar, &tx_compl_param); ++ ++ ath11k_dbg(ab, ATH11K_DBG_WMI, ++ "QOS null tx compl ev pdev_id %d, desc_id %d, status %d", ++ tx_compl_param.pdev_id, tx_compl_param.desc_id, ++ tx_compl_param.status); ++ ++exit: ++ rcu_read_unlock(); ++} ++ + 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); + 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; +--- a/drivers/net/wireless/ath/ath11k/wmi.h ++++ b/drivers/net/wireless/ath/ath11k/wmi.h +@@ -363,6 +363,7 @@ enum wmi_tlv_cmd_id { + WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, + WMI_VDEV_BCN_OFFLOAD_QUIET_CONFIG_CMDID, + WMI_FILS_DISCOVERY_TMPL_CMDID, ++ WMI_QOS_NULL_FRAME_TX_SEND_CMDID, + WMI_ADDBA_CLEAR_RESP_CMDID = WMI_TLV_CMD(WMI_GRP_BA_NEG), + WMI_ADDBA_SEND_CMDID, + WMI_ADDBA_STATUS_CMDID, +@@ -693,6 +694,8 @@ enum wmi_tlv_event_id { + WMI_TBTTOFFSET_EXT_UPDATE_EVENTID, + WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID, + WMI_HOST_FILS_DISCOVERY_EVENTID, ++ WMI_HOST_SWBA_V2_EVENTID, ++ WMI_QOS_NULL_FRAME_TX_COMPLETION_EVENTID, + WMI_TX_DELBA_COMPLETE_EVENTID = WMI_TLV_CMD(WMI_GRP_BA_NEG), + WMI_TX_ADDBA_COMPLETE_EVENTID, + WMI_BA_RSP_SSN_EVENTID, +@@ -1880,6 +1883,9 @@ enum wmi_tlv_tag { + 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_MAX + }; + +@@ -2107,7 +2113,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, ++ WMI_TLV_SERVICE_CONFIGURE_ROAM_TRIGGER_PARAM_SUPPORT = 254, ++ WMI_TLV_SERVICE_CFR_TA_RA_AS_FP_SUPPORT = 255, ++ WMI_TLV_SERVICE_CFR_CAPTURE_COUNT_SUPPORT = 256, ++ WMI_TLV_SERVICE_OCV_SUPPORT = 257, ++ WMI_TLV_SERVICE_LL_STATS_PER_CHAN_RX_TX_TIME_SUPPORT = 258, ++ WMI_TLV_SERVICE_THERMAL_MULTI_CLIENT_SUPPORT = 259, ++ WMI_TLV_SERVICE_NAN_SEND_NAN_ENABLE_RESPONSE_TO_HOST = 260, ++ WMI_TLV_SERVICE_UNIFIED_LL_GET_STA_CMD_SUPPORT = 261, ++ WMI_TLV_SERVICE_FSE_CMEM_ALLOC_SUPPORT = 262, + WMI_TLV_SERVICE_PASSIVE_SCAN_START_TIME_ENHANCE = 263, ++ WMI_TLV_SERVICE_QOS_NULL_FRAME_TX_OVER_WMI = 264, + + /* The second 128 bits */ + WMI_MAX_EXT_SERVICE = 256, +@@ -3814,6 +3830,7 @@ struct wmi_scan_prob_req_oui_cmd { + } __packed; + + #define WMI_MGMT_SEND_DOWNLD_LEN 64 ++#define WMI_QOS_NULL_SEND_BUF_LEN 64 + + #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 { + #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) +-#define WMI_TX_PARAMS_DWORD1_RSVD GENMASK(31, 21) ++#define WMI_TX_PARAMS_DWORD1_CFR_CAPTURE BIT(21) ++#define WMI_TX_PARAMS_DWORD1_RSVD GENMASK(31, 22) + +-struct wmi_mgmt_send_params { ++struct wmi_tx_send_params { + u32 tlv_header; + u32 tx_params_dword0; + u32 tx_params_dword1; +@@ -4570,8 +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 ppdu_id; +- u32 ack_rssi; + } __packed; + + #define WMI_VDEV_INSTALL_KEY_COMPL_STATUS_SUCCESS 0 +@@ -4919,7 +4935,7 @@ struct wmi_rssi_ctl_ext { + u32 rssi_ctl_ext[MAX_ANTENNA_EIGHT - ATH_MAX_ANTENNA]; + }; + +-struct wmi_mgmt_tx_compl_event { ++struct wmi_tx_compl_event { + u32 desc_id; + u32 status; + u32 pdev_id; +@@ -5750,6 +5766,17 @@ struct wmi_debug_log_config_cmd_fixed_pa + u32 value; + } __packed; + ++struct wmi_qos_null_tx_cmd { ++ u32 tlv_header; ++ u32 vdev_id; ++ u32 desc_id; ++ u32 paddr_lo; ++ u32 paddr_hi; ++ u32 frame_len; ++ u32 buf_len; ++ u32 tx_params_valid; ++} __packed; ++ + #define WMI_MAX_MEM_REQS 32 + + #define MAX_RADIOS 3 +@@ -6360,6 +6387,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); ++int ath11k_wmi_qos_null_send(struct ath11k *ar, u32 vdev_id, u32 buf_id, ++ struct sk_buff *frame); + int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id, + struct ieee80211_mutable_offsets *offs, + struct sk_buff *bcn, u32 ema_param); diff --git a/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch b/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch new file mode 100644 index 00000000000000..cd8a57385f9542 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch @@ -0,0 +1,856 @@ +From 30f54666ae15128f26fbad787a35253885a10513 Mon Sep 17 00:00:00 2001 +From: Ramya Gnanasekar +Date: Fri, 25 Dec 2020 16:11:06 +0530 +Subject: [PATCH] ath11k: Disable rx_header tlv for 2K SKB + +On low memory platform hdr_status in hal_rx_desc is not subscribed to +get a savings of 128bytes in skb. This is required to reduce the skb +size from 4K to 2K. Use HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG message +to unsubscribe rx_pkt_header tlv for rxdma ring. + +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 + } + + ar->debug.rx_filter = tlv_filter.rx_filter; ++ tlv_filter.offset_valid = false; + + 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 + } + + /* Clear rx filter set for monitor mode and rx status */ ++ tlv_filter.offset_valid = false; + 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, ar->dp.mac_id, +--- a/drivers/net/wireless/ath/ath11k/dp.h ++++ b/drivers/net/wireless/ath/ath11k/dp.h +@@ -609,7 +609,7 @@ enum htt_ppdu_stats_tag_type { + * + * |31 26|25|24|23 16|15 8|7 0| + * |-----------------+----------------+----------------+---------------| +- * | rsvd1 |PS|SS| ring_id | pdev_id | msg_type | ++ * | rsvd1|OV|PS|SS| ring_id | pdev_id | msg_type | + * |-------------------------------------------------------------------| + * | rsvd2 | ring_buffer_size | + * |-------------------------------------------------------------------| +@@ -623,6 +623,14 @@ enum htt_ppdu_stats_tag_type { + * |-------------------------------------------------------------------| + * | tlv_filter_in_flags | + * |-------------------------------------------------------------------| ++ * | rx_header_offset | rx_packet_offset | ++ * |-------------------------------------------------------------------| ++ * | rx_mpdu_start_offset | rx_mpdu_end_offset | ++ * |-------------------------------------------------------------------| ++ * | rx_msdu_start_offset | rx_msdu_end_offset | ++ * |-------------------------------------------------------------------| ++ * | rsvd3 | rx_attention_offset | ++ * |-------------------------------------------------------------------| + * Where: + * PS = pkt_swap + * SS = status_swap +@@ -636,6 +644,9 @@ enum htt_ppdu_stats_tag_type { + * 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 - rx_offset_valid (OV): flag to indicate rx offsets ++ * configuration fields are valid ++ * + * b'26: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 +676,42 @@ enum htt_ppdu_stats_tag_type { + * dword6 - b'0:31 - tlv_filter_in_flags: + * Filter in Attention/MPDU/PPDU/Header/User tlvs + * Refer to CFG_TLV_FILTER_IN_FLAG defs ++ * dword7 - b'0:15 - rx_packet_offset: rx_packet_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_1 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * - b'16:31 - rx_header_offset: rx_header_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_1 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * dword8 - b'0:15 - rx_mpdu_end_offset: rx_mpdu_end_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_2 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * - b'16:31 - rx_mpdu_start_offset: rx_mpdu_start_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_2 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * dword9 - b'0:15 - rx_msdu_end_offset: rx_msdu_end_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_3 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * - b'16:31 - rx_msdu_start_offset: rx_msdu_start_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_3 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * dword10- b'0:15 - rx_attention_offset: rx_attention_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_4 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * - b'16:31 - rsvd3 for future use + */ + + #define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) +@@ -672,8 +719,16 @@ enum htt_ppdu_stats_tag_type { + #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) ++#define HTT_RX_RING_SELECTION_CFG_CMD_OFFSET_VALID BIT(26) + + #define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE GENMASK(15, 0) ++#define HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET GENMASK(15, 0) ++#define HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET GENMASK(31, 16) ++#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET GENMASK(15, 0) ++#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET GENMASK(31, 16) ++#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET GENMASK(15, 0) ++#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET GENMASK(31, 16) ++#define HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET GENMASK(15, 0) + + enum htt_rx_filter_tlv_flags { + HTT_RX_FILTER_TLV_FLAGS_MPDU_START = BIT(0), +@@ -977,6 +1032,14 @@ enum htt_rx_data_pkt_filter_tlv_flasg3 { + HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER | \ + HTT_RX_FILTER_TLV_FLAGS_ATTENTION) + ++#define HTT_RX_RXDMA_FILTER_TLV_FLAGS_BUF_RING \ ++ (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ ++ HTT_RX_FILTER_TLV_FLAGS_MSDU_START | \ ++ HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \ ++ HTT_RX_FILTER_TLV_FLAGS_MSDU_END | \ ++ HTT_RX_FILTER_TLV_FLAGS_MPDU_END | \ ++ HTT_RX_FILTER_TLV_FLAGS_ATTENTION) ++ + struct htt_rx_ring_selection_cfg_cmd { + u32 info0; + u32 info1; +@@ -985,6 +1048,10 @@ struct htt_rx_ring_selection_cfg_cmd { + u32 pkt_type_en_flags2; + u32 pkt_type_en_flags3; + u32 rx_filter_tlv; ++ u32 rx_packet_offset; ++ u32 rx_mpdu_offset; ++ u32 rx_msdu_offset; ++ u32 rx_attn_offset; + } __packed; + + struct htt_rx_ring_tlv_filter { +@@ -993,6 +1060,14 @@ struct htt_rx_ring_tlv_filter { + u32 pkt_filter_flags1; /* MGMT */ + u32 pkt_filter_flags2; /* CTRL */ + u32 pkt_filter_flags3; /* DATA */ ++ bool offset_valid; ++ u16 rx_packet_offset; ++ u16 rx_header_offset; ++ u16 rx_mpdu_end_offset; ++ u16 rx_mpdu_start_offset; ++ u16 rx_msdu_end_offset; ++ u16 rx_msdu_start_offset; ++ u16 rx_attn_offset; + }; + + #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 + return ab->hw_params.hw_ops->rx_desc_get_mpdu_fc_valid(desc); + } + ++static u16 ath11k_dp_rxdesc_get_mpdu_frame_ctrl(struct ath11k_base *ab, ++ struct hal_rx_desc *desc) ++{ ++ return ab->hw_params.hw_ops->rx_desc_get_mpdu_frame_ctl(desc); ++} ++ + 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 + return ab->hw_params.hw_ops->rx_desc_mpdu_start_addr2(desc); + } + ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M ++static void ath11k_dp_get_rx_header_offset(struct ath11k_base *ab, ++ struct htt_rx_ring_tlv_filter *tlv_filter) ++{ ++ ab->hw_params.hw_ops->rx_desc_get_offset(tlv_filter); ++} ++#endif ++ ++static bool ath11k_dp_rx_desc_dot11_hdr_fields_valid(struct ath11k_base *ab, ++ struct hal_rx_desc *desc) ++{ ++ return ab->hw_params.hw_ops->rx_desc_dot11_hdr_fields_valid(desc); ++} ++ ++static void ath11k_dp_rx_desc_get_dot11_hdr(struct ath11k_base *ab, ++ struct hal_rx_desc *desc, ++ struct ieee80211_hdr *hdr) ++{ ++ ab->hw_params.hw_ops->rx_desc_get_dot11_hdr(desc, hdr); ++} ++ ++static void ath11k_dp_rx_desc_get_crypto_header(struct ath11k_base *ab, ++ struct hal_rx_desc *desc, ++ u8 *crypto_hdr, ++ enum hal_encrypt_type enctype) ++{ ++ ab->hw_params.hw_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); ++} ++ + 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 + return 0; + } + ++static void ath11k_get_dot11_hdr_from_rx_desc(struct ath11k *ar, ++ struct sk_buff *msdu, ++ struct ath11k_skb_rxcb *rxcb, ++ struct ieee80211_rx_status *status, ++ enum hal_encrypt_type enctype) ++{ ++ struct hal_rx_desc *rx_desc = rxcb->rx_desc; ++ struct ath11k_base *ab = ar->ab; ++ size_t hdr_len, crypto_len; ++ struct ieee80211_hdr *hdr; ++ u16 fc, qos_ctl = 0; ++ u8 *crypto_hdr; ++ ++ if (!(status->flag & RX_FLAG_IV_STRIPPED)) { ++ crypto_len = ath11k_dp_rx_crypto_param_len(ar, enctype); ++ crypto_hdr = skb_push(msdu, crypto_len); ++ ath11k_dp_rx_desc_get_crypto_header(ab, rx_desc, crypto_hdr, enctype); ++ } ++ ++ fc = ath11k_dp_rxdesc_get_mpdu_frame_ctrl(ab, rx_desc); ++ hdr_len = ieee80211_hdrlen(fc); ++ skb_push(msdu, hdr_len); ++ hdr = (struct ieee80211_hdr *)msdu->data; ++ hdr->frame_control = fc; ++ ++ /* Get wifi header from rx_desc */ ++ ath11k_dp_rx_desc_get_dot11_hdr(ab, rx_desc, hdr); ++ ++ if (rxcb->is_mcbc) ++ status->flag &= ~RX_FLAG_PN_VALIDATED; ++ ++ /* Add QOS header */ ++ if (ieee80211_is_data_qos(hdr->frame_control)) { ++ qos_ctl = rxcb->tid; ++ if (ath11k_dp_rx_h_msdu_start_mesh_ctl_present(ab, rx_desc)) ++ qos_ctl |= IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT; ++ ++ /* TODO Add other QoS ctl fields when required */ ++ memcpy(msdu->data + (hdr_len - IEEE80211_QOS_CTL_LEN), ++ &qos_ctl, IEEE80211_QOS_CTL_LEN); ++ } ++} ++ + 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 + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + u16 qos_ctl = 0; +- u8 *qos; ++ u8 *qos, *crypto_hdr; ++ bool add_qos_ctrl = false; + + /* 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 + ether_addr_copy(sa, ieee80211_get_SA(hdr)); + skb_pull(msdu, ieee80211_hdrlen(hdr->frame_control)); + +- if (rxcb->is_first_msdu) { ++ if (rxcb->is_first_msdu && first_hdr) { + /* 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 + + /* copy decap header before overwriting for reuse below */ + memcpy(decap_hdr, (uint8_t *)hdr, hdr_len); ++ add_qos_ctrl = true; + } + + 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)); ++ if (first_hdr) { ++ memcpy(skb_push(msdu, ++ ath11k_dp_rx_crypto_param_len(ar, enctype)), ++ (void *)hdr + hdr_len, ++ ath11k_dp_rx_crypto_param_len(ar, enctype)); ++ } else { ++ crypto_hdr = skb_push(msdu, ath11k_dp_rx_crypto_param_len(ar, enctype)); ++ ath11k_dp_rx_desc_get_crypto_header(ar->ab, ++ rxcb->rx_desc, crypto_hdr, enctype); ++ } + } + +- if (!rxcb->is_first_msdu) { ++ if (!rxcb->is_first_msdu || add_qos_ctrl) { + 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 + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + void *rfc1042; ++ struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); ++ struct ath11k_dp_rfc1042_hdr rfc = {0xaa, 0xaa, 0x03, {0x00, 0x00, 0x00}}; ++ ++ if (!first_hdr) { ++ eth = (struct ethhdr *)msdu->data; ++ ether_addr_copy(da, eth->h_dest); ++ ether_addr_copy(sa, eth->h_source); ++ rfc.snap_type = eth->h_proto; ++ skb_pull(msdu, sizeof(struct ethhdr)); ++ 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); ++ goto exit; ++ } + + 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 + + memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); + ++exit: + /* 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( + size_t hdr_len; + u8 l3_pad_bytes; + struct hal_rx_desc *rx_desc; ++ struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); + + /* Delivered decapped frame: + * [amsdu header] <-- replaced with 802.11 hdr +@@ -2212,6 +2314,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); + ++ if (!first_hdr) { ++ ath11k_get_dot11_hdr_from_rx_desc(ar, msdu, rxcb, status, enctype); ++ return; ++ } ++ + 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 + goto free_out; + } + ++ hdr_status = ath11k_dp_rx_h_80211_hdr(ab, rx_desc); ++ /* wifi hdr fields validation for 512M:: ++ * Mcast packets in ethernet frame mode ++ * will need wifi hdr in msdu to validate PN. ++ * Header will be added in undecap routine. ++ * Validation on wifi hdr fields from rx_desc. ++ */ ++ if (!hdr_status && ath11k_dp_rx_h_attn_is_mcbc(ab, rx_desc) && ++ !ath11k_dp_rx_desc_dot11_hdr_fields_valid(ab, rx_desc)) { ++ ath11k_warn(ab, "One or more invalid dot11 header fields\n"); ++ ret = -EIO; ++ goto free_out; ++ } ++ + 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 + hdr_status = ath11k_dp_rx_h_80211_hdr(ab, rx_desc); + ret = -EINVAL; + ath11k_warn(ab, "invalid msdu len %u\n", msdu_len); +- ath11k_dbg_dump(ab, ATH11K_DBG_DATA, NULL, "", hdr_status, +- sizeof(struct ieee80211_hdr)); ++ if (hdr_status) ++ ath11k_dbg_dump(ab, ATH11K_DBG_DATA, NULL, "", hdr_status, ++ sizeof(struct ieee80211_hdr)); + 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 + + hdr = (struct ieee80211_hdr *)(msdu->data + hal_rx_desc_sz); + hdr_len = ieee80211_hdrlen(hdr->frame_control); ++ + 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 + + static u64 ath11k_dp_rx_h_get_pn(struct ath11k *ar, struct sk_buff *skb) + { +- struct ieee80211_hdr *hdr; + u64 pn = 0; ++ struct ieee80211_hdr *hdr; + 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 + 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); +- ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", hdr_status, +- sizeof(struct ieee80211_hdr)); ++ if (hdr_status) ++ ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", hdr_status, ++ sizeof(struct ieee80211_hdr)); + 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 + ath11k_dp_rxdma_pdev_buf_free(ar); + } + ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M ++static int ath11k_dp_rxdma_ring_sel_config(struct ath11k *ar) ++{ ++ struct ath11k_pdev_dp *dp = &ar->dp; ++ struct htt_rx_ring_tlv_filter tlv_filter = {0}; ++ u32 ring_id; ++ int ret; ++ u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; ++ ++ ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id; ++ ++ tlv_filter.rx_filter = HTT_RX_RXDMA_FILTER_TLV_FLAGS_BUF_RING; ++ tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR; ++ tlv_filter.pkt_filter_flags3 = HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST | ++ HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST; ++ tlv_filter.offset_valid = true; ++ tlv_filter.rx_packet_offset = hal_rx_desc_sz; ++ tlv_filter.rx_header_offset = 0; ++ ++ ath11k_dp_get_rx_header_offset(ar->ab, &tlv_filter); ++ ++ if (!ar->ab->nss.enabled) ++ ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, dp->mac_id, ++ HAL_RXDMA_BUF, ++ DP_RXDMA_REFILL_RING_SIZE, ++ &tlv_filter); ++ else ++ ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, dp->mac_id, ++ HAL_RXDMA_BUF, ++ DP_RXDMA_NSS_REFILL_RING_SIZE, ++ &tlv_filter); ++ ++ return ret; ++} ++#else ++static int ath11k_dp_rxdma_ring_sel_config(struct ath11k *ar) ++{ ++ return 0; ++} ++#endif ++ + 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: + } + } + ++ ret = ath11k_dp_rxdma_ring_sel_config(ar); ++ if (ret) { ++ ath11k_warn(ab, "failed to setup rxdma ring selection config\n"); ++ return ret; ++ } ++ + return 0; + } + +--- 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 + !!(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)); ++ cmd->info0 |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_OFFSET_VALID, ++ tlv_filter->offset_valid); + + 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 + cmd->pkt_type_en_flags3 = tlv_filter->pkt_filter_flags3; + cmd->rx_filter_tlv = tlv_filter->rx_filter; + ++ if (tlv_filter->offset_valid) { ++ cmd->rx_packet_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET, ++ tlv_filter->rx_packet_offset); ++ cmd->rx_packet_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET, ++ tlv_filter->rx_header_offset); ++ ++ cmd->rx_mpdu_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET, ++ tlv_filter->rx_mpdu_end_offset); ++ cmd->rx_mpdu_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET, ++ tlv_filter->rx_mpdu_start_offset); ++ ++ cmd->rx_msdu_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET, ++ tlv_filter->rx_msdu_end_offset); ++ cmd->rx_msdu_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET, ++ tlv_filter->rx_msdu_start_offset); ++ ++ cmd->rx_attn_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET, ++ tlv_filter->rx_attn_offset); ++ } ++ + 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 + } + + ring_id = dp->rxdma_mon_buf_ring.refill_buf_ring.ring_id; ++ tlv_filter.offset_valid = false; + + if (!reset) { + tlv_filter.rx_filter = HTT_RX_MON_FILTER_TLV_FLAGS_MON_BUF_RING; +--- a/drivers/net/wireless/ath/ath11k/hw.c ++++ b/drivers/net/wireless/ath/ath11k/hw.c +@@ -260,7 +260,11 @@ static u8 ath11k_hw_ipq8074_rx_desc_get_ + + static u8 *ath11k_hw_ipq8074_rx_desc_get_hdr_status(struct hal_rx_desc *desc) + { ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + return desc->u.ipq8074.hdr_status; ++#else ++ return NULL; ++#endif + } + + 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 + desc->u.ipq8074.msdu_start.info1 = __cpu_to_le32(info); + } + ++static ++struct rx_attention *ath11k_hw_ipq8074_rx_desc_get_attention(struct hal_rx_desc *desc) ++{ ++ return &desc->u.ipq8074.attention; ++} ++ ++static u8 *ath11k_hw_ipq8074_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) ++{ ++ return &desc->u.ipq8074.msdu_payload[0]; ++} ++ ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M ++static void ath11k_hw_ipq8074_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_ipq8074, mpdu_end_tag)); ++ tlv_filter->rx_mpdu_start_offset = __le16_to_cpu(offsetof ++ (struct hal_rx_desc_ipq8074, mpdu_start_tag)); ++ tlv_filter->rx_msdu_end_offset = __le16_to_cpu(offsetof ++ (struct hal_rx_desc_ipq8074, msdu_end_tag)); ++ tlv_filter->rx_msdu_start_offset = __le16_to_cpu(offsetof ++ (struct hal_rx_desc_ipq8074, msdu_start_tag)); ++ tlv_filter->rx_attn_offset = __le16_to_cpu(offsetof ++ (struct hal_rx_desc_ipq8074, rx_attn_tag)); ++} ++#endif ++ ++static u16 ath11k_hw_ipq8074_rx_desc_get_mpdu_frame_ctl(struct hal_rx_desc *desc) ++{ ++ return __le16_to_cpu(desc->u.ipq8074.mpdu_start.frame_ctrl); ++} ++ + static bool ath11k_hw_ipq8074_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) + { + return __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & + RX_MPDU_START_INFO1_MAC_ADDR2_VALID; + } + +-static u8 *ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) ++static u8* ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) + { + return desc->u.ipq8074.mpdu_start.addr2; + } + +-static +-struct rx_attention *ath11k_hw_ipq8074_rx_desc_get_attention(struct hal_rx_desc *desc) ++static bool ath11k_hw_ipq8074_rx_desc_dot11_hdr_fields_valid(struct hal_rx_desc *desc) + { +- return &desc->u.ipq8074.attention; ++ if ((ath11k_hw_ipq8074_rx_desc_get_mpdu_seq_ctl_vld(desc) && ++ ath11k_hw_ipq8074_rx_desc_get_mpdu_fc_valid(desc) && ++ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & ++ RX_MPDU_START_INFO1_MAC_ADDR1_VALID && ++ ath11k_hw_ipq8074_rx_desc_mac_addr2_valid(desc) && ++ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & ++ RX_MPDU_START_INFO1_MAC_ADDR3_VALID && ++ FIELD_GET((RX_MPDU_START_INFO1_MPDU_DUR_VALID), ++ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1)))) { ++ return true; ++ } ++ return false; ++} ++ ++static void ath11k_hw_ipq8074_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, ++ struct ieee80211_hdr *hdr) ++{ ++ hdr->frame_control = __le16_to_cpu(desc->u.ipq8074.mpdu_start.frame_ctrl); ++ hdr->duration_id = __le16_to_cpu(desc->u.ipq8074.mpdu_start.duration); ++ ether_addr_copy(hdr->addr1, desc->u.ipq8074.mpdu_start.addr1); ++ ether_addr_copy(hdr->addr2, desc->u.ipq8074.mpdu_start.addr2); ++ ether_addr_copy(hdr->addr3, desc->u.ipq8074.mpdu_start.addr3); ++ if (__le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & ++ RX_MPDU_START_INFO1_MAC_ADDR4_VALID) { ++ ether_addr_copy(hdr->addr4, desc->u.ipq8074.mpdu_start.addr4); ++ } ++ hdr->seq_ctrl = __le16_to_cpu(desc->u.ipq8074.mpdu_start.seq_ctrl); ++} ++ ++static void ath11k_hw_ipq8074_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.ipq8074.mpdu_start.pn[0]); ++ crypto_hdr[1] = 0; ++ crypto_hdr[2] = ++ HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.ipq8074.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.ipq8074.mpdu_start.pn[0]); ++ crypto_hdr[1] = ++ HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.ipq8074.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_INFO5_KEY_ID, ++ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info5)); ++ crypto_hdr[3] = 0x20 | (key_id << 6); ++ crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.ipq8074.mpdu_start.pn[0]); ++ crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.ipq8074.mpdu_start.pn[0]); ++ crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.ipq8074.mpdu_start.pn[1]); ++ crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.ipq8074.mpdu_start.pn[1]); + } + +-static u8 *ath11k_hw_ipq8074_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) ++static bool ath11k_hw_qcn9074_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) + { +- return &desc->u.ipq8074.msdu_payload[0]; ++ return __le32_to_cpu(desc->u.qcn9074.mpdu_start.info11) & ++ RX_MPDU_START_INFO11_MAC_ADDR2_VALID; ++} ++ ++static u8* ath11k_hw_qcn9074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) ++{ ++ return desc->u.qcn9074.mpdu_start.addr2; + } + + 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_ + + static u8 *ath11k_hw_qcn9074_rx_desc_get_hdr_status(struct hal_rx_desc *desc) + { ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + return desc->u.qcn9074.hdr_status; ++#else ++ return NULL; ++#endif + } + + 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_ + + static u8 *ath11k_hw_wcn6855_rx_desc_get_hdr_status(struct hal_rx_desc *desc) + { ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + return desc->u.wcn6855.hdr_status; ++#else ++ return NULL; ++#endif + } + + 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, + .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2, + .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, ++#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 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 = + .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, + .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, + }; + +--- a/drivers/net/wireless/ath/ath11k/hw.h ++++ b/drivers/net/wireless/ath/ath11k/hw.h +@@ -129,6 +129,8 @@ 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]; +@@ -285,6 +287,16 @@ 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); ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M ++ void (*rx_desc_get_offset)(struct htt_rx_ring_tlv_filter *tlv_filter); ++#endif ++ u16 (*rx_desc_get_mpdu_frame_ctl)(struct hal_rx_desc *desc); ++ bool (*rx_desc_dot11_hdr_fields_valid)(struct hal_rx_desc *desc); ++ void (*rx_desc_get_dot11_hdr)(struct hal_rx_desc *desc, ++ struct ieee80211_hdr *hdr); ++ void (*rx_desc_get_crypto_header)(struct hal_rx_desc *desc, ++ u8 *crypto_hdr, ++ enum hal_encrypt_type enctype); + }; + + 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); +@@ -6336,6 +6336,7 @@ static int ath11k_mac_config_mon_status_ + tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar); + } + ++ tlv_filter.offset_valid = false; + 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, +@@ -9766,8 +9767,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 { + __le32 mpdu_end_tag; + struct rx_mpdu_end mpdu_end; + u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES]; ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + __le32 hdr_status_tag; + __le32 phy_ppdu_id; + u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN]; ++#endif + u8 msdu_payload[]; + } __packed; + +@@ -1461,9 +1463,11 @@ struct hal_rx_desc_qcn9074 { + __le32 mpdu_end_tag; + struct rx_mpdu_end mpdu_end; + u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES]; ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + __le32 hdr_status_tag; + __le32 phy_ppdu_id; + u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN]; ++#endif + u8 msdu_payload[]; + } __packed; + +@@ -1480,9 +1484,11 @@ struct hal_rx_desc_wcn6855 { + __le32 mpdu_end_tag; + struct rx_mpdu_end mpdu_end; + u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES]; ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + __le32 hdr_status_tag; + __le32 phy_ppdu_id; + u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN]; ++#endif + u8 msdu_payload[]; + } __packed; + +@@ -1502,4 +1508,17 @@ struct hal_rx_desc { + #define RU_484 18 + #define RU_996 37 + ++#define HAL_RX_MPDU_INFO_PN_GET_BYTE1(__val) \ ++ FIELD_GET(GENMASK(7, 0), __le32_to_cpu(__val)) ++ ++#define HAL_RX_MPDU_INFO_PN_GET_BYTE2(__val) \ ++ FIELD_GET(GENMASK(15, 8), __le32_to_cpu(__val)) ++ ++#define HAL_RX_MPDU_INFO_PN_GET_BYTE3(__val) \ ++ FIELD_GET(GENMASK(23, 16), __le32_to_cpu(__val)) ++ ++#define HAL_RX_MPDU_INFO_PN_GET_BYTE4(__val) \ ++ FIELD_GET(GENMASK(31, 24), __le32_to_cpu(__val)) ++ ++ + #endif /* ATH11K_RX_DESC_H */ diff --git a/package/kernel/mac80211/patches/ath11k_nss/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch b/package/kernel/mac80211/patches/ath11k_nss/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch new file mode 100644 index 00000000000000..56dbf2a0371b31 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch @@ -0,0 +1,109 @@ +From 246e530a47d9adab9106fb6f2b92197cace17e53 Mon Sep 17 00:00:00 2001 +From: Seevalamuthu Mariappan +Date: Fri, 21 May 2021 14:16:22 +0530 +Subject: [PATCH] ath11k: configure nss radio priority during pdev_init + +pdev's priority value is read from dts. Get scheme_id +using pdev priority. Configure scheme_id during pdev_init. + +Signed-off-by: Seevalamuthu Mariappan +--- + drivers/net/wireless/ath/ath11k/nss.c | 20 +++++++++++++++++++- + drivers/net/wireless/ath/ath11k/nss.h | 3 +++ + 2 files changed, 22 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath11k/nss.c ++++ b/drivers/net/wireless/ath/ath11k/nss.c +@@ -2,6 +2,7 @@ + /* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + */ ++#include + + #include "debug.h" + #include "mac.h" +@@ -1782,6 +1783,7 @@ static int ath11k_nss_init(struct ath11k + nss_tx_status_t status; + struct ath11k_dp *dp; + int i, ret; ++ struct device *dev = ab->dev; + + dp = &ab->dp; + +@@ -1801,6 +1803,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_RX_BUFFER_SIZE; ++ if (of_property_read_bool(dev->of_node, "nss-radio-priority")) ++ wim->flags |= WIFILI_MULTISOC_THREAD_MAP_ENABLE; + + /* 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 + struct nss_wifili_msg *wlmsg = NULL; + nss_wifili_msg_callback_t msg_cb; + nss_tx_status_t status; ++ struct device *dev = ab->dev; + int radio_if_num = -1; + int refill_ring_id; + int features = 0; + int dyn_if_type; +- int ret, i; ++ int ret, i, scheme_id = 0; ++ u32 nss_radio_priority; + + dyn_if_type = ath11k_nss_get_dynamic_interface_type(ab); + +@@ -2010,6 +2016,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); + ++ if (!of_property_read_u32(dev->of_node, "nss-radio-priority", &nss_radio_priority)) { ++ scheme_id = nss_wifili_thread_scheme_alloc(ab->nss.ctx, ar->nss.if_num, nss_radio_priority); ++ if (scheme_id == WIFILI_SCHEME_ID_INVALID) { ++ ath11k_warn(ab, "received invalid scheme_id, configuring default value\n"); ++ scheme_id = 0; ++ } ++ } ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "ifnum: %d scheme_id: %d nss_radio_priority: %d\n", ar->nss.if_num, scheme_id, nss_radio_priority); ++ + 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 + 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; ++ pdevmsg->scheme_id = scheme_id; + + /* 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 + /* pdev deinit msg success, dealloc, deregister and return */ + ret = 0; + ++ /* reset thread scheme*/ ++ nss_wifili_thread_scheme_dealloc(ab->nss.ctx, ar->nss.if_num); ++ + nss_dynamic_interface_dealloc_node(ar->nss.if_num, dyn_if_type); + nss_unregister_wifili_radio_if(ar->nss.if_num); + 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; + /* Init Flags */ + #define WIFILI_NSS_CCE_DISABLED 0x1 + #define WIFILI_ADDTL_MEM_SEG_SET 0x000000002 ++#define WIFILI_MULTISOC_THREAD_MAP_ENABLE 0x10 + + /* 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, + }; + ++#define WIFILI_SCHEME_ID_INVALID -1 ++ + enum ath11k_nss_opmode { + ATH11K_NSS_OPMODE_UNKNOWN, + ATH11K_NSS_OPMODE_AP, diff --git a/package/kernel/mac80211/patches/ath11k_nss/318-ath11k-avoid-stack-corrupt-in-nwifi-undecap.patch b/package/kernel/mac80211/patches/ath11k_nss/318-ath11k-avoid-stack-corrupt-in-nwifi-undecap.patch new file mode 100644 index 00000000000000..9189729b77f595 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/318-ath11k-avoid-stack-corrupt-in-nwifi-undecap.patch @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/ath/ath11k/dp_rx.h ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.h +@@ -9,7 +9,7 @@ + #include "rx_desc.h" + #include "debug.h" + +-#define DP_MAX_NWIFI_HDR_LEN 30 ++#define DP_MAX_NWIFI_HDR_LEN 36 + + #define DP_RX_MPDU_ERR_FCS BIT(0) + #define DP_RX_MPDU_ERR_DECRYPT BIT(1) 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/ath11k_nss/319-ath11k-fix-double-free-of-peer-rx_tid-during-reo-cmd.patch new file mode 100644 index 00000000000000..0dd8dcba9ec152 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/319-ath11k-fix-double-free-of-peer-rx_tid-during-reo-cmd.patch @@ -0,0 +1,40 @@ +From 210b20357989ace8bb5c861b37e25b6c986c816d Mon Sep 17 00:00:00 2001 +From: Sathishkumar Muruganandam +Date: Thu, 1 Jul 2021 13:08:54 +0530 +Subject: [PATCH] ath11k: fix double free of peer rx_tid during reo cmd failure + +Peer rx_tid is locally copied thrice during peer_rx_tid_cleanup to send +REO_CMD_UPDATE_RX_QUEUE followed by REO_CMD_FLUSH_CACHE to flush all +aged REO descriptors from HW cache. + +When sending REO_CMD_FLUSH_CACHE fails, we do dma unmap of already +mapped rx_tid->vaddr and free it. This is not checked during +reo_cmd_list_cleanup() and dp_reo_cmd_free() before trying to free and +unmap again. + +Fix this by setting rx_tid->vaddr NULL in rx tid delete and also wherever +freeing it to check in reo_cmd_list_cleanup() and reo_cmd_free() before +trying to free again. + +Prevent REO cmd failures causing double free by increasing REO cmd +ring size and moving REO status ring mask to IRQ group 3 from group +0 to separate from tx completion ring on IRQ group 0 which may delay +reo status processing. + +Signed-off-by: Sathishkumar Muruganandam +--- + drivers/net/wireless/ath/ath11k/dp.h | 2 +- + drivers/net/wireless/ath/ath11k/dp_rx.c | 66 ++++++++++++++++++------- + drivers/net/wireless/ath/ath11k/hw.c | 1 + + 3 files changed, 49 insertions(+), 20 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/hw.c ++++ b/drivers/net/wireless/ath/ath11k/hw.c +@@ -1418,6 +1418,7 @@ const struct ath11k_hw_ring_mask ath11k_ + ATH11K_RX_WBM_REL_RING_MASK_0, + }, + .reo_status = { ++ 0, 0, 0, + ATH11K_REO_STATUS_RING_MASK_0, + }, + .rxdma2host = { diff --git a/package/kernel/mac80211/patches/ath11k_nss/319-ath11k-nss-2K-SKB.patch b/package/kernel/mac80211/patches/ath11k_nss/319-ath11k-nss-2K-SKB.patch new file mode 100644 index 00000000000000..8c235ae04de09a --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/319-ath11k-nss-2K-SKB.patch @@ -0,0 +1,37 @@ +From 30f54666ae15128f26fbad787a35253885a10513 Mon Sep 17 00:00:00 2001 +From: Ramya Gnanasekar +Date: Fri, 25 Dec 2020 16:11:06 +0530 +Subject: [PATCH] ath11k: Disable rx_header tlv for 2K SKB + +On low memory platform hdr_status in hal_rx_desc is not subscribed to +get a savings of 128bytes in skb. This is required to reduce the skb +size from 4K to 2K. Use HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG message +to unsubscribe rx_pkt_header tlv for rxdma ring. + +Signed-off-by: Ramya Gnanasekar + +--- a/drivers/net/wireless/ath/ath11k/dp.h ++++ b/drivers/net/wireless/ath/ath11k/dp.h +@@ -220,6 +220,11 @@ struct ath11k_pdev_dp { + #define DP_REO_STATUS_RING_SIZE 2048 + #define DP_RXDMA_BUF_RING_SIZE 4096 + #define DP_RXDMA_REFILL_RING_SIZE 2048 ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512MB ++#define DP_RXDMA_NSS_REFILL_RING_SIZE 1816 ++#else ++#define DP_RXDMA_NSS_REFILL_RING_SIZE 2048 ++#endif + #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 +--- a/drivers/net/wireless/ath/ath11k/nss.c ++++ b/drivers/net/wireless/ath/ath11k/nss.c +@@ -1802,7 +1802,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; +- wim->wrip.rx_buf_len = DP_RX_BUFFER_SIZE; ++ wim->wrip.rx_buf_len = DP_RXDMA_NSS_REFILL_RING_SIZE; + if (of_property_read_bool(dev->of_node, "nss-radio-priority")) + wim->flags |= WIFILI_MULTISOC_THREAD_MAP_ENABLE; + diff --git a/package/kernel/mac80211/patches/ath11k_nss/336-ath11k-skip-status-ring-entry-processing.patch b/package/kernel/mac80211/patches/ath11k_nss/336-ath11k-skip-status-ring-entry-processing.patch new file mode 100644 index 00000000000000..4ed84ffa3e21d4 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/336-ath11k-skip-status-ring-entry-processing.patch @@ -0,0 +1,191 @@ +From 0e79fe8c6937e080816230892d5382af5a5a86c6 Mon Sep 17 00:00:00 2001 +From: Venkateswara Naralasetty +Date: Mon, 29 Nov 2021 11:07:53 +0530 +Subject: [PATCH] ath11k: skip status ring entry processing + +If STATUS_BUFFER_DONE is not set for a monitor status ring entry, +we don't process the status ring until STATUS_BUFFER_DONE set +for that status ring entry. + +During LMAC reset it may happnen that HW will not write +STATUS_BUFFER_DONE tlv in status buffer, in that case we end up +waiting for STATUS_BUFFER_DONE leading to backpressure on monitor +status ring. + +As per MAC team's suggestion, when HP + 1 entry is peeked and if DMA +is not done and if HP + 2 entry's DMA done is set, +replenish HP + 1 entry and start processing in next interrupt. +If HP + 2 entry's DMA done is not set, +poll onto HP + 1 entry DMA done to be set. + +Also, During monitor attach HP points to the end of the ring and TP +points to the start of the ring. Using ath11k_hal_srng_src_peek() +may result in processing invali buffer for the very first interrupt. +Since, HW starts writing buffer from TP. + +Hence, replaced ath11k_hal_srng_src_peek() with +ath11k_hal_srng_src_next_peek(). + +Signed-off-by: Venkateswara Naralasetty +--- + drivers/net/wireless/ath/ath11k/dp_rx.c | 92 ++++++++++++++++++++++++++++----- + drivers/net/wireless/ath/ath11k/hal.c | 30 +++++++++++ + drivers/net/wireless/ath/ath11k/hal.h | 4 ++ + 3 files changed, 113 insertions(+), 13 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -3168,6 +3168,46 @@ ath11k_dp_rx_mon_update_status_buf_state + } + } + ++enum dp_mon_status_buf_state ++dp_rx_mon_handle_status_buf_done(struct ath11k_base *ab, struct hal_srng *srng, ++ struct dp_rxdma_ring *rx_ring) ++{ ++ void *status_desc; ++ struct sk_buff *skb; ++ struct ath11k_skb_rxcb *rxcb; ++ struct hal_tlv_hdr *tlv; ++ dma_addr_t paddr; ++ u32 cookie; ++ int buf_id; ++ u8 rbm; ++ ++ status_desc = ath11k_hal_srng_src_next_peek(ab, srng); ++ if (!status_desc) ++ return DP_MON_STATUS_NO_DMA; ++ ++ ath11k_hal_rx_buf_addr_info_get(status_desc, &paddr, &cookie, &rbm); ++ ++ buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID, cookie); ++ ++ spin_lock_bh(&rx_ring->idr_lock); ++ skb = idr_find(&rx_ring->bufs_idr, buf_id); ++ spin_unlock_bh(&rx_ring->idr_lock); ++ ++ if (!skb) ++ return DP_MON_STATUS_NO_DMA; ++ ++ rxcb = ATH11K_SKB_RXCB(skb); ++ dma_sync_single_for_cpu(ab->dev, rxcb->paddr, ++ skb->len + skb_tailroom(skb), ++ DMA_FROM_DEVICE); ++ ++ tlv = (struct hal_tlv_hdr *)skb->data; ++ if (FIELD_GET(HAL_TLV_HDR_TAG, tlv->tl) != HAL_RX_STATUS_BUFFER_DONE) ++ return DP_MON_STATUS_NO_DMA; ++ ++ return DP_MON_STATUS_REPLINISH; ++} ++ + static int ath11k_dp_rx_reap_mon_status_ring(struct ath11k_base *ab, int mac_id, + int *budget, struct sk_buff_head *skb_list) + { +@@ -3181,6 +3221,7 @@ static int ath11k_dp_rx_reap_mon_status_ + struct sk_buff *skb; + struct ath11k_skb_rxcb *rxcb; + struct hal_tlv_hdr *tlv; ++ enum dp_mon_status_buf_state reap_status; + u32 cookie; + int buf_id, srng_id; + dma_addr_t paddr; +@@ -3200,8 +3241,7 @@ static int ath11k_dp_rx_reap_mon_status_ + ath11k_hal_srng_access_begin(ab, srng); + while (*budget) { + *budget -= 1; +- rx_mon_status_desc = +- ath11k_hal_srng_src_peek(ab, srng); ++ rx_mon_status_desc = ath11k_hal_srng_src_peek(ab, srng); + if (!rx_mon_status_desc) { + pmon->buf_state = DP_MON_STATUS_REPLINISH; + break; +@@ -3232,18 +3272,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) { +- ath11k_warn(ab, "mon status DONE not set %lx, buf_id %d\n", +- FIELD_GET(HAL_TLV_HDR_TAG, +- tlv->tl), buf_id); +- /* If done status is missing, hold onto status +- * ring until status is done for this status +- * ring buffer. +- * Keep HP in mon_status_ring unchanged, +- * and break from here. +- * Check status for same buffer for next time ++ /* RxDMA status done bit might not be set even ++ * though tp is moved by HW. + */ +- pmon->buf_state = DP_MON_STATUS_NO_DMA; +- break; ++ ++ /* If done status is missing: ++ * 1. As per MAC team's suggestion, ++ * when HP + 1 entry is peeked and if DMA ++ * is not done and if HP + 2 entry's DMA done ++ * is set. skip HP + 1 entry and ++ * start processing in next interrupt. ++ * 2. If HP + 2 entry's DMA done is not set, ++ * poll onto HP + 1 entry DMA done to be set. ++ * Check status for same buffer for next time ++ * dp_rx_mon_status_srng_process ++ */ ++ ++ reap_status = dp_rx_mon_handle_status_buf_done(ab, srng, ++ rx_ring); ++ if (reap_status == DP_MON_STATUS_NO_DMA) { ++ continue; ++ } else if (reap_status == DP_MON_STATUS_REPLINISH) { ++ ath11k_warn(ab, "mon status DONE not set %lx, buf_id %d\n", ++ FIELD_GET(HAL_TLV_HDR_TAG, tlv->tl), ++ buf_id); ++ ++ spin_lock_bh(&rx_ring->idr_lock); ++ idr_remove(&rx_ring->bufs_idr, buf_id); ++ spin_unlock_bh(&rx_ring->idr_lock); ++ ++ dma_unmap_single(ab->dev, rxcb->paddr, ++ skb->len + skb_tailroom(skb), ++ DMA_FROM_DEVICE); ++ ++ dev_kfree_skb_any(skb); ++ pmon->buf_state = DP_MON_STATUS_REPLINISH; ++ goto move_next; ++ } + } + + spin_lock_bh(&rx_ring->idr_lock); +--- a/drivers/net/wireless/ath/ath11k/hal.c ++++ b/drivers/net/wireless/ath/ath11k/hal.c +@@ -781,6 +781,20 @@ u32 *ath11k_hal_srng_src_get_next_reaped + return desc; + } + ++u32 *ath11k_hal_srng_src_next_peek(struct ath11k_base *ab, struct hal_srng *srng) ++{ ++ u32 next_hp; ++ ++ lockdep_assert_held(&srng->lock); ++ ++ next_hp = (srng->u.src_ring.hp + srng->entry_size) % srng->ring_size; ++ ++ if (next_hp != srng->u.src_ring.cached_tp) ++ return srng->ring_base_vaddr + next_hp; ++ ++ return NULL; ++} ++ + u32 *ath11k_hal_srng_src_peek(struct ath11k_base *ab, struct hal_srng *srng) + { + lockdep_assert_held(&srng->lock); +--- a/drivers/net/wireless/ath/ath11k/hal.h ++++ b/drivers/net/wireless/ath/ath11k/hal.h +@@ -948,6 +948,8 @@ u32 *ath11k_hal_srng_dst_peek(struct ath + int ath11k_hal_srng_dst_num_free(struct ath11k_base *ab, struct hal_srng *srng, + bool sync_hw_ptr); + u32 *ath11k_hal_srng_src_peek(struct ath11k_base *ab, struct hal_srng *srng); ++u32 *ath11k_hal_srng_src_next_peek(struct ath11k_base *ab, ++ struct hal_srng *srng); + u32 *ath11k_hal_srng_src_get_next_reaped(struct ath11k_base *ab, + struct hal_srng *srng); + u32 *ath11k_hal_srng_src_reap_next(struct ath11k_base *ab, 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/ath11k_nss/342-ath11k-provide-access-of-the-dma-buffer-back-to-dma-.patch new file mode 100644 index 00000000000000..db779080b71f96 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/342-ath11k-provide-access-of-the-dma-buffer-back-to-dma-.patch @@ -0,0 +1,28 @@ +From a12157095a8a59eeaeb7c9efe70495288140159c Mon Sep 17 00:00:00 2001 +From: Hari Chandrakanthan +Date: Mon, 10 Jan 2022 12:38:10 +0530 +Subject: [PATCH] ath11k: provide access of the dma buffer back to dma device + +In ath11k_dbring_bufs_replenish, after accessing paddr which is a member of +ath11k_dbring_element, provide the access of the buffer back to +dma device by using dma_sync_single_for_device. + +Also the gfp flag to used inside ath11k_dbring_fill_bufs is changed +from GFP_KERNEL to GFP_ATOMIC as the buffers are allocated inside spin lock. + +Signed-off-by: Hari Chandrakanthan +--- + drivers/net/wireless/ath/ath11k/dbring.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath11k/dbring.c ++++ b/drivers/net/wireless/ath/ath11k/dbring.c +@@ -80,6 +80,8 @@ static int ath11k_dbring_bufs_replenish( + + buff->paddr = paddr; + ++ dma_sync_single_for_device(ab->dev, paddr, ring->buf_sz, DMA_FROM_DEVICE); ++ + cookie = FIELD_PREP(DP_RXDMA_BUF_COOKIE_PDEV_ID, ar->pdev_idx) | + FIELD_PREP(DP_RXDMA_BUF_COOKIE_BUF_ID, buf_id); + diff --git a/package/kernel/mac80211/patches/ath11k_nss/999-fix-build.patch b/package/kernel/mac80211/patches/ath11k_nss/999-fix-build.patch new file mode 100644 index 00000000000000..9993d3f03fb572 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/999-fix-build.patch @@ -0,0 +1,237 @@ +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -2299,6 +2299,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); + +@@ -2323,12 +2324,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); + } + +@@ -2358,7 +2369,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); +@@ -2418,7 +2430,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 +@@ -9224,7 +9224,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 + */ +-int cfg80211_bss_color_notify(struct net_device *dev, ++int cfg80211_bss_color_notify(struct net_device *dev, gfp_t gfp, + enum nl80211_commands cmd, u8 count, + u64 color_bitmap); + +@@ -9234,9 +9234,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, +- u64 color_bitmap) ++ u64 color_bitmap, gfp_t gfp) + { +- return cfg80211_bss_color_notify(dev, NL80211_CMD_OBSS_COLOR_COLLISION, ++ return cfg80211_bss_color_notify(dev, gfp, NL80211_CMD_OBSS_COLOR_COLLISION, + 0, color_bitmap); + } + +@@ -9250,7 +9250,7 @@ static inline int cfg80211_obss_color_co + static inline int cfg80211_color_change_started_notify(struct net_device *dev, + u8 count) + { +- return cfg80211_bss_color_notify(dev, NL80211_CMD_COLOR_CHANGE_STARTED, ++ return cfg80211_bss_color_notify(dev, GFP_KERNEL, NL80211_CMD_COLOR_CHANGE_STARTED, + count, 0); + } + +@@ -9262,7 +9262,7 @@ static inline int cfg80211_color_change_ + */ + static inline int cfg80211_color_change_aborted_notify(struct net_device *dev) + { +- return cfg80211_bss_color_notify(dev, NL80211_CMD_COLOR_CHANGE_ABORTED, ++ return cfg80211_bss_color_notify(dev, GFP_KERNEL, NL80211_CMD_COLOR_CHANGE_ABORTED, + 0, 0); + } + +@@ -9274,7 +9274,7 @@ static inline int cfg80211_color_change_ + */ + static inline int cfg80211_color_change_notify(struct net_device *dev) + { +- return cfg80211_bss_color_notify(dev, ++ return cfg80211_bss_color_notify(dev, GFP_KERNEL, + NL80211_CMD_COLOR_CHANGE_COMPLETED, + 0, 0); + } +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -5234,6 +5234,10 @@ void ieee80211_tx_status_ext(struct ieee + * (NULL for multicast packets) + * @info: tx status information + */ ++void ieee80211_tx_status_8023(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct sk_buff *skb); ++ + static inline void ieee80211_tx_status_noskb(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + struct ieee80211_tx_info *info) +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -4775,7 +4775,7 @@ void ieee80211_color_collision_detection + struct ieee80211_sub_if_data *sdata = link->sdata; + + sdata_lock(sdata); +- cfg80211_obss_color_collision_notify(sdata->dev, link->color_bitmap); ++ cfg80211_obss_color_collision_notify(sdata->dev, link->color_bitmap, GFP_KERNEL); + sdata_unlock(sdata); + } + +--- a/net/mac80211/debugfs_netdev.c ++++ b/net/mac80211/debugfs_netdev.c +@@ -889,7 +889,7 @@ void ieee80211_debugfs_add_netdev(struct + { + char buf[10+IFNAMSIZ]; + +- sprintf(buf, "netdev:%s", sdata->name); ++ snprintf(buf, 10 + IFNAMSIZ, "netdev:%s", sdata->name); + sdata->vif.debugfs_dir = debugfs_create_dir(buf, + sdata->local->hw.wiphy->debugfsdir); + sdata->debugfs.subdir_stations = debugfs_create_dir("stations", +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -1406,18 +1406,6 @@ static void __sta_info_destroy_part2(str + WARN_ON_ONCE(ret); + } + +- /* Flush queues before removing keys, as that might remove them +- * from hardware, and then depending on the offload method, any +- * frames sitting on hardware queues might be sent out without +- * any encryption at all. +- */ +- if (local->ops->set_key) { +- if (local->ops->flush_sta) +- drv_flush_sta(local, sta->sdata, sta); +- else +- ieee80211_flush_queues(local, sta->sdata, false); +- } +- + /* now keys can no longer be reached */ + ieee80211_free_sta_keys(local, sta); + +--- a/net/mac80211/status.c ++++ b/net/mac80211/status.c +@@ -1244,6 +1244,30 @@ void ieee80211_tx_rate_update(struct iee + } + EXPORT_SYMBOL(ieee80211_tx_rate_update); + ++void ieee80211_tx_status_8023(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct sk_buff *skb) ++{ ++ struct ieee80211_sub_if_data *sdata; ++ struct ieee80211_tx_status status = { ++ .skb = skb, ++ .info = IEEE80211_SKB_CB(skb), ++ }; ++ struct sta_info *sta; ++ ++ sdata = vif_to_sdata(vif); ++ ++ rcu_read_lock(); ++ ++ if (!ieee80211_lookup_ra_sta(sdata, skb, &sta) && !IS_ERR(sta)) ++ status.sta = &sta->sta; ++ ++ ieee80211_tx_status_ext(hw, &status); ++ ++ rcu_read_unlock(); ++} ++EXPORT_SYMBOL(ieee80211_tx_status_8023); ++ + void ieee80211_report_low_ack(struct ieee80211_sta *pubsta, u32 num_packets) + { + struct sta_info *sta = container_of(pubsta, struct sta_info, sta); +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -19406,7 +19406,7 @@ void cfg80211_ch_switch_started_notify(s + } + EXPORT_SYMBOL(cfg80211_ch_switch_started_notify); + +-int cfg80211_bss_color_notify(struct net_device *dev, ++int cfg80211_bss_color_notify(struct net_device *dev, gfp_t gfp, + enum nl80211_commands cmd, u8 count, + u64 color_bitmap) + { +@@ -19420,7 +19420,7 @@ int cfg80211_bss_color_notify(struct net + + trace_cfg80211_bss_color_notify(dev, cmd, count, color_bitmap); + +- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); ++ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); + if (!msg) + return -ENOMEM; + +@@ -19443,7 +19443,7 @@ int cfg80211_bss_color_notify(struct net + genlmsg_end(msg, hdr); + + return genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), +- msg, 0, NL80211_MCGRP_MLME, GFP_KERNEL); ++ msg, 0, NL80211_MCGRP_MLME, gfp); + + nla_put_failure: + nlmsg_free(msg); +--- a/backport-include/linux/netdevice.h ++++ b/backport-include/linux/netdevice.h +@@ -70,6 +70,9 @@ static inline void netif_trans_update(st + (_dev)->needs_free_netdev = true; + #endif + ++#define netdev_tstats(dev) dev->tstats ++#define netdev_assign_tstats(dev, e) dev->tstats = (e); ++ + #if LINUX_VERSION_IS_LESS(4,15,0) + static inline int _bp_netdev_upper_dev_link(struct net_device *dev, + struct net_device *upper_dev) From c3f668c2408c89567afb5f4ae04d9ab24da587f9 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 17 Dec 2023 02:58:33 -0500 Subject: [PATCH 060/225] ath11k-nss: Wifi offloading working (unstable) Wifi offloading seems to be working, however it is not stable. Logs will initially show a lot of flooding. ``` [Sun Dec 17 02:43:25 2023] ath11k c000000.wifi: peer not found for nss peer delete [Sun Dec 17 02:43:28 2023] ath11k c000000.wifi: peer not found for nss peer delete [Sun Dec 17 02:43:30 2023] ath11k c000000.wifi: peer not found for nss peer delete [Sun Dec 17 02:43:32 2023] ath11k c000000.wifi: peer not found for nss peer delete [Sun Dec 17 02:43:34 2023] ath11k c000000.wifi: peer not found for nss peer delete [Sun Dec 17 02:43:40 2023] ath11k c000000.wifi: peer not found for nss peer delete [Sun Dec 17 02:43:41 2023] ath11k c000000.wifi: peer not found for nss peer delete [Sun Dec 17 02:43:46 2023] ath11k c000000.wifi: peer not found for nss peer delete ``` But eventually ends up subsiding. Needs heavy testing... --- package/kernel/mac80211/Makefile | 7 +- ...dma-counter-increamenting-improperly.patch | 8 +- ...-adding-support-for-mgmt-frame-stats.patch | 36 +- ...91-ath11k-add-mgmt-and-data-ack-rssi.patch | 11 +- ...-ath11k_nss-add-nss-driver-interface.patch | 42 +- .../199-003-ath11k-add-nss-support.patch | 237 ++++---- ...-004-ath10k-add-nss-driver-interface.patch | 12 +- ...-ath11k-Add-support-for-dynamic-vlan.patch | 60 +++ ...th11k-Enable-512MB-profile-in-ath11k.patch | 129 +++-- ...07-mac80211-add-nss-redirect-support.patch | 268 ++++++++++ ...14-ath11k-qos-null-frame-tx-over-wmi.patch | 9 +- ...11k-Disable-rx_header-tlv-for-2K-SKB.patch | 70 ++- ...01-ath11k-account-tx-rx-packets-flow.patch | 275 ++++++++++ ...dd-provision-to-configure-rx-hashmap.patch | 208 +++++++ ...dst-ring-descriptors-from-cacheable-.patch | 147 +++++ ...ow-fast-rx-by-bypassing-stats-update.patch | 412 ++++++++++++++ .../ath11k_nss/245-compilation_fix.patch | 183 +++++++ .../245-revert-dev-sw-netstats-txrx-add.patch | 145 +++++ ...-nss-thread-priority-during-pdev_ini.patch | 24 +- ...e-free-of-peer-rx_tid-during-reo-cmd.patch | 2 +- ...1k-skip-status-ring-entry-processing.patch | 16 +- ...mac80211-fix-unconditional-sta-usage.patch | 50 ++ ...-event-handler-support-for-link-desc.patch | 73 +++ ...unused-RX_FLAGS-from-mac80211_rx_fla.patch | 85 +++ .../640-006-mac80211-add-eht-radiotap.patch | 506 ++++++++++++++++++ ...se-HW-checksum-offload-only-for-ethm.patch | 111 ++++ .../patches/ath11k_nss/999-fix-build.patch | 19 +- 27 files changed, 2879 insertions(+), 266 deletions(-) create mode 100644 package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/207-mac80211-add-nss-redirect-support.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/234-001-ath11k-account-tx-rx-packets-flow.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/237-002-ath11k-Add-provision-to-configure-rx-hashmap.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/237-003-ath11k-allocate-dst-ring-descriptors-from-cacheable-.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/245-compilation_fix.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/245-revert-dev-sw-netstats-txrx-add.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/342-mac80211-fix-unconditional-sta-usage.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/376-ath11k-Add-nss-event-handler-support-for-link-desc.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/640-006-mac80211-add-eht-radiotap.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 31bb9aed055f30..f5147d7982aba6 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -121,10 +121,15 @@ define KernelPackage/mac80211 $(call KernelPackage/mac80211/Default) TITLE:=Linux 802.11 Wireless Networking Stack # +kmod-crypto-cmac is a runtime only dependency of net/mac80211/aes_cmac.c - DEPENDS+= +kmod-cfg80211 +kmod-crypto-cmac +kmod-crypto-ccm +kmod-crypto-gcm +hostapd-common + DEPENDS+= +kmod-cfg80211 +kmod-crypto-cmac +kmod-crypto-ccm +kmod-crypto-gcm +hostapd-common \ + +ATH11K_NSS_SUPPORT:kmod-qca-nss-drv KCONFIG:=\ CONFIG_AVERAGE=y FILES:= $(PKG_BUILD_DIR)/net/mac80211/mac80211.ko +ifdef CONFIG_ATH11K_NSS_SUPPORT + AUTOLOAD:=$(call AutoProbe,mac80211) + MODPARAMS.mac80211:=nss_redirect=1 +endif ABI_VERSION:=$(PKG_VERSION)-$(PKG_RELEASE) MENU:=1 endef diff --git a/package/kernel/mac80211/patches/ath11k_nss/087-ath11k-fix-ul-ofdma-counter-increamenting-improperly.patch b/package/kernel/mac80211/patches/ath11k_nss/087-ath11k-fix-ul-ofdma-counter-increamenting-improperly.patch index 42495d7db3470b..326db09145b342 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/087-ath11k-fix-ul-ofdma-counter-increamenting-improperly.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/087-ath11k-fix-ul-ofdma-counter-increamenting-improperly.patch @@ -8,7 +8,7 @@ @@ -5242,8 +5242,11 @@ int ath11k_dp_rx_process_mon_status(stru goto next_skb; } - + - arsta = ath11k_sta_to_arsta(peer->sta); - ath11k_dp_rx_update_peer_stats(arsta, ppdu_info); + if ((ppdu_info->fc_valid) && @@ -16,7 +16,7 @@ + arsta = (struct ath11k_sta *)peer->sta->drv_priv; + ath11k_dp_rx_update_peer_stats(arsta, ppdu_info); + } - + if (ath11k_debugfs_is_pktlog_peer_valid(ar, peer->addr)) trace_ath11k_htt_rxdesc(ar, skb->data, log_type, rx_buf_sz); --- a/drivers/net/wireless/ath/ath11k/hal_rx.c @@ -35,10 +35,10 @@ +++ b/drivers/net/wireless/ath/ath11k/hal_rx.h @@ -66,6 +66,7 @@ enum hal_rx_reception_type { }; - + #define HAL_RX_FCS_LEN 4 +#define HAL_AST_IDX_INVALID 0xFFFF - + enum hal_rx_mon_status { HAL_RX_MON_STATUS_PPDU_NOT_DONE, @@ -150,6 +151,7 @@ struct hal_rx_mon_ppdu_info { diff --git a/package/kernel/mac80211/patches/ath11k_nss/142-ath11k-adding-support-for-mgmt-frame-stats.patch b/package/kernel/mac80211/patches/ath11k_nss/142-ath11k-adding-support-for-mgmt-frame-stats.patch index 61feac0f6cb6e6..18d0d461c9cfe9 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/142-ath11k-adding-support-for-mgmt-frame-stats.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/142-ath11k-adding-support-for-mgmt-frame-stats.patch @@ -3,7 +3,7 @@ @@ -311,6 +311,16 @@ struct ath11k_rekey_data { bool enable_offload; }; - + +#define ATH11K_STATS_MGMT_FRM_TYPE_MAX 16 + +struct ath11k_mgmt_frame_stats { @@ -24,22 +24,14 @@ + + struct ath11k_mgmt_frame_stats mgmt_stats; }; - + struct ath11k_vif_iter { -@@ -901,6 +913,7 @@ struct ath11k_base { - struct list_head peers; - wait_queue_head_t peer_mapping_wq; - u8 mac_addr[ETH_ALEN]; -+ int userpd_id; - int irq_num[ATH11K_IRQ_NUM_MAX]; - struct ath11k_ext_irq_grp ext_irq_grp[ATH11K_EXT_IRQ_GRP_NUM_MAX]; - struct ath11k_targ_cap target_caps; --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c @@ -1588,6 +1588,87 @@ static const struct file_operations fops .llseek = default_llseek, }; - + +static ssize_t ath11k_dump_mgmt_stats(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) +{ @@ -131,7 +123,7 @@ + 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, --- a/drivers/net/wireless/ath/ath11k/mac.c @@ -146,7 +138,7 @@ - return -ENOSPC; + return -EBUSY; } - + if (skb_queue_len_lockless(q) >= ATH11K_TX_MGMT_NUM_PENDING_MAX) { @@ -6174,9 +6174,11 @@ static void ath11k_mac_op_tx(struct ieee struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); @@ -158,7 +150,7 @@ bool is_prb_rsp; + u16 frm_type = 0; int ret; - + memset(skb_cb, 0, sizeof(*skb_cb)); @@ -6190,12 +6192,21 @@ static void ath11k_mac_op_tx(struct ieee if (info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { @@ -187,11 +179,11 @@ --- 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 - + peer->sec_type = HAL_ENCRYPT_TYPE_OPEN; peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; + peer->vif = arvif->vif; - + if (sta) { arsta = ath11k_sta_to_arsta(sta); --- a/drivers/net/wireless/ath/ath11k/peer.h @@ -217,12 +209,12 @@ + struct ath11k_mgmt_frame_stats *mgmt_stats; + u16 frm_type; int num_mgmt; - + spin_lock_bh(&ar->txmgmt_idr_lock); @@ -5850,6 +5856,31 @@ static int wmi_process_mgmt_tx_comp(stru info->status.ack_signal = tx_compl_param->ack_rssi; } - + + hdr = (struct ieee80211_hdr *)msdu->data; + frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, hdr->frame_control); + @@ -249,7 +241,7 @@ + +skip_mgmt_stats: ieee80211_tx_status_irqsafe(ar->hw, msdu); - + num_mgmt = atomic_dec_if_positive(&ar->num_pending_mgmt_tx); @@ -7519,6 +7550,11 @@ static void ath11k_mgmt_rx_event(struct struct ieee80211_hdr *hdr; @@ -260,11 +252,11 @@ + struct ath11k_vif *arvif; + struct ath11k_mgmt_frame_stats *mgmt_stats; + u16 frm_type = 0; - + if (ath11k_pull_mgmt_rx_params_tlv(ab, skb, &rx_ev) != 0) { ath11k_warn(ab, "failed to extract mgmt rx event"); @@ -7584,7 +7620,34 @@ static void ath11k_mgmt_rx_event(struct - + hdr = (struct ieee80211_hdr *)skb->data; fc = le16_to_cpu(hdr->frame_control); + frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, fc); @@ -293,7 +285,7 @@ + mgmt_stats->rx_cnt[frm_type]++; + + spin_unlock_bh(&ar->data_lock); - + +skip_mgmt_stats: /* Firmware is guaranteed to report all essential management frames via * WMI while it can deliver some extra via HTT. Since there can be diff --git a/package/kernel/mac80211/patches/ath11k_nss/191-ath11k-add-mgmt-and-data-ack-rssi.patch b/package/kernel/mac80211/patches/ath11k_nss/191-ath11k-add-mgmt-and-data-ack-rssi.patch index 202439056c43da..6d8cdb83fd73cc 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/191-ath11k-add-mgmt-and-data-ack-rssi.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/191-ath11k-add-mgmt-and-data-ack-rssi.patch @@ -30,12 +30,19 @@ 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,8 @@ struct wmi_pdev_bss_chan_info_event { +@@ -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 ppdu_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/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch index d9be673c93f5f9..ea47c3c9721d7e 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch @@ -20,9 +20,9 @@ Signed-off-by: Sriram R --- a/drivers/net/wireless/ath/ath11k/Kconfig +++ b/drivers/net/wireless/ath/ath11k/Kconfig @@ -13,6 +13,16 @@ config ATH11K - + If you choose to build a module, it'll be called ath11k. - + +config ATH11K_NSS_SUPPORT + bool "QCA ath11k nss support" + depends on ATH11K @@ -43,7 +43,7 @@ Signed-off-by: Sriram R ath11k-$(CPTCFG_ATH11K_SPECTRAL) += spectral.o ath11k-$(CONFIG_PM) += wow.o +ath11k-$(CPTCFG_ATH11K_NSS_SUPPORT) += nss.o - + obj-$(CPTCFG_ATH11K_AHB) += ath11k_ahb.o ath11k_ahb-y += ahb.o --- /dev/null @@ -2757,12 +2757,12 @@ Signed-off-by: Sriram R void (*get_ce_msi_idx)(struct ath11k_base *ab, u32 ce_id, u32 *msi_idx); + u32 (*get_window_offset)(struct ath11k_base *ab, u32 offset); }; - + static inline void ath11k_hif_ce_irq_enable(struct ath11k_base *ab) @@ -136,6 +137,14 @@ static inline void ath11k_get_msi_addres ab->hif.ops->get_msi_address(ab, msi_addr_lo, msi_addr_hi); } - + +static inline u32 ath11k_hif_get_window_offset(struct ath11k_base *ab, u32 offset) +{ + if (ab->hif.ops->get_window_offset) @@ -2779,7 +2779,7 @@ Signed-off-by: Sriram R @@ -67,6 +67,20 @@ static u32 ath11k_pci_get_window_start(s return ATH11K_PCI_WINDOW_START; } - + +static inline u32 ath11k_pci_get_window_offset(struct ath11k_base *ab, + u32 offset) +{ @@ -2804,13 +2804,13 @@ Signed-off-by: Sriram R + .get_window_offset = ath11k_pci_get_window_offset, .get_ce_msi_idx = ath11k_pcic_get_ce_msi_idx, }; - + --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -992,6 +992,29 @@ unlock_exit: spin_unlock_bh(&ab->base_lock); } - + +/* Sends WMI config to filter packets to route packets to WBM release ring */ +int ath11k_dp_rx_pkt_type_filter(struct ath11k *ar, enum ath11k_routing_pkt_type pkt_type, u32 meta_data) +{ @@ -2842,7 +2842,7 @@ Signed-off-by: Sriram R @@ -1164,6 +1164,44 @@ int ath11k_wmi_send_pdev_set_regdomain(s return ret; } - + +int ath11k_wmi_send_pdev_pkt_route(struct ath11k *ar, struct ath11k_wmi_pkt_route_param *param) +{ + struct ath11k_pdev_wmi *wmi = ar->wmi; @@ -2889,7 +2889,7 @@ Signed-off-by: Sriram R @@ -2873,6 +2873,27 @@ struct pdev_set_regdomain_params { u32 pdev_id; }; - + + /* Defines various options for routing policy */ +enum wmi_pdev_dest_ring_handler_type { + ATH11K_WMI_PKTROUTE_USE_CCE = 0, @@ -2917,7 +2917,7 @@ Signed-off-by: Sriram R @@ -3121,6 +3142,16 @@ struct wmi_pdev_set_regdomain_cmd { u32 dfs_domain; } __packed; - + +struct wmi_pdev_pkt_route_cmd { + u32 tlv_header; + u32 pdev_id; @@ -2931,10 +2931,10 @@ Signed-off-by: Sriram R struct wmi_peer_set_param_cmd { u32 tlv_header; u32 vdev_id; -@@ -6364,6 +6395,8 @@ int ath11k_wmi_send_peer_create_cmd(stru +@@ -6362,6 +6393,8 @@ int ath11k_wmi_send_peer_create_cmd(stru int ath11k_wmi_vdev_set_param_cmd(struct ath11k *ar, u32 vdev_id, u32 param_id, u32 param_value); - + +int ath11k_wmi_send_pdev_pkt_route(struct ath11k *ar, + struct ath11k_wmi_pkt_route_param *param); int ath11k_wmi_set_sta_ps_param(struct ath11k *ar, u32 vdev_id, @@ -2945,7 +2945,7 @@ Signed-off-by: Sriram R @@ -20,6 +20,34 @@ #define DP_RX_MPDU_ERR_MPDU_LEN BIT(6) #define DP_RX_MPDU_ERR_UNENCRYPTED_FRAME BIT(7) - + +/* different supported pkt types for routing */ +enum ath11k_routing_pkt_type { + ATH11K_PKT_TYPE_ARP_IPV4, @@ -2992,7 +2992,7 @@ Signed-off-by: Sriram R @@ -6365,6 +6365,16 @@ static int ath11k_mac_op_start(struct ie goto err; } - + + /* nss offload requires eapol packets to be routed to wbm release ring */ + if (ab->nss.enabled) { + ret = ath11k_dp_rx_pkt_type_filter(ar, ATH11K_PKT_TYPE_EAP, @@ -3004,5 +3004,15 @@ Signed-off-by: Sriram R + } + __ath11k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask); - + /* 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 { + struct list_head peers; + wait_queue_head_t peer_mapping_wq; + u8 mac_addr[ETH_ALEN]; ++ int userpd_id; + int irq_num[ATH11K_IRQ_NUM_MAX]; + struct ath11k_ext_irq_grp ext_irq_grp[ATH11K_EXT_IRQ_GRP_NUM_MAX]; + struct ath11k_targ_cap target_caps; diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch b/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch index 72af89fd7cb4d6..f829f7adc2fd7d 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch @@ -34,38 +34,38 @@ Signed-off-by: Sriram R + * to nss when its enabled, hence don't enable these interrupts + */ + nss_offload = ab->nss.enabled; - + for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; @@ -537,20 +543,20 @@ static int ath11k_ahb_config_ext_irq(str ath11k_ahb_ext_grp_napi_poll); - + for (j = 0; j < ATH11K_EXT_IRQ_NUM_MAX; j++) { - if (ab->hw_params.ring_mask->tx[i] & BIT(j)) { + if (!nss_offload && ab->hw_params.ring_mask->tx[i] & BIT(j)) { irq_grp->irqs[num_irq++] = wbm2host_tx_completions_ring1 - j; } - + - if (ab->hw_params.ring_mask->rx[i] & BIT(j)) { + if (!nss_offload && ab->hw_params.ring_mask->rx[i] & BIT(j)) { irq_grp->irqs[num_irq++] = reo2host_destination_ring1 - j; } - + - if (ab->hw_params.ring_mask->rx_err[i] & BIT(j)) + if (!nss_offload && ab->hw_params.ring_mask->rx_err[i] & BIT(j)) irq_grp->irqs[num_irq++] = reo2host_exception; - + - if (ab->hw_params.ring_mask->rx_wbm_rel[i] & BIT(j)) + if (!nss_offload && ab->hw_params.ring_mask->rx_wbm_rel[i] & BIT(j)) irq_grp->irqs[num_irq++] = wbm2host_rx_release; - + if (ab->hw_params.ring_mask->reo_status[i] & BIT(j)) @@ -563,7 +569,7 @@ static int ath11k_ahb_config_ext_irq(str ath11k_hw_get_mac_from_pdev_id(hw, j); } - + - if (ab->hw_params.ring_mask->host2rxdma[i] & BIT(j)) { + if (!nss_offload && ab->hw_params.ring_mask->host2rxdma[i] & BIT(j)) { irq_grp->irqs[num_irq++] = @@ -73,18 +73,18 @@ Signed-off-by: Sriram R ath11k_hw_get_mac_from_pdev_id(hw, j); @@ -904,6 +910,7 @@ static int ath11k_ahb_setup_resources(st } - + ab->mem = mem; + ab->mem_pa = mem_res->start; ab->mem_len = resource_size(mem_res); - + return 0; --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -17,6 +17,12 @@ #include "hif.h" #include "wow.h" - + +unsigned int nss_offload; +#ifdef CPTCFG_ATH11K_NSS_SUPPORT +module_param_named(nss_offload, nss_offload, uint, 0644); @@ -97,7 +97,7 @@ Signed-off-by: Sriram R @@ -1528,10 +1534,16 @@ static int ath11k_core_pdev_create(struc goto err_pdev_debug; } - + + ret = ath11k_nss_setup(ab); + if (ret) { + ath11k_err(ab, "failed to setup nss driver interface%d", ret); @@ -110,7 +110,7 @@ Signed-off-by: Sriram R - goto err_dp_pdev_free; + goto err_nss_tear; } - + ret = ath11k_thermal_register(ab); @@ -1553,6 +1565,8 @@ err_thermal_unregister: ath11k_thermal_unregister(ab); @@ -134,7 +134,7 @@ Signed-off-by: Sriram R ath11k_debugfs_pdev_destroy(ab); @@ -1772,6 +1790,10 @@ static int ath11k_core_reconfigure_on_cr int ret; - + mutex_lock(&ab->core_lock); + + ath11k_nss_teardown(ab); @@ -151,7 +151,7 @@ Signed-off-by: Sriram R + + if (nss_offload) + ab->nss.stats_enabled = 1; - + return 0; } --- a/drivers/net/wireless/ath/ath11k/core.h @@ -161,28 +161,28 @@ Signed-off-by: Sriram R #include "spectral.h" #include "wow.h" +#include "nss.h" - + #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) - + @@ -381,6 +382,9 @@ struct ath11k_vif { #endif /* CPTCFG_ATH11K_DEBUGFS */ - + struct ath11k_mgmt_frame_stats mgmt_stats; +#ifdef CPTCFG_ATH11K_NSS_SUPPORT + struct arvif_nss nss; +#endif }; - + struct ath11k_vif_iter { @@ -520,6 +524,9 @@ struct ath11k_sta { #endif - + bool use_4addr_set; +#ifdef CPTCFG_ATH11K_NSS_SUPPORT + struct ath11k_nss_sta_stats *nss_stats; +#endif u16 tcl_metadata; - + /* Protected with ar->data_lock */ @@ -610,6 +617,9 @@ struct ath11k { struct ieee80211_hw *hw; @@ -200,19 +200,19 @@ Signed-off-by: Sriram R atomic_t misc_fail; + atomic_t nss_tx_fail; }; - + struct ath11k_soc_dp_stats { @@ -868,9 +879,11 @@ struct ath11k_base { struct ath11k_htc htc; - + struct ath11k_dp dp; + struct ath11k_soc_nss nss; - + void __iomem *mem; void __iomem *mem_ce; + dma_addr_t mem_pa; unsigned long mem_len; - + struct { --- a/drivers/net/wireless/ath/ath11k/dp.c +++ b/drivers/net/wireless/ath/ath11k/dp.c @@ -225,20 +225,20 @@ Signed-off-by: Sriram R + /* RX Hash based steering is disabled for NSS Offload */ + if (ar->ab->nss.enabled) + rx_hash_enable = DP_RX_HASH_DISABLE; - + /* NOTE: reo_dest ring id starts from 1 unlike mac_id which starts from 0 */ reo_dest = ar->dp.mac_id + 1; ret = ath11k_wmi_set_peer_param(ar, addr, vdev_id, WMI_PEER_SET_DEFAULT_ROUTING, - DP_RX_HASH_ENABLE | (reo_dest << 1)); + rx_hash_enable | (reo_dest << 1)); - + if (ret) { ath11k_warn(ab, "failed to set default routing %d peer :%pM vdev_id :%d\n", @@ -132,6 +137,18 @@ static int ath11k_dp_srng_calculate_msi_ { const u8 *grp_mask; - + + if (ab->nss.enabled) { + switch (type) { + case HAL_REO_STATUS: @@ -259,7 +259,7 @@ Signed-off-by: Sriram R int i, j; int tot_work_done = 0; + bool nss_offload; - + - for (i = 0; i < ab->hw_params.max_tx_ring; i++) { - if (BIT(ab->hw_params.hal_params->tcl2wbm_rbm_map[i].wbm_ring_num) & - ab->hw_params.ring_mask->tx[grp_id]) @@ -270,7 +270,7 @@ Signed-off-by: Sriram R + i = __fls(ab->hw_params.ring_mask->tx[grp_id]); + ath11k_dp_tx_completion_handler(ab, i); } - + - if (ab->hw_params.ring_mask->rx_err[grp_id]) { + if (!nss_offload && ab->hw_params.ring_mask->rx_err[grp_id]) { work_done = ath11k_dp_process_rx_err(ab, napi, budget); @@ -279,7 +279,7 @@ Signed-off-by: Sriram R @@ -793,7 +812,7 @@ int ath11k_dp_service_srng(struct ath11k goto done; } - + - if (ab->hw_params.ring_mask->rx_wbm_rel[grp_id]) { + if (!nss_offload && ab->hw_params.ring_mask->rx_wbm_rel[grp_id]) { work_done = ath11k_dp_rx_process_wbm_err(ab, @@ -288,7 +288,7 @@ Signed-off-by: Sriram R @@ -804,7 +823,7 @@ int ath11k_dp_service_srng(struct ath11k goto done; } - + - if (ab->hw_params.ring_mask->rx[grp_id]) { + if (!nss_offload && ab->hw_params.ring_mask->rx[grp_id]) { i = fls(ab->hw_params.ring_mask->rx[grp_id]) - 1; @@ -307,26 +307,26 @@ Signed-off-by: Sriram R + budget); budget -= work_done; tot_work_done += work_done; - + @@ -838,7 +858,7 @@ int ath11k_dp_service_srng(struct ath11k if (ab->hw_params.ring_mask->reo_status[grp_id]) ath11k_dp_process_reo_status(ab); - + - for (i = 0; i < ab->num_radios; i++) { + for (i = 0; !nss_offload && i < ab->num_radios; i++) { for (j = 0; j < ab->hw_params.num_rxmda_per_pdev; j++) { int id = i * ab->hw_params.num_rxmda_per_pdev + j; - + --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h @@ -194,6 +194,7 @@ struct ath11k_pdev_dp { #define DP_AVG_MSDUS_PER_MPDU 4 - + #define DP_RX_HASH_ENABLE 1 /* Enable hash based Rx steering */ +#define DP_RX_HASH_DISABLE 0 /* Disable hash based Rx steering */ - + #define DP_BA_WIN_SZ_MAX 256 - + --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -17,6 +17,7 @@ @@ -334,13 +334,13 @@ Signed-off-by: Sriram R #include "dp_tx.h" #include "peer.h" +#include "nss.h" - + #define ATH11K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ) - + @@ -213,8 +214,8 @@ static inline u8 ath11k_dp_rx_h_mpdu_sta return ab->hw_params.hw_ops->rx_desc_get_mpdu_tid(desc); } - + -static inline u16 ath11k_dp_rx_h_mpdu_start_peer_id(struct ath11k_base *ab, - struct hal_rx_desc *desc) +u16 ath11k_dp_rx_h_mpdu_start_peer_id(struct ath11k_base *ab, @@ -351,7 +351,7 @@ Signed-off-by: Sriram R @@ -225,8 +226,8 @@ static inline u8 ath11k_dp_rx_h_msdu_end return ab->hw_params.hw_ops->rx_desc_get_l3_pad_bytes(desc); } - + -static inline bool ath11k_dp_rx_h_msdu_end_first_msdu(struct ath11k_base *ab, - struct hal_rx_desc *desc) +bool ath11k_dp_rx_h_msdu_end_first_msdu(struct ath11k_base *ab, @@ -362,7 +362,7 @@ Signed-off-by: Sriram R @@ -283,7 +284,7 @@ static inline void ath11k_dp_rxdesc_set_ ab->hw_params.hw_ops->rx_desc_set_msdu_len(desc, len); } - + -static bool ath11k_dp_rx_h_attn_is_mcbc(struct ath11k_base *ab, +bool ath11k_dp_rx_h_attn_is_mcbc(struct ath11k_base *ab, struct hal_rx_desc *desc) @@ -371,18 +371,18 @@ Signed-off-by: Sriram R @@ -498,7 +499,9 @@ static int ath11k_dp_rxdma_pdev_buf_setu struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; int i; - + - ath11k_dp_rxdma_ring_buf_setup(ar, rx_ring, HAL_RXDMA_BUF); + /* RXDMA BUF ring is offloaded to NSS */ + if (!ar->ab->nss.enabled) + ath11k_dp_rxdma_ring_buf_setup(ar, rx_ring, HAL_RXDMA_BUF); - + 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( CHECKSUM_NONE : CHECKSUM_UNNECESSARY; } - + -static int ath11k_dp_rx_crypto_mic_len(struct ath11k *ar, +int ath11k_dp_rx_crypto_mic_len(struct ath11k *ar, enum hal_encrypt_type enctype) @@ -391,7 +391,7 @@ Signed-off-by: Sriram R @@ -1920,7 +1923,7 @@ static int ath11k_dp_rx_crypto_mic_len(s return 0; } - + -static int ath11k_dp_rx_crypto_param_len(struct ath11k *ar, +int ath11k_dp_rx_crypto_param_len(struct ath11k *ar, enum hal_encrypt_type enctype) @@ -400,7 +400,7 @@ Signed-off-by: Sriram R @@ -1948,7 +1951,7 @@ static int ath11k_dp_rx_crypto_param_len return 0; } - + -static int ath11k_dp_rx_crypto_icv_len(struct ath11k *ar, +int ath11k_dp_rx_crypto_icv_len(struct ath11k *ar, enum hal_encrypt_type enctype) @@ -420,7 +420,7 @@ Signed-off-by: Sriram R @@ -126,4 +126,16 @@ 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); - + +int ath11k_dp_rx_crypto_mic_len(struct ath11k *ar, + enum hal_encrypt_type enctype); +int ath11k_dp_rx_crypto_param_len(struct ath11k *ar, @@ -439,7 +439,7 @@ Signed-off-by: Sriram R @@ -424,6 +424,8 @@ enum hal_srng_ring_id { #define HAL_SRNG_RING_ID_MAX (HAL_SRNG_RING_ID_UMAC_ID_END + \ HAL_SRNG_NUM_LMAC_RINGS) - + +#define HAL_SRNG_REO_ALTERNATE_SELECT 0x7 + enum hal_ring_type { @@ -452,12 +452,12 @@ Signed-off-by: Sriram R #include "hif.h" #include "wow.h" +#include "nss.h" - + #define CHAN2G(_channel, _freq, _flags) { \ .band = NL80211_BAND_2GHZ, \ @@ -1603,6 +1604,11 @@ static void ath11k_control_beaconing(str lockdep_assert_held(&arvif->ar->conf_mutex); - + if (!info->enable_beacon) { + + ret = ath11k_nss_vdev_down(arvif); @@ -468,9 +468,9 @@ Signed-off-by: Sriram R if (ret) ath11k_warn(ar->ab, "failed to down vdev_id %i: %d\n", @@ -1642,6 +1648,12 @@ static void ath11k_control_beaconing(str - + arvif->is_up = true; - + + ret = ath11k_nss_vdev_up(arvif); + if(ret) { + ath11k_warn(ar->ab, "failure in nss vdev up %d\r\n",ret); @@ -479,11 +479,11 @@ Signed-off-by: Sriram R + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "vdev %d up\n", arvif->vdev_id); } - + @@ -3075,6 +3087,12 @@ static void ath11k_bss_assoc(struct ieee "vdev %d up (associated) bssid %pM aid %d\n", arvif->vdev_id, bss_conf->bssid, vif->cfg.aid); - + + ret = ath11k_nss_vdev_up(arvif); + if(ret) { + ath11k_warn(ar->ab, "failure in nss vdev up %d\r\n",ret); @@ -491,23 +491,23 @@ Signed-off-by: Sriram R + } + spin_lock_bh(&ar->ab->base_lock); - + peer = ath11k_peer_find(ar->ab, arvif->vdev_id, arvif->bssid); @@ -3117,6 +3135,10 @@ static void ath11k_bss_disassoc(struct i - + lockdep_assert_held(&ar->conf_mutex); - + + ret = ath11k_nss_vdev_down(arvif); + if(ret) + ath11k_warn(ar->ab, "failure in nss vdev down %d\r\n",ret); + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "vdev %i disassoc bssid %pM\n", arvif->vdev_id, arvif->bssid); - + @@ -3397,6 +3419,28 @@ static int ath11k_mac_config_obss_pd(str return 0; } - + +static void ath11k_mac_op_nss_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u32 changed) @@ -534,7 +534,7 @@ Signed-off-by: Sriram R struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, @@ -4293,6 +4337,26 @@ static int ath11k_mac_op_set_key(struct - + spin_lock_bh(&ab->base_lock); peer = ath11k_peer_find(ab, arvif->vdev_id, peer_addr); + @@ -574,7 +574,7 @@ Signed-off-by: Sriram R @@ -6214,10 +6277,14 @@ static void ath11k_mac_op_tx(struct ieee if (control->sta) arsta = ath11k_sta_to_arsta(control->sta); - + - ret = ath11k_dp_tx(ar, arvif, arsta, skb); + if (ar->ab->nss.enabled) + ret = ath11k_nss_tx(arvif,skb); @@ -586,9 +586,9 @@ Signed-off-by: Sriram R + return; } } - + @@ -6239,6 +6306,8 @@ static int ath11k_mac_config_mon_status_ - + if (enable) { tlv_filter = ath11k_mac_mon_status_filter_default; + ath11k_nss_ext_rx_stats(ar->ab, &tlv_filter); @@ -599,7 +599,7 @@ Signed-off-by: Sriram R @@ -6537,7 +6606,7 @@ static int ath11k_mac_setup_vdev_create_ return 0; } - + -static void ath11k_mac_op_update_vif_offload(struct ieee80211_hw *hw, +static int ath11k_mac_op_update_vif_offload(struct ieee80211_hw *hw, struct ieee80211_vif *vif) @@ -612,12 +612,12 @@ Signed-off-by: Sriram R + + return ret; } - + static bool ath11k_mac_vif_ap_active_any(struct ath11k_base *ab) @@ -6713,6 +6784,8 @@ static int ath11k_mac_vdev_delete(struct - + reinit_completion(&ar->vdev_delete_done); - + + ath11k_nss_vdev_delete(arvif); + ret = ath11k_wmi_vdev_delete(ar, arvif->vdev_id); @@ -626,7 +626,7 @@ Signed-off-by: Sriram R @@ -6853,7 +6926,34 @@ static int ath11k_mac_op_add_interface(s list_add(&arvif->list, &ar->arvifs); spin_unlock_bh(&ar->data_lock); - + - ath11k_mac_op_update_vif_offload(hw, vif); + ret = ath11k_nss_vdev_create(arvif); + if(ret) { @@ -656,12 +656,12 @@ Signed-off-by: Sriram R + ath11k_warn(ab, "failed to set decap type in nss %d\n", ret); + goto err_vdev_del; + } - + nss = get_num_chains(ar->cfg_tx_chainmask) ? : 1; ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, @@ -6977,6 +7077,7 @@ err_peer_del: } - + err_vdev_del: + ath11k_nss_vdev_delete(arvif); ath11k_mac_vdev_delete(ar, arvif); @@ -676,7 +676,7 @@ Signed-off-by: Sriram R + if(ret) + ath11k_warn(ar->ab, "failure in nss vdev up %d\r\n",ret); } - + /* Restart the internal monitor vdev on new channel */ @@ -8769,6 +8874,8 @@ static void ath11k_mac_op_sta_statistics sinfo->signal_avg = ewma_avg_rssi_read(&arsta->avg_rssi) + @@ -685,7 +685,7 @@ Signed-off-by: Sriram R + + ath11k_nss_update_sta_stats(sinfo, sta, arsta); } - + #if IS_ENABLED(CONFIG_IPV6) @@ -9188,6 +9295,7 @@ static const struct ieee80211_ops ath11k .update_vif_offload = ath11k_mac_op_update_vif_offload, @@ -703,12 +703,12 @@ Signed-off-by: Sriram R + if(!ab->nss.enabled) + ieee80211_hw_set(ar->hw, USES_RSS); } - + ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; @@ -9688,6 +9797,9 @@ static int __ath11k_mac_register(struct ab->hw_params.bios_sar_capa) ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa; - + + if (ab->nss.enabled) + ieee80211_hw_set(ar->hw, SUPPORTS_NSS_OFFLOAD); + @@ -722,7 +722,7 @@ Signed-off-by: Sriram R #include "peer.h" #include "debug.h" +#include "nss.h" - + 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 @@ -732,12 +732,12 @@ Signed-off-by: Sriram R + if (ab->nss.enabled) + ath11k_nss_peer_create(ab, peer); } - + ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "peer map vdev %d peer %pM id %d\n", @@ -332,6 +335,8 @@ static int __ath11k_peer_delete(struct a - + reinit_completion(&ar->peer_delete_done); - + + ath11k_nss_peer_delete(ar->ab, addr); + ret = ath11k_wmi_send_peer_delete_cmd(ar, addr, vdev_id); @@ -750,17 +750,17 @@ Signed-off-by: Sriram R u8 pdev_idx; u16 hw_peer_id; + struct ath11k_nss_peer nss; - + /* protected by ab->data_lock */ struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c @@ -570,6 +570,7 @@ static int ath11k_pci_claim(struct ath11 } - + ab->mem_ce = ab->mem; + ab->mem_pa = pci_resource_start(pdev, ATH11K_PCI_BAR_NUM); - + ath11k_dbg(ab, ATH11K_DBG_BOOT, "pci_mem 0x%p\n", ab->mem); return 0; --- a/drivers/net/wireless/ath/ath11k/debugfs.c @@ -775,7 +775,7 @@ Signed-off-by: Sriram R -#include "peer.h" #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 @@ -784,27 +784,12 @@ Signed-off-by: Sriram R tlv_filter = ath11k_mac_mon_status_filter_default; + ath11k_nss_ext_rx_stats(ar->ab, &tlv_filter); } - + ar->debug.rx_filter = tlv_filter.rx_filter; -@@ -1592,10 +1592,13 @@ static ssize_t ath11k_dump_mgmt_stats(st - size_t count, loff_t *ppos) - { - struct ath11k *ar = file->private_data; -+#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M -+ struct ath11k_base *ab = ar->ab; -+#endif - 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", -@@ -1669,72 +1672,6 @@ static const struct file_operations fops +@@ -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; @@ -874,10 +859,10 @@ Signed-off-by: Sriram R void ath11k_debugfs_unregister(struct ath11k *ar) { struct ath11k_debug_dbr *dbr_debug; -@@ -1977,6 +1914,144 @@ static const struct file_operations ath1 +@@ -1977,6 +1911,144 @@ static const struct file_operations ath1 .open = simple_open }; - + +static ssize_t ath11k_write_nss_stats(struct file *file, + const char __user *ubuf, + size_t count, loff_t *ppos) @@ -1024,7 +1009,7 @@ Signed-off-by: Sriram R @@ -12,7 +12,7 @@ #include "peer.h" #include "mac.h" - + -static enum hal_tcl_encap_type +enum hal_tcl_encap_type ath11k_dp_tx_get_encap_type(struct ath11k_vif *arvif, struct sk_buff *skb) @@ -1038,7 +1023,7 @@ Signed-off-by: Sriram R struct htt_rx_ring_tlv_filter *tlv_filter); +enum hal_tcl_encap_type +ath11k_dp_tx_get_encap_type(struct ath11k_vif *arvif, struct sk_buff *skb); - + int ath11k_dp_tx_htt_rx_full_mon_setup(struct ath11k_base *ab, int mac_id, bool config); --- a/drivers/net/wireless/ath/ath11k/nss.c @@ -1053,18 +1038,18 @@ Signed-off-by: Sriram R #include "wmi.h" #include "../../../../../net/mac80211/sta_info.h" @@ -465,7 +467,7 @@ deliver_amsdu: - + /* create list containing all the subframes */ ieee80211_amsdu_to_8023s(skb, &subframe_list, NULL, - vif->type, 0, NULL, NULL); + vif->type, 0, NULL, NULL, false); - + /* This shouldn't happen, indicating error during defragmentation */ if (skb_queue_empty(&subframe_list)) @@ -657,12 +659,14 @@ drop: return -EINVAL; } - + -int ath11k_nss_vdev_set_cmd(struct ath11k_vif *arvif, int cmd, int val) +int ath11k_nss_vdev_set_cmd(struct ath11k_vif *arvif, enum ath11k_nss_vdev_cmd nss_cmd, + int val) @@ -1074,13 +1059,13 @@ Signed-off-by: Sriram R struct ath11k *ar = arvif->ar; nss_tx_status_t status; + int cmd; - + if (!ar->ab->nss.enabled) return 0; @@ -675,6 +679,22 @@ int ath11k_nss_vdev_set_cmd(struct ath11 if (!vdev_msg) return -ENOMEM; - + + switch(nss_cmd) { + case ATH11K_NSS_WIFI_VDEV_CFG_AP_BRIDGE_CMD: + cmd = NSS_WIFI_VDEV_CFG_AP_BRIDGE_CMD; @@ -1107,17 +1092,17 @@ Signed-off-by: Sriram R - int tid_idx; struct ath11k *ar = arsta->arvif->ar; struct ath11k_base *ab = ar->ab; - + @@ -1230,6 +1249,9 @@ void ath11k_nss_update_sta_rxrate(struct if (!ab->nss.enabled) return; - + + if (!ieee80211_is_data(__cpu_to_le16(ppdu_info->frame_control))) + return; + if (!peer->nss.nss_stats) return; - + @@ -1289,7 +1311,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; @@ -1132,7 +1117,7 @@ Signed-off-by: Sriram R @@ -101,6 +101,13 @@ do { \ u64_stats_update_end(&tstats->syncp); \ } while (0) - + +enum ath11k_nss_vdev_cmd { + ATH11K_NSS_WIFI_VDEV_CFG_AP_BRIDGE_CMD, + ATH11K_NSS_WIFI_VDEV_SECURITY_TYPE_CMD, @@ -1144,7 +1129,7 @@ Signed-off-by: Sriram R ATH11K_NSS_OPMODE_UNKNOWN, ATH11K_NSS_OPMODE_AP, @@ -190,7 +197,8 @@ struct ath11k_soc_nss { - + #ifdef CPTCFG_ATH11K_NSS_SUPPORT int ath11k_nss_tx(struct ath11k_vif *arvif, struct sk_buff *skb); -int ath11k_nss_vdev_set_cmd(struct ath11k_vif *arvif, int cmd, int val); @@ -1156,7 +1141,7 @@ Signed-off-by: Sriram R @@ -217,7 +225,8 @@ static inline int ath11k_nss_tx(struct a return 0; } - + -static inline int ath11k_nss_vdev_set_cmd(struct ath11k_vif *arvif, int cmd, int val) +static inline int ath11k_nss_vdev_set_cmd(struct ath11k_vif *arvif, enum ath11k_nss_vdev_cmd cmd, + int val) @@ -1166,7 +1151,7 @@ Signed-off-by: Sriram R --- a/drivers/net/wireless/ath/ath11k/hw.c +++ b/drivers/net/wireless/ath/ath11k/hw.c @@ -104,8 +104,10 @@ static void ath11k_init_wmi_config_qca63 - + static void ath11k_hw_ipq8074_reo_setup(struct ath11k_base *ab) { + u8 frag_dest_ring = HAL_SRNG_RING_ID_REO2SW1; @@ -1179,12 +1164,12 @@ Signed-off-by: Sriram R @@ -116,11 +118,14 @@ static void ath11k_hw_ipq8074_reo_setup( HAL_HASH_ROUTING_RING_SW3 << 18 | HAL_HASH_ROUTING_RING_SW4 << 21; - + + if (ab->nss.enabled) + frag_dest_ring = HAL_SRNG_REO_ALTERNATE_SELECT; + val = ath11k_hif_read32(ab, reo_base + HAL_REO1_GEN_ENABLE); - + val &= ~HAL_REO1_GEN_ENABLE_FRAG_DST_RING; val |= FIELD_PREP(HAL_REO1_GEN_ENABLE_FRAG_DST_RING, - HAL_SRNG_RING_ID_REO2SW1) | @@ -1195,7 +1180,7 @@ Signed-off-by: Sriram R @@ -134,6 +139,10 @@ static void ath11k_hw_ipq8074_reo_setup( ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_3(ab), HAL_DEFAULT_REO_TIMEOUT_USEC); - + + /* REO Dest ring setup is not required in NSS offload case */ + if (ab->nss.enabled) + return; @@ -1204,7 +1189,7 @@ Signed-off-by: Sriram R FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP, ring_hash_map)); @@ -758,8 +767,10 @@ static u8 *ath11k_hw_wcn6855_rx_desc_mpd - + static void ath11k_hw_wcn6855_reo_setup(struct ath11k_base *ab) { + u8 frag_dest_ring = HAL_SRNG_RING_ID_REO2SW1; @@ -1217,7 +1202,7 @@ Signed-off-by: Sriram R @@ -770,6 +781,9 @@ static void ath11k_hw_wcn6855_reo_setup( HAL_HASH_ROUTING_RING_SW3 << 24 | HAL_HASH_ROUTING_RING_SW4 << 28; - + + if (ab->nss.enabled) + frag_dest_ring = HAL_SRNG_REO_ALTERNATE_SELECT; + @@ -1225,18 +1210,18 @@ Signed-off-by: Sriram R val |= FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_LIST_ENABLE, 1) | FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_FLUSH_ENABLE, 1); @@ -777,7 +791,7 @@ static void ath11k_hw_wcn6855_reo_setup( - + val = ath11k_hif_read32(ab, reo_base + HAL_REO1_MISC_CTL(ab)); val &= ~HAL_REO1_MISC_CTL_FRAGMENT_DST_RING; - val |= FIELD_PREP(HAL_REO1_MISC_CTL_FRAGMENT_DST_RING, HAL_SRNG_RING_ID_REO2SW1); + val |= FIELD_PREP(HAL_REO1_MISC_CTL_FRAGMENT_DST_RING, frag_dest_ring); ath11k_hif_write32(ab, reo_base + HAL_REO1_MISC_CTL(ab), val); - + ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_0(ab), @@ -789,6 +803,10 @@ static void ath11k_hw_wcn6855_reo_setup( ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_3(ab), HAL_DEFAULT_REO_TIMEOUT_USEC); - + + /* REO Dest ring setup is not required in NSS offload case */ + if (ab->nss.enabled) + return; @@ -1249,7 +1234,7 @@ Signed-off-by: Sriram R @@ -571,6 +571,12 @@ static int ath11k_pcic_ext_irq_config(st netif_napi_add(&irq_grp->napi_ndev, &irq_grp->napi, ath11k_pcic_ext_grp_napi_poll); - + + /* tcl, reo, rx_err, wbm release, rxdma rings are offloaded to nss. */ + if (ab->nss.enabled && + !(ab->hw_params.ring_mask->reo_status[i] || diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-004-ath10k-add-nss-driver-interface.patch b/package/kernel/mac80211/patches/ath11k_nss/199-004-ath10k-add-nss-driver-interface.patch index bf116d15b2afb4..ecf5ee16c80cf7 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-004-ath10k-add-nss-driver-interface.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/199-004-ath10k-add-nss-driver-interface.patch @@ -1,6 +1,14 @@ --- 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 +@@ -24,7 +24,6 @@ + #include "wmi-tlv.h" + #include "wmi-ops.h" + #include "wow.h" +-#include "leds.h" + + /*********/ + /* Rates */ +@@ -5530,7 +5529,7 @@ static int ath10k_mac_set_txbf_conf(stru ar->wmi.vdev_param->txbf, value); } @@ -9,7 +17,7 @@ struct ieee80211_vif *vif) { struct ath10k_vif *arvif = (void *)vif->drv_priv; -@@ -5552,6 +5552,8 @@ static void ath10k_update_vif_offload(st +@@ -5552,6 +5551,8 @@ static void ath10k_update_vif_offload(st ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n", arvif->vdev_id, ret); } diff --git a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch new file mode 100644 index 00000000000000..af46c8f0bfa05e --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch @@ -0,0 +1,60 @@ +From f013e1e9829ec346fa0a215552eef51953b46bf0 Mon Sep 17 00:00:00 2001 +From: Seevalamuthu Mariappan +Date: Fri, 7 Aug 2020 18:24:32 +0530 +Subject: [PATCH] ath11k: Add support for dynamic vlan + +This patch adds support for dynamic vlan. VLAN group traffics +are encrypted in software. vlan unicast packets shall be taking +8023 xmit path if encap offload is enabled and mcast/bcast will +be using 80211 xmit path. + +Metadata info in dp_tx added to notify firmware that the +multicast/broadcast packets are encrypted in sw. + +Signed-off-by: Seevalamuthu Mariappan +Signed-off-by: Gautham Kumar Senthilkumaran +--- + net/mac80211/tx.c | 14 +++ + 1 files changed, 14 insertions(+) + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -37,6 +37,9 @@ + #include "wme.h" + #include "rate.h" + ++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); + /* misc utils */ + + static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, +@@ -4268,6 +4271,8 @@ void __ieee80211_subif_start_xmit(struct + struct sta_info *sta; + struct sk_buff *next; + int len = skb->len; ++ struct ieee80211_key *key = NULL; ++ struct ieee80211_sub_if_data *ap_sdata; + + if (unlikely(!ieee80211_sdata_running(sdata) || skb->len < ETH_HLEN)) { + kfree_skb(skb); +@@ -4289,6 +4294,19 @@ void __ieee80211_subif_start_xmit(struct + if (IS_ERR(sta)) + sta = NULL; + ++ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { ++ ap_sdata = container_of(sdata->bss, ++ struct ieee80211_sub_if_data, u.ap); ++ if (ap_sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED && ++ !is_multicast_ether_addr(skb->data)) { ++ if (sta) ++ key = rcu_dereference(sta->ptk[sta->ptk_idx]); ++ ieee80211_8023_xmit(sdata, dev, sta, key, skb); ++ rcu_read_unlock(); ++ return; ++ } ++ } ++ + skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb)); + ieee80211_aggr_check(sdata, sta, skb); + diff --git a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-512MB-profile-in-ath11k.patch b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-512MB-profile-in-ath11k.patch index 44ab73377b1232..41c9bf698b3f87 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-512MB-profile-in-ath11k.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-512MB-profile-in-ath11k.patch @@ -236,7 +236,15 @@ Signed-off-by: Ramya Gnanasekar static struct ath11k_hw_params ath11k_hw_params[] = { { .hw_rev = ATH11K_HW_IPQ8074, -@@ -177,7 +182,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -100,6 +105,7 @@ static struct ath11k_hw_params ath11k_hw + .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, +@@ -177,7 +183,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = true, .coldboot_cal_ftm = true, .cbcal_restart_fw = true, @@ -245,7 +253,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = false, -@@ -259,7 +264,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -259,7 +265,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -254,7 +262,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -426,7 +431,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -426,7 +432,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -263,7 +271,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -509,7 +514,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -509,7 +515,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -272,7 +280,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -593,7 +598,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -593,7 +599,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = true, .coldboot_cal_ftm = true, .cbcal_restart_fw = false, @@ -281,7 +289,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = false, -@@ -672,7 +677,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -672,7 +678,7 @@ static struct ath11k_hw_params ath11k_hw .supports_monitor = false, .supports_sta_ps = false, .supports_shadow_regs = false, @@ -290,7 +298,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_regdb = false, -@@ -710,7 +715,23 @@ static struct ath11k_hw_params ath11k_hw +@@ -710,7 +716,23 @@ static struct ath11k_hw_params ath11k_hw }, }; @@ -315,7 +323,7 @@ Signed-off-by: Ramya Gnanasekar { WARN_ON(!ab->hw_params.single_pdev_only); -@@ -794,8 +815,10 @@ int ath11k_core_suspend(struct ath11k_ba +@@ -794,8 +816,10 @@ int ath11k_core_suspend(struct ath11k_ba ret = ath11k_dp_rx_pktlog_stop(ab, true); if (ret) { @@ -328,7 +336,7 @@ Signed-off-by: Ramya Gnanasekar return ret; } -@@ -807,13 +830,15 @@ int ath11k_core_suspend(struct ath11k_ba +@@ -807,13 +831,15 @@ int ath11k_core_suspend(struct ath11k_ba ret = ath11k_wow_enable(ab); if (ret) { @@ -346,7 +354,7 @@ Signed-off-by: Ramya Gnanasekar ret); return ret; } -@@ -853,7 +878,8 @@ int ath11k_core_resume(struct ath11k_bas +@@ -853,7 +879,8 @@ int ath11k_core_resume(struct ath11k_bas ret = ath11k_hif_resume(ab); if (ret) { @@ -356,7 +364,7 @@ Signed-off-by: Ramya Gnanasekar return ret; } -@@ -869,7 +895,8 @@ int ath11k_core_resume(struct ath11k_bas +@@ -869,7 +896,8 @@ int ath11k_core_resume(struct ath11k_bas ret = ath11k_wow_wakeup(ab); if (ret) { @@ -366,7 +374,7 @@ Signed-off-by: Ramya Gnanasekar return ret; } -@@ -877,7 +904,8 @@ int ath11k_core_resume(struct ath11k_bas +@@ -877,7 +905,8 @@ int ath11k_core_resume(struct ath11k_bas } EXPORT_SYMBOL(ath11k_core_resume); @@ -376,7 +384,7 @@ Signed-off-by: Ramya Gnanasekar { struct ath11k_base *ab = data; const char *magic = ATH11K_SMBIOS_BDF_EXT_MAGIC; -@@ -914,7 +942,8 @@ static void ath11k_core_check_cc_code_bd +@@ -914,7 +943,8 @@ static void ath11k_core_check_cc_code_bd ath11k_dbg(ab, ATH11K_DBG_BOOT, "smbios worldwide regdomain\n"); break; default: @@ -386,7 +394,7 @@ Signed-off-by: Ramya Gnanasekar smbios->country_code_flag); break; } -@@ -922,7 +951,8 @@ static void ath11k_core_check_cc_code_bd +@@ -922,7 +952,8 @@ static void ath11k_core_check_cc_code_bd spin_unlock_bh(&ab->base_lock); if (!smbios->bdf_enabled) { @@ -396,7 +404,7 @@ Signed-off-by: Ramya Gnanasekar return; } -@@ -933,22 +963,26 @@ static void ath11k_core_check_cc_code_bd +@@ -933,22 +964,26 @@ static void ath11k_core_check_cc_code_bd return; } @@ -431,7 +439,7 @@ Signed-off-by: Ramya Gnanasekar return; } -@@ -984,9 +1018,10 @@ int ath11k_core_check_dt(struct ath11k_b +@@ -984,9 +1019,10 @@ int ath11k_core_check_dt(struct ath11k_b return -ENODATA; if (strscpy(ab->qmi.target.bdf_ext, variant, max_len) < 0) @@ -445,7 +453,7 @@ Signed-off-by: Ramya Gnanasekar return 0; } -@@ -1012,24 +1047,20 @@ static int __ath11k_core_create_board_na +@@ -1012,24 +1048,20 @@ static int __ath11k_core_create_board_na case ATH11K_BDF_SEARCH_BUS_AND_BOARD: switch (name_type) { case ATH11K_BDF_NAME_FULL: @@ -479,7 +487,7 @@ Signed-off-by: Ramya Gnanasekar ath11k_bus_str(ab->hif.bus), ab->qmi.target.chip_id); break; -@@ -1038,8 +1069,7 @@ static int __ath11k_core_create_board_na +@@ -1038,8 +1070,7 @@ static int __ath11k_core_create_board_na default: scnprintf(name, name_len, "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s", @@ -489,7 +497,7 @@ Signed-off-by: Ramya Gnanasekar ab->qmi.target.board_id, variant); break; } -@@ -1056,22 +1086,22 @@ static int ath11k_core_create_board_name +@@ -1056,22 +1087,22 @@ static int ath11k_core_create_board_name ATH11K_BDF_NAME_FULL); } @@ -518,7 +526,7 @@ Signed-off-by: Ramya Gnanasekar { return __ath11k_core_create_board_name(ab, name, name_len, false, ATH11K_BDF_NAME_CHIP_ID); -@@ -1093,8 +1123,8 @@ const struct firmware *ath11k_core_firmw +@@ -1093,8 +1124,8 @@ const struct firmware *ath11k_core_firmw if (ret) return ERR_PTR(ret); @@ -529,7 +537,7 @@ Signed-off-by: Ramya Gnanasekar return fw; } -@@ -1110,10 +1140,8 @@ void ath11k_core_free_bdf(struct ath11k_ +@@ -1110,10 +1141,8 @@ void ath11k_core_free_bdf(struct ath11k_ static int ath11k_core_parse_bd_ie_board(struct ath11k_base *ab, struct ath11k_board_data *bd, const void *buf, size_t buf_len, @@ -542,7 +550,7 @@ Signed-off-by: Ramya Gnanasekar { const struct ath11k_fw_ie *hdr; bool name_match_found; -@@ -1135,8 +1163,8 @@ static int ath11k_core_parse_bd_ie_board +@@ -1135,8 +1164,8 @@ static int ath11k_core_parse_bd_ie_board if (buf_len < ALIGN(board_ie_len, 4)) { ath11k_err(ab, "invalid %s length: %zu < %zu\n", @@ -553,7 +561,7 @@ Signed-off-by: Ramya Gnanasekar ret = -EINVAL; goto out; } -@@ -1148,24 +1176,22 @@ static int ath11k_core_parse_bd_ie_board +@@ -1148,24 +1177,22 @@ static int ath11k_core_parse_bd_ie_board if (board_ie_len != strlen(boardname)) goto next; @@ -583,7 +591,7 @@ Signed-off-by: Ramya Gnanasekar bd->data = board_ie_data; bd->len = board_ie_len; -@@ -1174,8 +1200,7 @@ static int ath11k_core_parse_bd_ie_board +@@ -1174,8 +1201,7 @@ static int ath11k_core_parse_bd_ie_board goto out; } else { ath11k_warn(ab, "unknown %s id found: %d\n", @@ -593,7 +601,7 @@ Signed-off-by: Ramya Gnanasekar } next: /* jump over the padding */ -@@ -1195,8 +1220,7 @@ out: +@@ -1195,8 +1221,7 @@ out: static int ath11k_core_fetch_board_data_api_n(struct ath11k_base *ab, struct ath11k_board_data *bd, const char *boardname, @@ -603,7 +611,7 @@ Signed-off-by: Ramya Gnanasekar int data_id) { size_t len, magic_len; -@@ -1217,14 +1241,16 @@ static int ath11k_core_fetch_board_data_ +@@ -1217,14 +1242,16 @@ static int ath11k_core_fetch_board_data_ data = bd->fw->data; len = bd->fw->size; @@ -624,7 +632,7 @@ Signed-off-by: Ramya Gnanasekar ret = -EINVAL; goto err; } -@@ -1238,8 +1264,10 @@ static int ath11k_core_fetch_board_data_ +@@ -1238,8 +1265,10 @@ static int ath11k_core_fetch_board_data_ /* magic is padded to 4 bytes */ magic_len = ALIGN(magic_len, 4); if (len < magic_len) { @@ -637,7 +645,7 @@ Signed-off-by: Ramya Gnanasekar ret = -EINVAL; goto err; } -@@ -1256,19 +1284,19 @@ static int ath11k_core_fetch_board_data_ +@@ -1256,19 +1285,19 @@ static int ath11k_core_fetch_board_data_ data = hdr->data; if (len < ALIGN(ie_len, 4)) { @@ -663,7 +671,7 @@ Signed-off-by: Ramya Gnanasekar if (ret == -ENOENT) /* no match found, continue */ goto next; -@@ -1290,8 +1318,8 @@ out: +@@ -1290,8 +1319,8 @@ out: if (!bd->data || !bd->len) { ath11k_dbg(ab, ATH11K_DBG_BOOT, "failed to fetch %s for %s from %s\n", @@ -674,7 +682,7 @@ Signed-off-by: Ramya Gnanasekar ret = -ENODATA; goto err; } -@@ -1321,7 +1349,8 @@ int ath11k_core_fetch_board_data_api_1(s +@@ -1321,7 +1350,8 @@ int ath11k_core_fetch_board_data_api_1(s #define BOARD_NAME_SIZE 200 int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd) { @@ -684,7 +692,7 @@ Signed-off-by: Ramya Gnanasekar char *filename, filepath[100]; int ret = 0; -@@ -1388,15 +1417,18 @@ int ath11k_core_fetch_bdf(struct ath11k_ +@@ -1388,15 +1418,18 @@ int ath11k_core_fetch_bdf(struct ath11k_ goto exit; ab->bd_api = 1; @@ -708,7 +716,7 @@ Signed-off-by: Ramya Gnanasekar ath11k_err(ab, "failed to fetch board data for %s from %s\n", chip_id_boardname, filepath); -@@ -1411,12 +1443,14 @@ exit: +@@ -1411,12 +1444,14 @@ exit: kfree(chip_id_boardname); if (!ret) @@ -725,7 +733,7 @@ Signed-off-by: Ramya Gnanasekar { char boardname[BOARD_NAME_SIZE], default_boardname[BOARD_NAME_SIZE]; int ret; -@@ -1439,7 +1473,8 @@ int ath11k_core_fetch_regdb(struct ath11 +@@ -1439,7 +1474,8 @@ int ath11k_core_fetch_regdb(struct ath11 BOARD_NAME_SIZE); if (ret) { ath11k_dbg(ab, ATH11K_DBG_BOOT, @@ -735,7 +743,7 @@ Signed-off-by: Ramya Gnanasekar goto exit; } -@@ -1450,7 +1485,8 @@ int ath11k_core_fetch_regdb(struct ath11 +@@ -1450,7 +1486,8 @@ int ath11k_core_fetch_regdb(struct ath11 if (!ret) goto exit; @@ -745,7 +753,7 @@ Signed-off-by: Ramya Gnanasekar if (ret) ath11k_dbg(ab, ATH11K_DBG_BOOT, "failed to fetch %s from %s\n", ATH11K_REGDB_FILE_NAME, ab->hw_params.fw.dir); -@@ -1542,14 +1578,14 @@ static int ath11k_core_pdev_create(struc +@@ -1542,14 +1579,14 @@ static int ath11k_core_pdev_create(struc ret = ath11k_mac_register(ab); if (ret) { @@ -763,7 +771,7 @@ Signed-off-by: Ramya Gnanasekar goto err_mac_unregister; } -@@ -1637,14 +1673,16 @@ static int ath11k_core_start(struct ath1 +@@ -1637,14 +1674,16 @@ static int ath11k_core_start(struct ath1 ret = ath11k_wmi_wait_for_service_ready(ab); if (ret) { @@ -782,7 +790,7 @@ Signed-off-by: Ramya Gnanasekar ret); goto err_hif_stop; } -@@ -1653,7 +1691,9 @@ static int ath11k_core_start(struct ath1 +@@ -1653,7 +1692,9 @@ static int ath11k_core_start(struct ath1 ret = ath11k_dp_pdev_reo_setup(ab); if (ret) { @@ -793,7 +801,7 @@ Signed-off-by: Ramya Gnanasekar goto err_mac_destroy; } -@@ -1665,13 +1705,15 @@ static int ath11k_core_start(struct ath1 +@@ -1665,13 +1706,15 @@ static int ath11k_core_start(struct ath1 ret = ath11k_wmi_wait_for_unified_ready(ab); if (ret) { @@ -811,7 +819,7 @@ Signed-off-by: Ramya Gnanasekar ret = ath11k_wmi_set_hw_mode(ab, WMI_HOST_HW_MODE_DBS); if (ret) { ath11k_err(ab, "failed to send dbs mode: %d\n", ret); -@@ -1681,7 +1723,8 @@ static int ath11k_core_start(struct ath1 +@@ -1681,7 +1724,8 @@ static int ath11k_core_start(struct ath1 ret = ath11k_dp_tx_htt_h2t_ver_req_msg(ab); if (ret) { @@ -821,7 +829,7 @@ Signed-off-by: Ramya Gnanasekar ret); goto err_reo_cleanup; } -@@ -1749,7 +1792,8 @@ int ath11k_core_qmi_firmware_ready(struc +@@ -1749,7 +1793,8 @@ int ath11k_core_qmi_firmware_ready(struc clear_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags); break; default: @@ -831,7 +839,7 @@ Signed-off-by: Ramya Gnanasekar return -EINVAL; } -@@ -1850,7 +1894,8 @@ void ath11k_core_halt(struct ath11k *ar) +@@ -1850,7 +1895,8 @@ void ath11k_core_halt(struct ath11k *ar) static void ath11k_update_11d(struct work_struct *work) { @@ -841,7 +849,7 @@ Signed-off-by: Ramya Gnanasekar struct ath11k *ar; struct ath11k_pdev *pdev; struct wmi_set_current_country_params set_current_param = {}; -@@ -1861,19 +1906,20 @@ static void ath11k_update_11d(struct wor +@@ -1861,19 +1907,20 @@ static void ath11k_update_11d(struct wor spin_unlock_bh(&ab->base_lock); ath11k_dbg(ab, ATH11K_DBG_WMI, "update 11d new cc %c%c\n", @@ -868,7 +876,7 @@ Signed-off-by: Ramya Gnanasekar } } -@@ -1910,8 +1956,8 @@ void ath11k_core_pre_reconfigure_recover +@@ -1910,8 +1957,8 @@ void ath11k_core_pre_reconfigure_recover complete(&ar->thermal.wmi_sync); wake_up(&ar->dp.tx_empty_waitq); @@ -879,7 +887,7 @@ Signed-off-by: Ramya Gnanasekar idr_destroy(&ar->txmgmt_idr); wake_up(&ar->txmgmt_empty_waitq); -@@ -1947,9 +1993,10 @@ static void ath11k_core_post_reconfigure +@@ -1947,9 +1994,10 @@ static void ath11k_core_post_reconfigure ieee80211_restart_hw(ar->hw); break; case ATH11K_STATE_OFF: @@ -893,7 +901,7 @@ Signed-off-by: Ramya Gnanasekar break; case ATH11K_STATE_RESTARTING: break; -@@ -1957,8 +2004,10 @@ static void ath11k_core_post_reconfigure +@@ -1957,8 +2005,10 @@ static void ath11k_core_post_reconfigure ar->state = ATH11K_STATE_WEDGED; fallthrough; case ATH11K_STATE_WEDGED: @@ -906,7 +914,7 @@ Signed-off-by: Ramya Gnanasekar break; case ATH11K_STATE_FTM: ath11k_dbg(ab, ATH11K_DBG_TESTMODE, -@@ -1973,12 +2022,14 @@ static void ath11k_core_post_reconfigure +@@ -1973,12 +2023,14 @@ static void ath11k_core_post_reconfigure static void ath11k_core_restart(struct work_struct *work) { @@ -923,7 +931,7 @@ Signed-off-by: Ramya Gnanasekar return; } -@@ -1991,12 +2042,14 @@ static void ath11k_core_restart(struct w +@@ -1991,12 +2043,14 @@ static void ath11k_core_restart(struct w static void ath11k_core_reset(struct work_struct *work) { @@ -940,7 +948,7 @@ Signed-off-by: Ramya Gnanasekar return; } -@@ -2022,8 +2075,8 @@ static void ath11k_core_reset(struct wor +@@ -2022,8 +2076,8 @@ static void ath11k_core_reset(struct wor ath11k_warn(ab, "already resetting count %d\n", reset_count); reinit_completion(&ab->reset_complete); @@ -951,7 +959,7 @@ Signed-off-by: Ramya Gnanasekar if (time_left) { ath11k_dbg(ab, ATH11K_DBG_BOOT, "to skip reset\n"); -@@ -2050,8 +2103,8 @@ static void ath11k_core_reset(struct wor +@@ -2050,8 +2104,8 @@ static void ath11k_core_reset(struct wor ath11k_dbg(ab, ATH11K_DBG_BOOT, "waiting recovery start...\n"); @@ -962,7 +970,7 @@ Signed-off-by: Ramya Gnanasekar ath11k_hif_power_down(ab); ath11k_hif_power_up(ab); -@@ -2073,22 +2126,21 @@ static int ath11k_init_hw_params(struct +@@ -2073,22 +2127,21 @@ static int ath11k_init_hw_params(struct } if (i == ARRAY_SIZE(ath11k_hw_params)) { @@ -989,7 +997,7 @@ Signed-off-by: Ramya Gnanasekar ab->hw_params.fw_mem_mode = 1; ab->hw_params.num_vdevs = 8; ab->hw_params.num_peers = 128; -@@ -2099,7 +2151,8 @@ static int ath11k_init_hw_params(struct +@@ -2099,7 +2152,8 @@ static int ath11k_init_hw_params(struct ab->hw_params.coldboot_cal_mm = false; ab->hw_params.coldboot_cal_ftm = false; } else @@ -999,7 +1007,7 @@ Signed-off-by: Ramya Gnanasekar } ath11k_info(ab, "%s\n", ab->hw_params.name); -@@ -2215,5 +2268,6 @@ err_sc_free: +@@ -2215,5 +2269,6 @@ err_sc_free: } EXPORT_SYMBOL(ath11k_core_alloc); @@ -1007,3 +1015,20 @@ Signed-off-by: Ramya Gnanasekar +MODULE_DESCRIPTION( + "Core module for Qualcomm Atheros 802.11ax wireless LAN cards."); MODULE_LICENSE("Dual BSD/GPL"); +--- a/drivers/net/wireless/ath/ath11k/debugfs.c ++++ b/drivers/net/wireless/ath/ath11k/debugfs.c +@@ -1592,10 +1592,13 @@ static ssize_t ath11k_dump_mgmt_stats(st + size_t count, loff_t *ppos) + { + struct ath11k *ar = file->private_data; ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M ++ struct ath11k_base *ab = ar->ab; ++#endif + 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/207-mac80211-add-nss-redirect-support.patch b/package/kernel/mac80211/patches/ath11k_nss/207-mac80211-add-nss-redirect-support.patch new file mode 100644 index 00000000000000..c9a12d5f127cbe --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/207-mac80211-add-nss-redirect-support.patch @@ -0,0 +1,268 @@ +From 3acca4ecfe25a7d97e7cb820fd8c7c6324a1f318 Mon Sep 17 00:00:00 2001 +From: Sowmiya Sree Elavalagan +Date: Tue, 18 Aug 2020 16:17:25 +0530 +Subject: [PATCH] ath11k : Add NSS redirect support + +Add NSS Redirect support for ath11k. Tested on ipq8074 +Most of the changes are similar to the one done for ath10k with +minor changes to send to nss with eth header + +Redirect can be enabled by setting nss_redirect module param during +mac80211 insmod followed by ecm start +insmod mac80211.ko nss_redirect=1 +/etc/init.d/qca-nss-ecm start + +Check for ipv4_hash_hits counts in ipv4 stats and eth_rx +in qca-nss-drv to check whether packets are redirected or not. + +Verified both in nwifi and ethernet mode by running tcp and udp +traffic. + +Co-developed by: Sriram R +Signed-off-by: Sriram R +Signed-off-by: Sowmiya Sree Elavalagan +--- + net/mac80211/ieee80211_i.h | 2 ++ + net/mac80211/iface.c | 43 ++++++++++++++++++++++++++++++++ + net/mac80211/rx.c | 61 +++++++++++++++++++++++++++++++++++++--------- + net/mac80211/tx.c | 32 ++++++++++++++++++++++++ + 4 files changed, 126 insertions(+), 12 deletions(-) + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -34,6 +34,9 @@ + #include "sta_info.h" + #include "debug.h" + #include "drop.h" ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++#include ++#endif + + extern const struct cfg80211_ops mac80211_config_ops; + +@@ -1120,6 +1123,9 @@ struct ieee80211_sub_if_data { + struct dentry *default_beacon_key; + } debugfs; + #endif ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++ struct nss_virt_if_handle *nssctx; ++#endif + + /* must be last, dynamically sized area in this! */ + struct ieee80211_vif vif; +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -27,6 +27,12 @@ + #include "wme.h" + #include "rate.h" + ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++bool nss_redirect = false; ++module_param(nss_redirect, bool, 0644); ++MODULE_PARM_DESC(nss_redirect, "module param to enable NSS Redirect; 1-enable, 0-disable"); ++#endif ++ + /** + * DOC: Interface list locking + * +@@ -752,6 +758,13 @@ static int ieee80211_stop(struct net_dev + + cancel_work_sync(&sdata->activate_links_work); + ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++ if (sdata->nssctx) { ++ nss_virt_if_destroy_sync(sdata->nssctx); ++ sdata_info(sdata, "Destroyed NSS virtual interface\n"); ++ } ++#endif ++ + wiphy_lock(sdata->local->hw.wiphy); + ieee80211_do_stop(sdata, true); + wiphy_unlock(sdata->local->hw.wiphy); +@@ -1219,6 +1232,34 @@ void ieee80211_del_virtual_monitor(struc + kfree(sdata); + } + ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++/* This callback is registered for nss redirect to receive packet exceptioned from nss in Rx path. ++ * When packet does not match any of the ecm rules is redirected back here. ++ */ ++void receive_from_nss(struct net_device *dev, struct sk_buff *sk_buff, struct napi_struct *napi) ++{ ++ struct net_device *netdev; ++ struct sk_buff *skb; ++ struct ieee80211_sub_if_data *sdata; ++ ++ if (!dev) { ++ kfree(sk_buff); ++ return; ++ } ++ ++ netdev = (struct net_device *)dev; ++ sdata = netdev_priv(netdev); ++ if (sdata->dev != dev) { ++ kfree(sk_buff); ++ return; ++ } ++ skb = (struct sk_buff *)sk_buff; ++ skb->dev = netdev; ++ skb->protocol = eth_type_trans(skb, netdev); ++ napi_gro_receive(napi, skb); ++} ++#endif ++ + /* + * NOTE: Be very careful when changing this function, it must NOT return + * an error on interface type changes that have been pre-checked, so most +@@ -1450,6 +1491,19 @@ int ieee80211_do_open(struct wireless_de + + ieee80211_recalc_ps(local); + ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++ sdata->nssctx = NULL; ++ if (nss_redirect) { ++ sdata->nssctx = nss_virt_if_create_sync(dev); ++ if (sdata->nssctx) { ++ sdata_info(sdata, "Created a NSS virtual interface\n"); ++ nss_virt_if_register(sdata->nssctx, receive_from_nss, sdata->dev); ++ } else { ++ sdata_info(sdata, "Failed to create a NSS virtual interface\n"); ++ } ++ } ++#endif ++ + set_bit(SDATA_STATE_RUNNING, &sdata->state); + + return 0; +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -2570,6 +2570,54 @@ static bool ieee80211_frame_allowed(stru + return true; + } + ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++#define case_rtn_string(val) case val: return #val ++ ++static const char *nss_tx_status_str(nss_tx_status_t status) ++{ ++ switch (status) { ++ case_rtn_string(NSS_TX_SUCCESS); ++ case_rtn_string(NSS_TX_FAILURE); ++ case_rtn_string(NSS_TX_FAILURE_QUEUE); ++ case_rtn_string(NSS_TX_FAILURE_NOT_READY); ++ case_rtn_string(NSS_TX_FAILURE_TOO_LARGE); ++ case_rtn_string(NSS_TX_FAILURE_TOO_SHORT); ++ case_rtn_string(NSS_TX_FAILURE_NOT_SUPPORTED); ++ case_rtn_string(NSS_TX_FAILURE_BAD_PARAM); ++ default: ++ return "Unknown NSS TX status"; ++ } ++} ++ ++static void netif_rx_nss(struct ieee80211_rx_data *rx, ++ struct sk_buff *skb) ++{ ++ struct ieee80211_sub_if_data *sdata = rx->sdata; ++ int ret; ++ ++ if (!sdata->nssctx) ++ goto out; ++ ++ /* NSS expects ethernet header in skb data so resetting here */ ++ skb_push(skb, ETH_HLEN); ++ ret = nss_virt_if_tx_buf(sdata->nssctx, skb); ++ if (ret) { ++ if (net_ratelimit()) { ++ sdata_err(sdata, "NSS TX failed with error: %s\n", ++ nss_tx_status_str(ret)); ++ } ++ goto out; ++ } ++ ++ return; ++out: ++ if (rx->napi) ++ napi_gro_receive(rx->napi, skb); ++ else ++ netif_receive_skb(skb); ++} ++#endif ++ + 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 + !ether_addr_equal(ehdr->h_dest, sdata->vif.addr))) + ether_addr_copy(ehdr->h_dest, sdata->vif.addr); + ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++ netif_rx_nss(rx, skb); ++#else + /* deliver to local stack */ + if (rx->list) + list_add_tail(&skb->list, rx->list); + else + netif_receive_skb(skb); ++#endif + } + } + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -4501,6 +4501,35 @@ static void ieee80211_mlo_multicast_tx(s + kfree_skb(skb); + } + ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++void ieee80211_xmit_nss_fixup(struct sk_buff *skb, ++ struct net_device *dev) ++{ ++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); ++ ++ /* Packets from NSS does not have valid protocol, priority and other ++ * network stack values. Derive required parameters (priority ++ * and network_header) from payload for QoS header. ++ * XXX: Here the assumption is that packet are in 802.3 format. ++ * As of now priority is handled only for IPv4 and IPv6. ++ */ ++ ++ if (sdata->nssctx && likely(!skb->protocol)) { ++ skb_set_network_header(skb, 14); ++ switch (((struct ethhdr *)skb->data)->h_proto) { ++ case htons(ETH_P_IP): ++ skb->priority = (ipv4_get_dsfield(ip_hdr(skb)) & ++ 0xfc) >> 5; ++ break; ++ case htons(ETH_P_IPV6): ++ skb->priority = (ipv6_get_dsfield(ipv6_hdr(skb)) & ++ 0xfc) >> 5; ++ break; ++ } ++ } ++} ++#endif ++ + /** + * 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 + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + const struct ethhdr *eth = (void *)skb->data; + ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++ ieee80211_xmit_nss_fixup(skb, dev); ++#endif ++ + if (likely(!is_multicast_ether_addr(eth->h_dest))) + goto normal; + +@@ -4700,6 +4733,9 @@ netdev_tx_t ieee80211_subif_start_xmit_8 + struct ieee80211_key *key; + struct sta_info *sta; + ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++ ieee80211_xmit_nss_fixup(skb, dev); ++#endif + if (unlikely(!ieee80211_sdata_running(sdata) || skb->len < ETH_HLEN)) { + kfree_skb(skb); + return NETDEV_TX_OK; diff --git a/package/kernel/mac80211/patches/ath11k_nss/214-ath11k-qos-null-frame-tx-over-wmi.patch b/package/kernel/mac80211/patches/ath11k_nss/214-ath11k-qos-null-frame-tx-over-wmi.patch index a388aa24b7aab2..bd8bd86146e9f5 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/214-ath11k-qos-null-frame-tx-over-wmi.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/214-ath11k-qos-null-frame-tx-over-wmi.patch @@ -473,16 +473,15 @@ Signed-off-by: Sowmiya Sree Elavalagan u32 tlv_header; u32 tx_params_dword0; u32 tx_params_dword1; -@@ -4570,8 +4588,6 @@ struct wmi_pdev_bss_chan_info_event { +@@ -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 ppdu_id; - u32 ack_rssi; } __packed; #define WMI_VDEV_INSTALL_KEY_COMPL_STATUS_SUCCESS 0 -@@ -4919,7 +4935,7 @@ struct wmi_rssi_ctl_ext { +@@ -4918,7 +4935,7 @@ struct wmi_rssi_ctl_ext { u32 rssi_ctl_ext[MAX_ANTENNA_EIGHT - ATH_MAX_ANTENNA]; }; @@ -491,7 +490,7 @@ Signed-off-by: Sowmiya Sree Elavalagan u32 desc_id; u32 status; u32 pdev_id; -@@ -5750,6 +5766,17 @@ struct wmi_debug_log_config_cmd_fixed_pa +@@ -5748,6 +5765,17 @@ struct wmi_debug_log_config_cmd_fixed_pa u32 value; } __packed; @@ -509,7 +508,7 @@ Signed-off-by: Sowmiya Sree Elavalagan #define WMI_MAX_MEM_REQS 32 #define MAX_RADIOS 3 -@@ -6360,6 +6387,8 @@ int ath11k_wmi_cmd_send(struct ath11k_pd +@@ -6358,6 +6386,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/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch b/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch index cd8a57385f9542..72d27789b8c1e8 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch @@ -30,7 +30,17 @@ 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 -@@ -609,7 +609,7 @@ enum htt_ppdu_stats_tag_type { +@@ -219,7 +219,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 +-#define DP_RXDMA_REFILL_RING_SIZE 2048 ++#define DP_RXDMA_REFILL_RING_SIZE ATH11K_DP_RXDMA_REFILL_RING_SIZE ++#define DP_RXDMA_NSS_REFILL_RING_SIZE ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE + #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 { * * |31 26|25|24|23 16|15 8|7 0| * |-----------------+----------------+----------------+---------------| @@ -39,7 +49,7 @@ Signed-off-by: Ramya Gnanasekar * |-------------------------------------------------------------------| * | rsvd2 | ring_buffer_size | * |-------------------------------------------------------------------| -@@ -623,6 +623,14 @@ enum htt_ppdu_stats_tag_type { +@@ -623,6 +624,14 @@ enum htt_ppdu_stats_tag_type { * |-------------------------------------------------------------------| * | tlv_filter_in_flags | * |-------------------------------------------------------------------| @@ -54,7 +64,7 @@ Signed-off-by: Ramya Gnanasekar * Where: * PS = pkt_swap * SS = status_swap -@@ -636,6 +644,9 @@ enum htt_ppdu_stats_tag_type { +@@ -636,6 +645,9 @@ enum htt_ppdu_stats_tag_type { * 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 @@ -64,7 +74,7 @@ Signed-off-by: Ramya Gnanasekar * b'26: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 +676,42 @@ enum htt_ppdu_stats_tag_type { +@@ -665,6 +677,42 @@ enum htt_ppdu_stats_tag_type { * dword6 - b'0:31 - tlv_filter_in_flags: * Filter in Attention/MPDU/PPDU/Header/User tlvs * Refer to CFG_TLV_FILTER_IN_FLAG defs @@ -107,7 +117,7 @@ Signed-off-by: Ramya Gnanasekar */ #define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) -@@ -672,8 +719,16 @@ enum htt_ppdu_stats_tag_type { +@@ -672,8 +720,16 @@ enum htt_ppdu_stats_tag_type { #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) @@ -124,7 +134,7 @@ Signed-off-by: Ramya Gnanasekar enum htt_rx_filter_tlv_flags { HTT_RX_FILTER_TLV_FLAGS_MPDU_START = BIT(0), -@@ -977,6 +1032,14 @@ enum htt_rx_data_pkt_filter_tlv_flasg3 { +@@ -977,6 +1033,14 @@ enum htt_rx_data_pkt_filter_tlv_flasg3 { HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER | \ HTT_RX_FILTER_TLV_FLAGS_ATTENTION) @@ -139,7 +149,7 @@ Signed-off-by: Ramya Gnanasekar struct htt_rx_ring_selection_cfg_cmd { u32 info0; u32 info1; -@@ -985,6 +1048,10 @@ struct htt_rx_ring_selection_cfg_cmd { +@@ -985,6 +1049,10 @@ struct htt_rx_ring_selection_cfg_cmd { u32 pkt_type_en_flags2; u32 pkt_type_en_flags3; u32 rx_filter_tlv; @@ -150,7 +160,7 @@ Signed-off-by: Ramya Gnanasekar } __packed; struct htt_rx_ring_tlv_filter { -@@ -993,6 +1060,14 @@ struct htt_rx_ring_tlv_filter { +@@ -993,6 +1061,14 @@ struct htt_rx_ring_tlv_filter { u32 pkt_filter_flags1; /* MGMT */ u32 pkt_filter_flags2; /* CTRL */ u32 pkt_filter_flags3; /* DATA */ @@ -744,7 +754,28 @@ Signed-off-by: Ramya Gnanasekar --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h -@@ -129,6 +129,8 @@ enum ath11k_bus { +@@ -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 + #else + /* Num VDEVS per radio */ + #define TARGET_NUM_VDEVS(ab) (ab->hw_params.num_vdevs) +@@ -34,6 +39,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 ++#define ATH11K_DP_RXDMA_REFILL_RING_SIZE 2048 ++#define ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE 2048 + #endif + + /* Num of peers for Single Radio mode */ +@@ -129,6 +136,8 @@ enum ath11k_bus { struct hal_rx_desc; struct hal_tcl_data_cmd; @@ -753,7 +784,15 @@ Signed-off-by: Ramya Gnanasekar struct ath11k_hw_ring_mask { u8 tx[ATH11K_EXT_IRQ_GRP_NUM_MAX]; -@@ -285,6 +287,16 @@ struct ath11k_hw_ops { +@@ -218,6 +227,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; +@@ -285,6 +295,16 @@ 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); @@ -854,3 +893,14 @@ 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 + + /* fill rx parameters to initialize rx context */ + wim->wrip.tlv_size = ab->hw_params.hal_desc_sz; +- wim->wrip.rx_buf_len = DP_RX_BUFFER_SIZE; ++ wim->wrip.rx_buf_len = DP_RXDMA_NSS_REFILL_RING_SIZE; + + /* fill hal srng message */ + wim->hssm.dev_base_addr = (u32)ab->mem_pa; 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 new file mode 100644 index 00000000000000..db3b2820d0f738 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/234-001-ath11k-account-tx-rx-packets-flow.patch @@ -0,0 +1,275 @@ +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_sta.c ++++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c +@@ -7,7 +7,6 @@ + + #include "debugfs_sta.h" + #include "core.h" +-#include "peer.h" + #include "debug.h" + #include "dp_tx.h" + #include "debugfs_htt_stats.h" +@@ -146,9 +145,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 +152,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 +231,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 = { +--- 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 +@@ -6250,6 +6250,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; +@@ -6310,6 +6311,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/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 new file mode 100644 index 00000000000000..83c019b871e81b --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/237-002-ath11k-Add-provision-to-configure-rx-hashmap.patch @@ -0,0 +1,208 @@ +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/237-003-ath11k-allocate-dst-ring-descriptors-from-cacheable-.patch b/package/kernel/mac80211/patches/ath11k_nss/237-003-ath11k-allocate-dst-ring-descriptors-from-cacheable-.patch new file mode 100644 index 00000000000000..c054ee146f748a --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/237-003-ath11k-allocate-dst-ring-descriptors-from-cacheable-.patch @@ -0,0 +1,147 @@ +From 61342ee83df7fa0b90d5ece88e3f83dea426802c Mon Sep 17 00:00:00 2001 +From: P Praneesh +Date: Mon, 14 Dec 2020 20:22:22 +0530 +Subject: [PATCH] ath11k: allocate dst ring descriptors from cacheable + memory + +tcl_data and reo_dst rings are currently being allocated +using dma_allocate_coherent() which is non cachable. + +Allocating ring memory from cacheable memory area +allows cached descriptor access and prefetch next +descriptors to optimize CPU usage during +descriptor processing on NAPI. + +Signed-off-by: Pradeep Kumar Chitrapu +Signed-off-by: Sriram R +Signed-off-by: P Praneesh +--- + drivers/net/wireless/ath/ath11k/dp.c | 39 ++++++++++++++++++++++++++++++----- + drivers/net/wireless/ath/ath11k/dp.h | 1 + + drivers/net/wireless/ath/ath11k/hal.c | 33 ++++++++++++++++++++++++++--- + drivers/net/wireless/ath/ath11k/hal.h | 1 + + 4 files changed, 66 insertions(+), 8 deletions(-) + +--- 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 + struct sk_buff *msdu; + struct hal_tx_status ts = { 0 }; + struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id]; ++ int valid_entries; + u32 *desc; + u32 msdu_id; + u8 mac_id; +@@ -713,9 +714,18 @@ void ath11k_dp_tx_completion_handler(str + + ath11k_hal_srng_access_begin(ab, status_ring); + ++ valid_entries = ath11k_hal_srng_dst_num_free(ab, status_ring, false); ++ if (!valid_entries) { ++ ath11k_hal_srng_access_end(ab, status_ring); ++ spin_unlock_bh(&status_ring->lock); ++ return; ++ } ++ ++ ath11k_hal_srng_dst_invalidate_entry(ab, status_ring, valid_entries); ++ + while ((ATH11K_TX_COMPL_NEXT(tx_ring->tx_status_head) != + tx_ring->tx_status_tail) && +- (desc = ath11k_hal_srng_dst_get_next_entry(ab, status_ring))) { ++ (desc = ath11k_hal_srng_dst_get_next_cache_entry(ab, status_ring))) { + memcpy(&tx_ring->tx_status[tx_ring->tx_status_head], + desc, sizeof(struct hal_wbm_release_ring)); + tx_ring->tx_status_head = +--- a/drivers/net/wireless/ath/ath11k/hal.c ++++ b/drivers/net/wireless/ath/ath11k/hal.c +@@ -653,7 +653,8 @@ u32 *ath11k_hal_srng_dst_get_next_entry( + + desc = srng->ring_base_vaddr + srng->u.dst_ring.tp; + +- srng->u.dst_ring.tp += srng->entry_size; ++ srng->u.dst_ring.tp = (srng->u.dst_ring.tp + srng->entry_size) % ++ srng->ring_size; + + /* wrap around to start of ring*/ + if (srng->u.dst_ring.tp == srng->ring_size) +@@ -666,8 +667,63 @@ u32 *ath11k_hal_srng_dst_get_next_entry( + return desc; + } + ++u32 *ath11k_hal_srng_dst_get_next_cache_entry(struct ath11k_base *ab, ++ struct hal_srng *srng) ++{ ++ u32 *desc,*desc_next; ++ lockdep_assert_held(&srng->lock); ++ ++ if (srng->u.dst_ring.tp == srng->u.dst_ring.cached_hp) ++ return NULL; ++ ++ desc = srng->ring_base_vaddr + srng->u.dst_ring.tp; ++ ++ srng->u.dst_ring.tp = (srng->u.dst_ring.tp + srng->entry_size) % ++ srng->ring_size; ++ ++ /* Try to prefetch the next descriptor in the ring */ ++ if (srng->u.dst_ring.tp != srng->u.dst_ring.cached_hp) { ++ /* prefetch only if desc is available */ ++ desc_next = srng->ring_base_vaddr + srng->u.dst_ring.tp; ++ prefetch(desc_next); ++ } ++ return desc; ++} ++ ++void ath11k_hal_srng_dst_invalidate_entry(struct ath11k_base *ab, ++ struct hal_srng *srng, int entries) ++{ ++ u32 *desc; ++ u32 tp, hp; ++ ++ lockdep_assert_held(&srng->lock); ++ ++ if (!(srng->flags & HAL_SRNG_FLAGS_CACHED) || !entries) ++ return; ++ ++ tp = srng->u.dst_ring.tp; ++ hp = srng->u.dst_ring.cached_hp; ++ ++ desc = srng->ring_base_vaddr + tp; ++ if (hp > tp) { ++ dma_sync_single_for_cpu(ab->dev, virt_to_phys(desc), ++ entries * srng->entry_size * sizeof(u32), ++ DMA_FROM_DEVICE); ++ } else { ++ entries = srng->ring_size - tp; ++ dma_sync_single_for_cpu(ab->dev, virt_to_phys(desc), ++ entries * sizeof(u32), ++ DMA_FROM_DEVICE); ++ ++ entries = hp; ++ dma_sync_single_for_cpu(ab->dev, virt_to_phys(srng->ring_base_vaddr), ++ entries * sizeof(u32), ++ DMA_FROM_DEVICE); ++ } ++} ++ + int ath11k_hal_srng_dst_num_free(struct ath11k_base *ab, struct hal_srng *srng, +- bool sync_hw_ptr) ++ bool sync_hw_ptr) + { + u32 tp, hp; + +--- 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 + 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); ++u32 *ath11k_hal_srng_dst_get_next_cache_entry(struct ath11k_base *ab, ++ struct hal_srng *srng); + int ath11k_hal_srng_dst_num_free(struct ath11k_base *ab, struct hal_srng *srng, +- bool sync_hw_ptr); ++ bool sync_hw_ptr); ++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); + u32 *ath11k_hal_srng_src_get_next_reaped(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/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch new file mode 100644 index 00000000000000..84f15426ec13b7 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch @@ -0,0 +1,412 @@ +From 594992a7ef169aa406e7fc025df2455af5d226be Mon Sep 17 00:00:00 2001 +From: P Praneesh +Date: Tue, 15 Dec 2020 10:31:30 +0530 +Subject: [PATCH] ath11k: Allow fast rx by bypassing stats update + +Add a provision to disable stats and enable fast rx support +for a peer when it is connected to an AP with ethernet decap support. +All valid IP packets are directly passed to the net core stack +bypassing mac80211 stats update + +Signed-off-by: Sriram R +Signed-off-by: P Praneesh +--- + drivers/net/wireless/ath/ath11k/core.h | 3 ++ + drivers/net/wireless/ath/ath11k/debugfs.c | 76 +++++++++++++++++++++++++++++++++ + drivers/net/wireless/ath/ath11k/dp.c | 45 +++++++++++++++++++ + drivers/net/wireless/ath/ath11k/dp_rx.c | 54 ++++++++++++++++++++--- + drivers/net/wireless/ath/ath11k/hw.c | 25 +++++++++++ + drivers/net/wireless/ath/ath11k/hw.h | 1 + + drivers/net/wireless/ath/ath11k/mac.c | 2 + + drivers/net/wireless/ath/ath11k/peer.h | 1 + + 8 files changed, 201 insertions(+), 6 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -135,6 +135,7 @@ struct ath11k_skb_rxcb { + u8 tid; + u16 peer_id; + u16 seq_no; ++ struct napi_struct *napi; + }; + + 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 + return -ETIMEDOUT; + } + ++static inline u8 ath11k_dp_rx_h_msdu_start_ip_valid(struct ath11k_base *ab, ++ struct hal_rx_desc *desc) ++{ ++ return ab->hw_params.hw_ops->rx_desc_get_ip_valid(desc); ++} ++ + /* 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 + return peer; + } + ++static bool ath11k_dp_rx_check_fast_rx(struct ath11k *ar, ++ struct sk_buff *msdu, ++ struct hal_rx_desc *rx_desc, ++ struct ath11k_peer *peer) ++{ ++ struct ethhdr *ehdr; ++ struct ath11k_peer *f_peer; ++ struct ath11k_skb_rxcb *rxcb; ++ u8 decap; ++ ++ lockdep_assert_held(&ar->ab->base_lock); ++ ++ decap = ath11k_dp_rx_h_msdu_start_decap_type(ar->ab, rx_desc); ++ rxcb = ATH11K_SKB_RXCB(msdu); ++ ++ if (!ar->ab->stats_disable || ++ decap != DP_RX_DECAP_TYPE_ETHERNET2_DIX || ++ peer->vif->type != NL80211_IFTYPE_AP) ++ return false; ++ ++ /* mcbc packets go through mac80211 for PN validation */ ++ if (rxcb->is_mcbc) ++ return false; ++ ++ if (!peer->is_authorized) ++ return false; ++ ++ if (!ath11k_dp_rx_h_msdu_start_ip_valid(ar->ab, rx_desc)) ++ return false; ++ ++ /* fast rx is supported only on ethernet decap, so ++ * we can directly gfet the ethernet header ++ */ ++ ehdr = (struct ethhdr *)msdu->data; ++ ++ /* requires rebroadcast from mac80211 */ ++ if (is_multicast_ether_addr(ehdr->h_dest)) ++ return false; ++ ++ /* check if the msdu needs to be bridged to our connected peer */ ++ f_peer = ath11k_peer_find_by_addr(ar->ab, ehdr->h_dest); ++ ++ if (f_peer && f_peer != peer) ++ return false; ++ ++ /* allow direct rx */ ++ return true; ++} ++ + static void ath11k_dp_rx_h_mpdu(struct ath11k *ar, + struct sk_buff *msdu, + struct hal_rx_desc *rx_desc, +- struct ieee80211_rx_status *rx_status) ++ struct ieee80211_rx_status *rx_status, ++ bool *fast_rx) + { + bool fill_crypto_hdr; + enum hal_encrypt_type enctype; +@@ -2417,6 +2473,9 @@ static void ath11k_dp_rx_h_mpdu(struct a + 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 + spin_lock_bh(&ar->ab->base_lock); + peer = ath11k_dp_rx_h_find_peer(ar->ab, msdu); + if (peer) { ++ /* If the pkt is a valid IP packet and peer supports ++ * fast rx, deliver directly to net, also note that ++ * pkts with crypto error are not expected to arrive in this ++ * path, so its safe to skip checking errors here */ ++ if (*fast_rx && ++ ath11k_dp_rx_check_fast_rx(ar, msdu, rx_desc, peer)) { ++ wdev = ieee80211_vif_to_wdev(peer->vif); ++ if (wdev) { ++ spin_unlock_bh(&ar->ab->base_lock); ++ ath11k_dp_rx_h_csum_offload(ar, msdu); ++ msdu->dev = wdev->netdev; ++ msdu->protocol = eth_type_trans(msdu, msdu->dev); ++ napi_gro_receive(rxcb->napi, msdu); ++ 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 + static int ath11k_dp_rx_process_msdu(struct ath11k *ar, + struct sk_buff *msdu, + struct sk_buff_head *msdu_list, +- struct ieee80211_rx_status *rx_status) ++ struct ieee80211_rx_status *rx_status, ++ bool *fast_rx) + { + 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 + } + } + ++ ath11k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_status, fast_rx); ++ if (*fast_rx) { ++ ab->soc_stats.invalid_rbm++; ++ return 0; ++ } ++ + ath11k_dp_rx_h_ppdu(ar, rx_desc, rx_status); +- ath11k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_status); + + rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; + +@@ -2791,10 +2880,12 @@ static void ath11k_dp_rx_process_receive + struct sk_buff_head *msdu_list, + int mac_id) + { ++ struct ath11k_skb_rxcb *rxcb; + struct sk_buff *msdu; + struct ath11k *ar; + struct ieee80211_rx_status rx_status = {0}; + int ret; ++ bool fast_rx; + + if (skb_queue_empty(msdu_list)) + return; +@@ -2811,7 +2902,12 @@ static void ath11k_dp_rx_process_receive + } + + while ((msdu = __skb_dequeue(msdu_list))) { +- ret = ath11k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_status); ++ rxcb = ATH11K_SKB_RXCB(msdu); ++ /* Enable fast rx by default, the value will cahnge based on peer cap ++ * and packet type */ ++ fast_rx = true; ++ rxcb->napi = napi; ++ ret = ath11k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_status, &fast_rx); + 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 + continue; + } + +- ath11k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_status); ++ /* msdu is already delivered directectly */ ++ if (!fast_rx) ++ ath11k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_status); ++ + } + } + +@@ -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; ++ 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 + } + ath11k_dp_rx_h_ppdu(ar, desc, status); + +- ath11k_dp_rx_h_mpdu(ar, msdu, desc, status); ++ fast_rx = false; ++ ath11k_dp_rx_h_mpdu(ar, msdu, desc, status, &fast_rx); + + rxcb->tid = ath11k_dp_rx_h_mpdu_start_tid(ar->ab, desc); + +--- 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 + __le32_to_cpu(desc->u.ipq8074.msdu_start.info2)); + } + ++static u8 ath11k_hw_ipq8074_rx_desc_get_ip_valid(struct hal_rx_desc *desc) ++{ ++ bool ipv4, ipv6; ++ ipv4 = FIELD_GET(RX_MSDU_START_INFO2_IPV4, ++ __le32_to_cpu(desc->u.ipq8074.msdu_start.info2)); ++ ipv6 = FIELD_GET(RX_MSDU_START_INFO2_IPV6, ++ __le32_to_cpu(desc->u.ipq8074.msdu_start.info2)); ++ return (ipv4 || ipv6); ++} ++ + 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 + __le32_to_cpu(desc->u.qcn9074.msdu_start.info2)); + } + ++static u8 ath11k_hw_qcn9074_rx_desc_get_ip_valid(struct hal_rx_desc *desc) ++{ ++ bool ipv4 , ipv6; ++ ipv4 = FIELD_GET(RX_MSDU_START_INFO2_IPV4, ++ __le32_to_cpu(desc->u.qcn9074.msdu_start.info2)); ++ ipv6 = FIELD_GET(RX_MSDU_START_INFO2_IPV6, ++ __le32_to_cpu(desc->u.qcn9074.msdu_start.info2)); ++ return (ipv4 || ipv6); ++} ++ + 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 = + .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, +@@ -1293,6 +1314,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, ++ .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, +--- a/drivers/net/wireless/ath/ath11k/hw.h ++++ b/drivers/net/wireless/ath/ath11k/hw.h +@@ -270,6 +270,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); ++ u8 (*rx_desc_get_ip_valid)(struct hal_rx_desc *desc); + bool (*rx_desc_get_ldpc_support)(struct hal_rx_desc *desc); + bool (*rx_desc_get_mpdu_seq_ctl_vld)(struct hal_rx_desc *desc); + 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 +@@ -5195,6 +5195,14 @@ static int ath11k_mac_op_sta_state(struc + } + } 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); diff --git a/package/kernel/mac80211/patches/ath11k_nss/245-compilation_fix.patch b/package/kernel/mac80211/patches/ath11k_nss/245-compilation_fix.patch new file mode 100644 index 00000000000000..f3ad6dea74e038 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/245-compilation_fix.patch @@ -0,0 +1,183 @@ +From 9cdb8bae50aca80b593d0f53be5b8efedfc91324 Mon Sep 17 00:00:00 2001 +From: Tamizh Chelvam +Date: Sun, 7 Mar 2021 22:49:26 +0530 +Subject: [PATCH] backport: Compile fix + +Adding these changes to fix compilation issue due to +package upgrade + +Signed-off-by: Tamizh Chelvam +Signed-off-by: Gautham Kumar Senthilkumaran +--- + include/linux/backport-refcount.h | 4 +-- + include/net/fq.h | 10 +++++- + net/mac80211/cfg.c | 4 +-- + net/mac80211/ieee80211_i.h | 4 ++- + net/mac80211/iface.c | 2 -- + net/mac80211/rx.c | 23 +++++++++----- + 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 { + }; + + struct ieee80211_rx_data { ++ struct napi_struct *napi; + 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 +@@ -4662,19 +4662,21 @@ static void ieee80211_8023_xmit(struct i + + ieee80211_aggr_check(sdata, sta, skb); + +- tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; +- tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); +- if (tid_tx) { +- if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) { +- /* fall back to non-offload slow path */ +- __ieee80211_subif_start_xmit(skb, dev, 0, +- IEEE80211_TX_CTRL_MLO_LINK_UNSPEC, +- NULL); +- return; +- } ++ if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) { ++ tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; ++ tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); ++ if (tid_tx) { ++ if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) { ++ /* fall back to non-offload slow path */ ++ __ieee80211_subif_start_xmit(skb, dev, 0, ++ IEEE80211_TX_CTRL_MLO_LINK_UNSPEC, ++ NULL); ++ return; ++ } + +- if (tid_tx->timeout) +- tid_tx->last_tx = jiffies; ++ if (tid_tx->timeout) ++ tid_tx->last_tx = jiffies; ++ } + } + + skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); +@@ -4730,7 +4732,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; +- struct ieee80211_key *key; ++ struct ieee80211_key *key = NULL; + struct sta_info *sta; + + #ifdef CPTCFG_MAC80211_NSS_SUPPORT +@@ -4748,9 +4750,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 + goto out; + } + +- if (unlikely(IS_ERR_OR_NULL(sta) || !sta->uploaded || +- !test_sta_flag(sta, WLAN_STA_AUTHORIZED) || +- sdata->control_port_protocol == ehdr->h_proto)) ++ if (ieee80211_hw_check(&sdata->local->hw, SUPPORTS_NSS_OFFLOAD)) { ++ if (unlikely(IS_ERR_OR_NULL(sta) || !sta->uploaded)) ++ sta = NULL; ++ goto tx_offload; ++ } else if (unlikely(IS_ERR_OR_NULL(sta) || !sta->uploaded || ++ !test_sta_flag(sta, WLAN_STA_AUTHORIZED) || ++ sdata->control_port_protocol == ehdr->h_proto)) + goto skip_offload; + + key = rcu_dereference(sta->ptk[sta->ptk_idx]); +@@ -4761,6 +4767,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); ++tx_offload: + ieee80211_8023_xmit(sdata, dev, sta, key, skb); + goto out; + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -5429,8 +5429,6 @@ void ieee80211_rx_list(struct ieee80211_ + + status->rx_flags = 0; + +- kcov_remote_start_common(skb_get_kcov_handle(skb)); +- + /* + * Frames with failed FCS/PLCP checksum are not returned, + * all other frames are returned without radiotap header +@@ -5450,7 +5448,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); +- +- 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); 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 new file mode 100644 index 00000000000000..79c179a2d1b55e --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/245-revert-dev-sw-netstats-txrx-add.patch @@ -0,0 +1,145 @@ +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); + } + } +@@ -2684,7 +2704,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 +@@ -4095,7 +4115,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) { +@@ -4803,7 +4823,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; +@@ -4343,7 +4355,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); + } +@@ -4711,7 +4723,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/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch b/package/kernel/mac80211/patches/ath11k_nss/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch index 56dbf2a0371b31..0a7dcf5e845780 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch @@ -19,7 +19,7 @@ Signed-off-by: Seevalamuthu Mariappan * Copyright (c) 2020 The Linux Foundation. All rights reserved. */ +#include - + #include "debug.h" #include "mac.h" @@ -1782,6 +1783,7 @@ static int ath11k_nss_init(struct ath11k @@ -27,16 +27,16 @@ Signed-off-by: Seevalamuthu Mariappan struct ath11k_dp *dp; int i, ret; + struct device *dev = ab->dev; - + dp = &ab->dp; - + @@ -1801,6 +1803,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_RX_BUFFER_SIZE; + wim->wrip.rx_buf_len = DP_RXDMA_NSS_REFILL_RING_SIZE; + if (of_property_read_bool(dev->of_node, "nss-radio-priority")) + wim->flags |= WIFILI_MULTISOC_THREAD_MAP_ENABLE; - + /* 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 @@ -51,13 +51,13 @@ Signed-off-by: Seevalamuthu Mariappan - int ret, i; + int ret, i, scheme_id = 0; + u32 nss_radio_priority; - + dyn_if_type = ath11k_nss_get_dynamic_interface_type(ab); - + @@ -2010,6 +2016,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); - + + if (!of_property_read_u32(dev->of_node, "nss-radio-priority", &nss_radio_priority)) { + scheme_id = nss_wifili_thread_scheme_alloc(ab->nss.ctx, ar->nss.if_num, nss_radio_priority); + if (scheme_id == WIFILI_SCHEME_ID_INVALID) { @@ -75,13 +75,13 @@ Signed-off-by: Seevalamuthu Mariappan pdevmsg->target_pdev_id = ar->pdev->pdev_id; pdevmsg->num_rx_swdesc = WIFILI_RX_DESC_POOL_WEIGHT * DP_RXDMA_BUF_RING_SIZE; + pdevmsg->scheme_id = scheme_id; - + /* 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 /* pdev deinit msg success, dealloc, deregister and return */ ret = 0; - + + /* reset thread scheme*/ + nss_wifili_thread_scheme_dealloc(ab->nss.ctx, ar->nss.if_num); + @@ -95,13 +95,13 @@ Signed-off-by: Seevalamuthu Mariappan #define WIFILI_NSS_CCE_DISABLED 0x1 #define WIFILI_ADDTL_MEM_SEG_SET 0x000000002 +#define WIFILI_MULTISOC_THREAD_MAP_ENABLE 0x10 - + /* 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, }; - + +#define WIFILI_SCHEME_ID_INVALID -1 + enum ath11k_nss_opmode { 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/ath11k_nss/319-ath11k-fix-double-free-of-peer-rx_tid-during-reo-cmd.patch index 0dd8dcba9ec152..7ea6b471e340aa 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/ath11k_nss/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 -@@ -1418,6 +1418,7 @@ const struct ath11k_hw_ring_mask ath11k_ +@@ -1435,6 +1435,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/336-ath11k-skip-status-ring-entry-processing.patch b/package/kernel/mac80211/patches/ath11k_nss/336-ath11k-skip-status-ring-entry-processing.patch index 4ed84ffa3e21d4..2e874d321d0ad1 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/336-ath11k-skip-status-ring-entry-processing.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/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 -@@ -3168,6 +3168,46 @@ ath11k_dp_rx_mon_update_status_buf_state +@@ -3296,6 +3296,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) { -@@ -3181,6 +3221,7 @@ static int ath11k_dp_rx_reap_mon_status_ +@@ -3309,6 +3349,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; -@@ -3200,8 +3241,7 @@ static int ath11k_dp_rx_reap_mon_status_ +@@ -3328,8 +3369,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; -@@ -3232,18 +3272,43 @@ static int ath11k_dp_rx_reap_mon_status_ +@@ -3360,18 +3400,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) { @@ -157,7 +157,7 @@ Signed-off-by: Venkateswara Naralasetty spin_lock_bh(&rx_ring->idr_lock); --- a/drivers/net/wireless/ath/ath11k/hal.c +++ b/drivers/net/wireless/ath/ath11k/hal.c -@@ -781,6 +781,20 @@ u32 *ath11k_hal_srng_src_get_next_reaped +@@ -837,6 +837,20 @@ u32 *ath11k_hal_srng_src_get_next_reaped return desc; } @@ -180,9 +180,9 @@ 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 -@@ -948,6 +948,8 @@ u32 *ath11k_hal_srng_dst_peek(struct ath - int ath11k_hal_srng_dst_num_free(struct ath11k_base *ab, struct hal_srng *srng, - bool sync_hw_ptr); +@@ -953,6 +953,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); +u32 *ath11k_hal_srng_src_next_peek(struct ath11k_base *ab, + struct hal_srng *srng); diff --git a/package/kernel/mac80211/patches/ath11k_nss/342-mac80211-fix-unconditional-sta-usage.patch b/package/kernel/mac80211/patches/ath11k_nss/342-mac80211-fix-unconditional-sta-usage.patch new file mode 100644 index 00000000000000..d8b3ff3f02e037 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/342-mac80211-fix-unconditional-sta-usage.patch @@ -0,0 +1,50 @@ +From 479096a023928cc75aa38953b7170a8984acd0da Mon Sep 17 00:00:00 2001 +From: Tamizh Chelvam +Date: Tue, 11 Jan 2022 14:04:09 +0530 +Subject: [PATCH] mac80211: Fix kernel panic due to unsafe sta usage + +Observing below crash in dynamic vlan scneario when +abruptly killing hostapd while ping or any traffic to stations +are going on. + +[ 753.307213] Unable to handle kernel NULL pointer dereference at virtual address 0000058c +[ 753.309137] pgd = 7514769a +[ 753.317392] [0000058c] *pgd=00000000 +[ 753.319892] Internal error: Oops: 5 [#1] PREEMPT SMP ARM +[ 753.604280] PC is at __ieee80211_subif_start_xmit+0xc58/0xe48 [mac80211] +[ 753.608954] LR is at __ieee80211_subif_start_xmit+0xc3c/0xe48 [mac80211] +[ 753.615729] pc : [] lr : [] psr: 40000013 +[ 753.622411] sp : 843b5940 ip : 98e7d348 fp : 99463e42 +[ 753.628398] r10: 98e7d318 r9 : 92d0e000 r8 : 00000000 +[ 753.633606] r7 : 963c8d20 r6 : 92d0e580 r5 : 00000000 r4 : 98e7d300 +[ 753.638819] r3 : 00000163 r2 : fffffff0 r1 : 00000000 r0 : 98e7d318 +[ 753.645416] Flags: nZcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user +[ 753.651928] Control: 10c0383d Table: 5db8806a DAC: 00000055 +[ 753.659135] Process ping (pid: 4436, stack limit = 0xf466aee4) + +Its due to accessing the sta pointer +unconditionally. Fix that by checking sta pointer is +available or not before using. + +Signed-off-by: Tamizh Chelvam +--- + net/mac80211/tx.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -4719,12 +4719,12 @@ 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, + &info->flags, NULL); + + ieee80211_tx_stats(dev, 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; + sta->deflink.tx_stats.bytes[queue] += len; + } 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/ath11k_nss/376-ath11k-Add-nss-event-handler-support-for-link-desc.patch new file mode 100644 index 00000000000000..7b3df32c05b69e --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/376-ath11k-Add-nss-event-handler-support-for-link-desc.patch @@ -0,0 +1,73 @@ +From 69356d5f6947c8a6182e1c6283478ad40c6df37b Mon Sep 17 00:00:00 2001 +From: Tamizh Chelvam Raja +Date: Wed, 21 Jun 2023 20:26:02 +0530 +Subject: [PATCH] ath11k: Add nss event handler support for link desc + +Add NSS event handler support for NSS_WIFILI_LINK_DESC_INFO_MSG. +This event will be given to host from NSS for releasing +link descriptor which used for fragmentation. This needs to be +handled to release the link descriptor back to hardware for +other usage. + +Signed-off-by: Tamizh Chelvam Raja +--- + drivers/net/wireless/ath/ath11k/nss.c | 43 +++++++++++++++++++++++++++ + 1 file changed, 43 insertions(+) + +--- 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 + spin_unlock_bh(&ab->base_lock); + } + ++static void ath11k_nss_wifili_link_desc_set(struct ath11k_base *ab, void *desc, ++ struct ath11k_buffer_addr *buf_addr_info, ++ enum hal_wbm_rel_bm_act action) ++{ ++ struct hal_wbm_release_ring *dst_desc = desc; ++ ++ dst_desc->buf_addr_info = *buf_addr_info; ++ dst_desc->info0 |= FIELD_PREP(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE, ++ HAL_WBM_REL_SRC_MODULE_SW) | ++ FIELD_PREP(HAL_WBM_RELEASE_INFO0_BM_ACTION, action) | ++ FIELD_PREP(HAL_WBM_RELEASE_INFO0_DESC_TYPE, ++ HAL_WBM_REL_DESC_TYPE_MSDU_LINK); ++} ++ ++static void ath11k_nss_wifili_link_desc_return(struct ath11k_base *ab, ++ struct ath11k_buffer_addr *buf_addr_info) ++{ ++ struct ath11k_dp *dp = &ab->dp; ++ struct hal_srng *srng; ++ u32 *desc; ++ ++ srng = &ab->hal.srng_list[dp->wbm_desc_rel_ring.ring_id]; ++ spin_lock_bh(&srng->lock); ++ ++ ath11k_hal_srng_access_begin(ab, srng); ++ desc = ath11k_hal_srng_src_get_next_entry(ab, srng); ++ ++ if (!desc) ++ goto exit; ++ ++ ath11k_nss_wifili_link_desc_set(ab, desc, buf_addr_info, HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); ++ ++exit: ++ ath11k_hal_srng_access_end(ab, srng); ++ spin_unlock(&srng->lock); ++} ++ + 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 */ + break; ++ case NSS_WIFILI_LINK_DESC_INFO_MSG: ++ ath11k_nss_wifili_link_desc_return(ab, ++ (void *)&msg->msg.linkdescinfomsg); ++ break; + default: + ath11k_dbg(ab, ATH11K_DBG_NSS, "unhandled event %d\n", msg_type); + break; 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/ath11k_nss/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch new file mode 100644 index 00000000000000..2d1fbc097df375 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch @@ -0,0 +1,85 @@ +From 11d0cce62afc157468e1d97ea80a2510091ea2c2 Mon Sep 17 00:00:00 2001 +From: P Praneesh +Date: Fri, 1 Jul 2022 11:57:00 +0530 +Subject: [PATCH] mac80211: Remove unused RX_FLAGS from mac80211_rx_flags + +Remove unused RX_FLAG_AMPDU_DELIM_CRC_KNOWN flag from +mac80211_rx_flags to provide space for new EHT flags. + +Signed-off-by: P Praneesh +--- + include/net/mac80211.h | 33 +++++++++++++++------------------ + net/mac80211/rx.c | 7 +------ + 2 files changed, 16 insertions(+), 24 deletions(-) + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -1385,8 +1385,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 +- * @RX_FLAG_AMPDU_DELIM_CRC_KNOWN: The delimiter CRC field is known (the CRC +- * is stored in the @ampdu_delimiter_crc field) + * @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 +@@ -1458,22 +1456,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), +- RX_FLAG_AMPDU_DELIM_CRC_KNOWN = BIT(15), +- RX_FLAG_MACTIME_END = BIT(16), +- RX_FLAG_ONLY_MONITOR = BIT(17), +- RX_FLAG_SKIP_MONITOR = BIT(18), +- RX_FLAG_AMSDU_MORE = BIT(19), +- RX_FLAG_RADIOTAP_TLV_AT_END = BIT(20), +- RX_FLAG_MIC_STRIPPED = BIT(21), +- RX_FLAG_ALLOW_SAME_PN = BIT(22), +- RX_FLAG_ICV_STRIPPED = BIT(23), +- RX_FLAG_AMPDU_EOF_BIT = BIT(24), +- RX_FLAG_AMPDU_EOF_BIT_KNOWN = BIT(25), +- RX_FLAG_RADIOTAP_HE = BIT(26), +- RX_FLAG_RADIOTAP_HE_MU = BIT(27), +- RX_FLAG_RADIOTAP_LSIG = BIT(28), +- RX_FLAG_NO_PSDU = BIT(29), +- RX_FLAG_8023 = BIT(30), ++ RX_FLAG_MACTIME_END = BIT(15), ++ RX_FLAG_ONLY_MONITOR = BIT(16), ++ RX_FLAG_SKIP_MONITOR = BIT(17), ++ RX_FLAG_AMSDU_MORE = BIT(18), ++ RX_FLAG_RADIOTAP_TLV_AT_END = BIT(19), ++ RX_FLAG_MIC_STRIPPED = BIT(20), ++ RX_FLAG_ALLOW_SAME_PN = BIT(21), ++ RX_FLAG_ICV_STRIPPED = BIT(22), ++ RX_FLAG_AMPDU_EOF_BIT = BIT(23), ++ RX_FLAG_AMPDU_EOF_BIT_KNOWN = BIT(24), ++ RX_FLAG_RADIOTAP_HE = BIT(25), ++ RX_FLAG_RADIOTAP_HE_MU = BIT(26), ++ RX_FLAG_RADIOTAP_LSIG = BIT(27), ++ RX_FLAG_NO_PSDU = BIT(28), ++ RX_FLAG_8023 = BIT(29), + }; + + /** +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -527,18 +527,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; +- if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN) +- flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN; + if (status->flag & RX_FLAG_AMPDU_EOF_BIT_KNOWN) + flags |= IEEE80211_RADIOTAP_AMPDU_EOF_KNOWN; + if (status->flag & RX_FLAG_AMPDU_EOF_BIT) + flags |= IEEE80211_RADIOTAP_AMPDU_EOF; + put_unaligned_le16(flags, pos); + pos += 2; +- if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN) +- *pos++ = status->ampdu_delimiter_crc; +- else +- *pos++ = 0; ++ *pos++ = 0; + *pos++ = 0; + } + 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 new file mode 100644 index 00000000000000..b8d2b614dd4759 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/640-006-mac80211-add-eht-radiotap.patch @@ -0,0 +1,506 @@ +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 +@@ -1439,7 +1439,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), +@@ -1471,6 +1475,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), + }; + + /** +@@ -1538,6 +1544,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 +@@ -1591,6 +1598,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/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch b/package/kernel/mac80211/patches/ath11k_nss/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch new file mode 100644 index 00000000000000..c0b787bd687dee --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch @@ -0,0 +1,111 @@ +From d4ddaebe2132dbb169f78da3666b11a21f645ea0 Mon Sep 17 00:00:00 2001 +From: Tamizh Chelvam Raja +Date: Fri, 21 Apr 2023 12:28:21 +0530 +Subject: [PATCH] mac80211: Advertise HW checksum offload only for ethmode + +Upper(NSS/SFE) layer might remove checksum offset from a skb +for the net device which advertise HW checksum offload +feature. This would create an issue if any software encrypted +packet or for the netdev which don't support IEEE80211_OFFLOAD_*. +Avoid this by advertising the HW checksum offload feature +only for the netdev which supports IEEE80211_OFFLOAD_* +and have an check before checking checksum offset for the +exceptional packets getting called from 8023_xmit API. + +Signed-off-by: Tamizh Chelvam Raja +--- + net/mac80211/ieee80211_i.h | 3 ++- + net/mac80211/iface.c | 4 ++++ + net/mac80211/tdls.c | 2 +- + net/mac80211/tx.c | 19 ++++++++++--------- + 4 files changed, 17 insertions(+), 11 deletions(-) + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -37,6 +37,8 @@ + #include "wme.h" + #include "rate.h" + ++#define IS_HW_CSUM_NOT_ENABLED(dev) (!((dev)->features & NETIF_F_HW_CSUM)) ++ + 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); +@@ -3632,7 +3634,7 @@ ieee80211_sdata_netdev_features(struct i + } + + static struct sk_buff * +-ieee80211_tx_skb_fixup(struct sk_buff *skb, netdev_features_t features) ++ieee80211_tx_skb_fixup(struct sk_buff *skb, netdev_features_t features, struct net_device *dev) + { + if (skb_is_gso(skb)) { + struct sk_buff *segs; +@@ -3650,7 +3652,7 @@ ieee80211_tx_skb_fixup(struct sk_buff *s + if (skb_needs_linearize(skb, features) && __skb_linearize(skb)) + goto free; + +- if (skb->ip_summed == CHECKSUM_PARTIAL) { ++ if (skb->ip_summed == CHECKSUM_PARTIAL && IS_HW_CSUM_NOT_ENABLED(dev)) { + int ofs = skb_checksum_start_offset(skb); + + if (skb->encapsulation) +@@ -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 */ +- skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); ++ skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata), sdata->dev); + if (!skb) + return true; + +@@ -4336,7 +4338,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. + */ +- skb = ieee80211_tx_skb_fixup(skb, 0); ++ skb = ieee80211_tx_skb_fixup(skb, 0, dev); + if (!skb) { + len = 0; + goto out; +@@ -4691,7 +4693,7 @@ static void ieee80211_8023_xmit(struct i + } + } + +- skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); ++ skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata), dev); + if (!skb) + return; + +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -2250,6 +2250,10 @@ int ieee80211_if_add(struct ieee80211_lo + + ndev->features |= local->hw.netdev_features; + ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE; ++ if ((type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_STATION) && ++ ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) && !params->use_4addr) ++ ndev->features |= NETIF_F_HW_CSUM; ++ + ndev->hw_features |= ndev->features & + MAC80211_SUPPORTED_FEATURES_TX; + sdata->vif.netdev_features = local->hw.netdev_features; +--- a/net/mac80211/mesh.c ++++ b/net/mac80211/mesh.c +@@ -13,6 +13,8 @@ + #include "wme.h" + #include "driver-ops.h" + ++#define IS_HW_CSUM_NOT_ENABLED(dev) (!((dev)->features & NETIF_F_HW_CSUM)) ++ + static int mesh_allocated; + static struct kmem_cache *rm_cache; + +@@ -797,7 +799,7 @@ bool ieee80211_mesh_xmit_fast(struct iee + if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) + return false; + +- if (skb->ip_summed == CHECKSUM_PARTIAL) { ++ if (skb->ip_summed == CHECKSUM_PARTIAL && IS_HW_CSUM_NOT_ENABLED(sdata->dev)) { + skb_set_transport_header(skb, skb_checksum_start_offset(skb)); + if (skb_checksum_help(skb)) + return false; diff --git a/package/kernel/mac80211/patches/ath11k_nss/999-fix-build.patch b/package/kernel/mac80211/patches/ath11k_nss/999-fix-build.patch index 9993d3f03fb572..916f16eb81989f 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/999-fix-build.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/999-fix-build.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -2299,6 +2299,7 @@ static void ath11k_dp_rx_h_undecap_snap( +@@ -2305,6 +2305,7 @@ static void ath11k_dp_rx_h_undecap_snap( struct ieee80211_hdr *hdr; size_t hdr_len; u8 l3_pad_bytes; @@ -8,7 +8,7 @@ struct hal_rx_desc *rx_desc; struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); -@@ -2323,12 +2324,22 @@ static void ath11k_dp_rx_h_undecap_snap( +@@ -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)) { @@ -35,7 +35,7 @@ memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); } -@@ -2358,7 +2369,8 @@ static void ath11k_dp_rx_h_undecap(struc +@@ -2364,7 +2375,8 @@ static void ath11k_dp_rx_h_undecap(struc ehdr = (struct ethhdr *)msdu->data; /* mac80211 allows fast path only for authorized STA */ @@ -45,7 +45,16 @@ ATH11K_SKB_RXCB(msdu)->is_eapol = true; ath11k_dp_rx_h_undecap_eth(ar, msdu, first_hdr, enctype, status); -@@ -2418,7 +2430,8 @@ static void ath11k_dp_rx_h_mpdu(struct a +@@ -2463,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; +@@ -2478,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); @@ -107,7 +116,7 @@ } --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -5234,6 +5234,10 @@ void ieee80211_tx_status_ext(struct ieee +@@ -5239,6 +5239,10 @@ void ieee80211_tx_status_ext(struct ieee * (NULL for multicast packets) * @info: tx status information */ From ab27d379ba7d0cb69cf50969ad9922d83097fdeb Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 17 Dec 2023 18:38:54 -0500 Subject: [PATCH 061/225] ath11k_nss: Add mac address to debug `nss peer delete` warnings also delete ath10k patch, and refresh. --- ...-ath11k_nss-add-nss-driver-interface.patch | 2 +- ...-004-ath10k-add-nss-driver-interface.patch | 28 -------------- .../ath11k_nss/319-ath11k-nss-2K-SKB.patch | 37 ------------------- ...99-fix-build.patch => 900-fix-build.patch} | 0 4 files changed, 1 insertion(+), 66 deletions(-) delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/199-004-ath10k-add-nss-driver-interface.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/319-ath11k-nss-2K-SKB.patch rename package/kernel/mac80211/patches/ath11k_nss/{999-fix-build.patch => 900-fix-build.patch} (100%) diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch b/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch index ea47c3c9721d7e..3a4ece0f6a6683 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch @@ -1365,7 +1365,7 @@ Signed-off-by: Sriram R + + peer = ath11k_peer_find_by_addr(ab, addr); + if (!peer) { -+ ath11k_warn(ab, "peer not found for nss peer delete\n"); ++ ath11k_warn(ab, "peer (%pM) not found for nss peer delete\n", addr); + spin_unlock_bh(&ab->base_lock); + return -EINVAL; + } diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-004-ath10k-add-nss-driver-interface.patch b/package/kernel/mac80211/patches/ath11k_nss/199-004-ath10k-add-nss-driver-interface.patch deleted file mode 100644 index ecf5ee16c80cf7..00000000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/199-004-ath10k-add-nss-driver-interface.patch +++ /dev/null @@ -1,28 +0,0 @@ ---- a/drivers/net/wireless/ath/ath10k/mac.c -+++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -24,7 +24,6 @@ - #include "wmi-tlv.h" - #include "wmi-ops.h" - #include "wow.h" --#include "leds.h" - - /*********/ - /* Rates */ -@@ -5530,7 +5529,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 +5551,8 @@ 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/319-ath11k-nss-2K-SKB.patch b/package/kernel/mac80211/patches/ath11k_nss/319-ath11k-nss-2K-SKB.patch deleted file mode 100644 index 8c235ae04de09a..00000000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/319-ath11k-nss-2K-SKB.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 30f54666ae15128f26fbad787a35253885a10513 Mon Sep 17 00:00:00 2001 -From: Ramya Gnanasekar -Date: Fri, 25 Dec 2020 16:11:06 +0530 -Subject: [PATCH] ath11k: Disable rx_header tlv for 2K SKB - -On low memory platform hdr_status in hal_rx_desc is not subscribed to -get a savings of 128bytes in skb. This is required to reduce the skb -size from 4K to 2K. Use HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG message -to unsubscribe rx_pkt_header tlv for rxdma ring. - -Signed-off-by: Ramya Gnanasekar - ---- a/drivers/net/wireless/ath/ath11k/dp.h -+++ b/drivers/net/wireless/ath/ath11k/dp.h -@@ -220,6 +220,11 @@ struct ath11k_pdev_dp { - #define DP_REO_STATUS_RING_SIZE 2048 - #define DP_RXDMA_BUF_RING_SIZE 4096 - #define DP_RXDMA_REFILL_RING_SIZE 2048 -+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512MB -+#define DP_RXDMA_NSS_REFILL_RING_SIZE 1816 -+#else -+#define DP_RXDMA_NSS_REFILL_RING_SIZE 2048 -+#endif - #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 ---- a/drivers/net/wireless/ath/ath11k/nss.c -+++ b/drivers/net/wireless/ath/ath11k/nss.c -@@ -1802,7 +1802,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; -- wim->wrip.rx_buf_len = DP_RX_BUFFER_SIZE; -+ wim->wrip.rx_buf_len = DP_RXDMA_NSS_REFILL_RING_SIZE; - if (of_property_read_bool(dev->of_node, "nss-radio-priority")) - wim->flags |= WIFILI_MULTISOC_THREAD_MAP_ENABLE; - diff --git a/package/kernel/mac80211/patches/ath11k_nss/999-fix-build.patch b/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/999-fix-build.patch rename to package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch From 5ec762d383b0228e8ce5a197ff90ee7bed2f1ced Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 24 Dec 2023 22:39:31 -0500 Subject: [PATCH 062/225] ath11k_nss: FIX `nss peer delete` + encap errors This should hopefullly fix the following errors: ``` [Sun Dec 24 22:03:21 2023] ath11k c000000.wifi: encap mismatch in nss tx skb encap type 1vif encap type 2 [Sun Dec 24 22:03:21 2023] ath11k c000000.wifi: failed to transmit frame -22 [Sun Dec 24 22:08:25 2023] ath11k c000000.wifi: encap mismatch in nss tx skb encap type 1vif encap type 2 [Sun Dec 24 22:08:25 2023] ath11k c000000.wifi: failed to transmit frame -22 ``` Clients should also be able to switch between 2Ghz and 5Ghz AP, as well as join using password (no longer required to boot with NSS off first, connect the client to acquire PSK, and reboot back with nss wifi offload enabled). Uptime has been 5 hours and so far no issues. --- ...th11k-fix-for-peer-memory-corruption.patch | 48 +++ ...-adding-support-for-mgmt-frame-stats.patch | 34 +- ...91-ath11k-add-mgmt-and-data-ack-rssi.patch | 2 +- ...-ath11k_nss-add-nss-driver-interface.patch | 2 +- .../199-003-ath11k-add-nss-support.patch | 73 +++- ...t-callback-when-hwencap-enable-in-st.patch | 35 ++ ...03-mac80211-ath11k-fw-dynamic-muedca.patch | 203 ++++++++++ .../211-ath11k-add-obss-pd-support.patch | 56 +++ ...14-ath11k-qos-null-frame-tx-over-wmi.patch | 8 +- ...11k-Disable-rx_header-tlv-for-2K-SKB.patch | 4 +- ...01-ath11k-account-tx-rx-packets-flow.patch | 245 +++++++++++- ...-mac80211-account-tx-rx-packets-flow.patch | 369 ++++++++++++++++++ ...ow-fast-rx-by-bypassing-stats-update.patch | 2 +- .../ath11k_nss/245-compilation_fix.patch | 21 +- .../245-revert-dev-sw-netstats-txrx-add.patch | 10 +- ...-0005-mac80211-simple-tx-for-AP-mode.patch | 99 +++++ ...mac80211-fix-unconditional-sta-usage.patch | 2 +- ...-fix-clear-peer-keys-during-disassoc.patch | 50 +++ ...-fix-tkip-encryption-traffic-failure.patch | 25 ++ ...ncapsulation-of-EAPOL-frames-if-OFFL.patch | 232 +++++++++++ .../702-ath11k-fix-memory-leak-in-dp-rx.patch | 48 +++ ...-the-frame-to-driver-tx-ops-directly.patch | 74 ++++ ...se-HW-checksum-offload-only-for-ethm.patch | 41 +- .../patches/ath11k_nss/900-fix-build.patch | 14 +- 24 files changed, 1611 insertions(+), 86 deletions(-) create mode 100644 package/kernel/mac80211/patches/ath11k_nss/033-ath11k-fix-for-peer-memory-corruption.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/199-mac80211-fix-xmit-callback-when-hwencap-enable-in-st.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/203-mac80211-ath11k-fw-dynamic-muedca.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/211-ath11k-add-obss-pd-support.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/234-002-mac80211-account-tx-rx-packets-flow.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/335-0005-mac80211-simple-tx-for-AP-mode.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/357-ath11k-fix-clear-peer-keys-during-disassoc.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/359-ath11k-fix-tkip-encryption-traffic-failure.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/702-ath11k-fix-memory-leak-in-dp-rx.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/033-ath11k-fix-for-peer-memory-corruption.patch b/package/kernel/mac80211/patches/ath11k_nss/033-ath11k-fix-for-peer-memory-corruption.patch new file mode 100644 index 00000000000000..5c9c723913b09a --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/033-ath11k-fix-for-peer-memory-corruption.patch @@ -0,0 +1,48 @@ +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -4178,22 +4178,28 @@ static int ath11k_clear_peer_keys(struct + int ret; + int i; + u32 flags = 0; ++ struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; + + lockdep_assert_held(&ar->conf_mutex); + + spin_lock_bh(&ab->base_lock); + peer = ath11k_peer_find(ab, arvif->vdev_id, addr); +- spin_unlock_bh(&ab->base_lock); +- +- if (!peer) ++ if (!peer) { ++ spin_unlock_bh(&ab->base_lock); + return -ENOENT; ++ } ++ for (i = 0; i < ARRAY_SIZE(keys); i++) { ++ keys[i]= peer->keys[i]; ++ peer->keys[i]= NULL; ++ } ++ spin_unlock_bh(&ab->base_lock); + +- for (i = 0; i < ARRAY_SIZE(peer->keys); i++) { +- if (!peer->keys[i]) ++ for (i = 0; i < ARRAY_SIZE(keys); i++) { ++ if (!keys[i]) + continue; + + /* key flags are not required to delete the key */ +- ret = ath11k_install_key(arvif, peer->keys[i], ++ ret = ath11k_install_key(arvif, keys[i], + DISABLE_KEY, addr, flags); + if (ret < 0 && first_errno == 0) + first_errno = ret; +@@ -4201,10 +4207,6 @@ static int ath11k_clear_peer_keys(struct + if (ret < 0) + ath11k_warn(ab, "failed to remove peer key %d: %d\n", + i, ret); +- +- spin_lock_bh(&ab->base_lock); +- peer->keys[i] = NULL; +- spin_unlock_bh(&ab->base_lock); + } + + return first_errno; diff --git a/package/kernel/mac80211/patches/ath11k_nss/142-ath11k-adding-support-for-mgmt-frame-stats.patch b/package/kernel/mac80211/patches/ath11k_nss/142-ath11k-adding-support-for-mgmt-frame-stats.patch index 18d0d461c9cfe9..f1dfc0f7b9a887 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/142-ath11k-adding-support-for-mgmt-frame-stats.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/142-ath11k-adding-support-for-mgmt-frame-stats.patch @@ -3,7 +3,7 @@ @@ -311,6 +311,16 @@ struct ath11k_rekey_data { bool enable_offload; }; - + +#define ATH11K_STATS_MGMT_FRM_TYPE_MAX 16 + +struct ath11k_mgmt_frame_stats { @@ -24,14 +24,14 @@ + + struct ath11k_mgmt_frame_stats mgmt_stats; }; - + struct ath11k_vif_iter { --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c @@ -1588,6 +1588,87 @@ static const struct file_operations fops .llseek = default_llseek, }; - + +static ssize_t ath11k_dump_mgmt_stats(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) +{ @@ -123,12 +123,12 @@ + 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, --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6146,9 +6146,9 @@ static int ath11k_mac_mgmt_tx(struct ath +@@ -6148,9 +6148,9 @@ static int ath11k_mac_mgmt_tx(struct ath */ if (is_prb_rsp && atomic_read(&ar->num_pending_mgmt_tx) > ATH11K_PRB_RSP_DROP_THRESHOLD) { @@ -138,9 +138,9 @@ - return -ENOSPC; + return -EBUSY; } - + if (skb_queue_len_lockless(q) >= ATH11K_TX_MGMT_NUM_PENDING_MAX) { -@@ -6174,9 +6174,11 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6176,9 +6176,11 @@ static void ath11k_mac_op_tx(struct ieee struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_key_conf *key = info->control.hw_key; @@ -150,9 +150,9 @@ bool is_prb_rsp; + u16 frm_type = 0; int ret; - + memset(skb_cb, 0, sizeof(*skb_cb)); -@@ -6190,12 +6192,21 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6192,12 +6194,21 @@ static void ath11k_mac_op_tx(struct ieee if (info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { skb_cb->flags |= ATH11K_SKB_HW_80211_ENCAP; } else if (ieee80211_is_mgmt(hdr->frame_control)) { @@ -179,11 +179,11 @@ --- 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 - + peer->sec_type = HAL_ENCRYPT_TYPE_OPEN; peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; + peer->vif = arvif->vif; - + if (sta) { arsta = ath11k_sta_to_arsta(sta); --- a/drivers/net/wireless/ath/ath11k/peer.h @@ -209,12 +209,12 @@ + struct ath11k_mgmt_frame_stats *mgmt_stats; + u16 frm_type; int num_mgmt; - + spin_lock_bh(&ar->txmgmt_idr_lock); @@ -5850,6 +5856,31 @@ static int wmi_process_mgmt_tx_comp(stru info->status.ack_signal = tx_compl_param->ack_rssi; } - + + hdr = (struct ieee80211_hdr *)msdu->data; + frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, hdr->frame_control); + @@ -241,7 +241,7 @@ + +skip_mgmt_stats: ieee80211_tx_status_irqsafe(ar->hw, msdu); - + num_mgmt = atomic_dec_if_positive(&ar->num_pending_mgmt_tx); @@ -7519,6 +7550,11 @@ static void ath11k_mgmt_rx_event(struct struct ieee80211_hdr *hdr; @@ -252,11 +252,11 @@ + struct ath11k_vif *arvif; + struct ath11k_mgmt_frame_stats *mgmt_stats; + u16 frm_type = 0; - + if (ath11k_pull_mgmt_rx_params_tlv(ab, skb, &rx_ev) != 0) { ath11k_warn(ab, "failed to extract mgmt rx event"); @@ -7584,7 +7620,34 @@ static void ath11k_mgmt_rx_event(struct - + hdr = (struct ieee80211_hdr *)skb->data; fc = le16_to_cpu(hdr->frame_control); + frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, fc); @@ -285,7 +285,7 @@ + mgmt_stats->rx_cnt[frm_type]++; + + spin_unlock_bh(&ar->data_lock); - + +skip_mgmt_stats: /* Firmware is guaranteed to report all essential management frames via * WMI while it can deliver some extra via HTT. Since there can be diff --git a/package/kernel/mac80211/patches/ath11k_nss/191-ath11k-add-mgmt-and-data-ack-rssi.patch b/package/kernel/mac80211/patches/ath11k_nss/191-ath11k-add-mgmt-and-data-ack-rssi.patch index 6d8cdb83fd73cc..9059e5180f63f0 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/191-ath11k-add-mgmt-and-data-ack-rssi.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/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 -@@ -9623,6 +9623,8 @@ static int __ath11k_mac_register(struct +@@ -9625,6 +9625,8 @@ static int __ath11k_mac_register(struct wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch b/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch index 3a4ece0f6a6683..6a6b7905637b4a 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch @@ -2989,7 +2989,7 @@ Signed-off-by: Sriram R int ath11k_dp_pdev_reo_setup(struct ath11k_base *ab); --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6365,6 +6365,16 @@ static int ath11k_mac_op_start(struct ie +@@ -6367,6 +6367,16 @@ static int ath11k_mac_op_start(struct ie goto err; } diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch b/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch index f829f7adc2fd7d..af04672a2498ae 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch @@ -533,7 +533,7 @@ Signed-off-by: Sriram R static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, -@@ -4293,6 +4337,26 @@ static int ath11k_mac_op_set_key(struct +@@ -4295,6 +4339,26 @@ static int ath11k_mac_op_set_key(struct spin_lock_bh(&ab->base_lock); peer = ath11k_peer_find(ab, arvif->vdev_id, peer_addr); @@ -560,7 +560,7 @@ Signed-off-by: Sriram R if (peer && cmd == SET_KEY) { peer->keys[key->keyidx] = key; if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { -@@ -4331,9 +4395,8 @@ static int ath11k_mac_op_set_key(struct +@@ -4333,9 +4397,8 @@ static int ath11k_mac_op_set_key(struct break; } } @@ -571,7 +571,7 @@ Signed-off-by: Sriram R exit: mutex_unlock(&ar->conf_mutex); return ret; -@@ -6214,10 +6277,14 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6216,10 +6279,14 @@ static void ath11k_mac_op_tx(struct ieee if (control->sta) arsta = ath11k_sta_to_arsta(control->sta); @@ -587,7 +587,7 @@ Signed-off-by: Sriram R } } -@@ -6239,6 +6306,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; @@ -596,7 +596,7 @@ Signed-off-by: Sriram R if (ath11k_debugfs_rx_filter(ar)) tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar); } -@@ -6537,7 +6606,7 @@ static int ath11k_mac_setup_vdev_create_ +@@ -6539,7 +6608,7 @@ static int ath11k_mac_setup_vdev_create_ return 0; } @@ -605,7 +605,7 @@ Signed-off-by: Sriram R struct ieee80211_vif *vif) { struct ath11k *ar = hw->priv; -@@ -6583,6 +6652,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; } @@ -614,7 +614,7 @@ Signed-off-by: Sriram R } static bool ath11k_mac_vif_ap_active_any(struct ath11k_base *ab) -@@ -6713,6 +6784,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); @@ -623,7 +623,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", -@@ -6853,7 +6926,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); @@ -659,7 +659,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, -@@ -6977,6 +7077,7 @@ err_peer_del: +@@ -6979,6 +7079,7 @@ err_peer_del: } err_vdev_del: @@ -667,7 +667,7 @@ Signed-off-by: Sriram R ath11k_mac_vdev_delete(ar, arvif); spin_lock_bh(&ar->data_lock); list_del(&arvif->list); -@@ -7487,6 +7588,10 @@ ath11k_mac_update_vif_chan(struct ath11k +@@ -7489,6 +7590,10 @@ ath11k_mac_update_vif_chan(struct ath11k arvif->vdev_id, ret); continue; } @@ -678,7 +678,7 @@ Signed-off-by: Sriram R } /* Restart the internal monitor vdev on new channel */ -@@ -8769,6 +8874,8 @@ static void ath11k_mac_op_sta_statistics +@@ -8771,6 +8876,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); @@ -687,7 +687,7 @@ Signed-off-by: Sriram R } #if IS_ENABLED(CONFIG_IPV6) -@@ -9188,6 +9295,7 @@ static const struct ieee80211_ops ath11k +@@ -9190,6 +9297,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, @@ -695,7 +695,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, -@@ -9573,7 +9681,8 @@ static int __ath11k_mac_register(struct +@@ -9575,7 +9683,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); @@ -705,7 +705,7 @@ Signed-off-by: Sriram R } ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; -@@ -9688,6 +9797,9 @@ static int __ath11k_mac_register(struct +@@ -9690,6 +9799,9 @@ static int __ath11k_mac_register(struct ab->hw_params.bios_sar_capa) ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa; @@ -734,15 +734,54 @@ Signed-off-by: Sriram R } ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "peer map vdev %d peer %pM id %d\n", -@@ -332,6 +335,8 @@ static int __ath11k_peer_delete(struct a +@@ -298,17 +301,13 @@ static int __ath11k_peer_delete(struct a - reinit_completion(&ar->peer_delete_done); + lockdep_assert_held(&ar->conf_mutex); ++ reinit_completion(&ar->peer_delete_done); + ath11k_nss_peer_delete(ar->ab, addr); + + mutex_lock(&ab->tbl_mtx_lock); + spin_lock_bh(&ab->base_lock); + + peer = ath11k_peer_find_by_addr(ab, addr); +- /* Check if the found peer is what we want to remove. +- * While the sta is transitioning to another band we may +- * have 2 peer with the same addr assigned to different +- * vdev_id. Make sure we are deleting the correct peer. +- */ +- if (peer && peer->vdev_id == vdev_id) +- ath11k_peer_rhash_delete(ab, peer); + + /* 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 + return -EINVAL; + } + ++ /* Check if the found peer is what we want to remove. ++ * While the sta is transitioning to another band we may ++ * have 2 peer with the same addr assigned to different ++ * vdev_id. Make sure we are deleting the correct peer. ++ */ ++ if (peer && peer->vdev_id == vdev_id) ++ ath11k_peer_rhash_delete(ab, peer); ++ + spin_unlock_bh(&ab->base_lock); + mutex_unlock(&ab->tbl_mtx_lock); + +- reinit_completion(&ar->peer_delete_done); + ret = ath11k_wmi_send_peer_delete_cmd(ar, addr, vdev_id); if (ret) { - ath11k_warn(ab, +@@ -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 { 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/ath11k_nss/199-mac80211-fix-xmit-callback-when-hwencap-enable-in-st.patch new file mode 100644 index 00000000000000..87c2a52b676f21 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/199-mac80211-fix-xmit-callback-when-hwencap-enable-in-st.patch @@ -0,0 +1,35 @@ +From c3389f87ea09dea804cda2483922e03ad3eb6c79 Mon Sep 17 00:00:00 2001 +From: P Praneesh +Date: Thu, 18 Jun 2020 00:07:15 +0530 +Subject: [PATCH] mac80211: fix xmit callback when hwencap enable in sta + +Since transmit control port uses same callback for both +(ieee80211_subif_start_xmit) ethernet mode and native +wifi mode, which cause regression in ethernet mode +when we use DUT as a STA with encryption(psk2+ccmp). + +Added hardware encap check to filter out ethernet mode +packets to follow ieee80211_subif_start_xmit_8023 callback. + +Signed-off-by: P Praneesh +--- + net/mac80211/tx.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -6213,7 +6213,13 @@ start_xmit: + mutex_lock(&local->mtx); + + local_bh_disable(); +- __ieee80211_subif_start_xmit(skb, skb->dev, flags, ctrl_flags, cookie); ++ ++ /* 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); ++ + local_bh_enable(); + + mutex_unlock(&local->mtx); diff --git a/package/kernel/mac80211/patches/ath11k_nss/203-mac80211-ath11k-fw-dynamic-muedca.patch b/package/kernel/mac80211/patches/ath11k_nss/203-mac80211-ath11k-fw-dynamic-muedca.patch new file mode 100644 index 00000000000000..df2d3f73da286c --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/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 +@@ -9304,4 +9304,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 +@@ -7358,6 +7358,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 +@@ -7927,3 +7927,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 +@@ -20133,6 +20133,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/211-ath11k-add-obss-pd-support.patch b/package/kernel/mac80211/patches/ath11k_nss/211-ath11k-add-obss-pd-support.patch new file mode 100644 index 00000000000000..ddae9fcbc50e7d --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/211-ath11k-add-obss-pd-support.patch @@ -0,0 +1,56 @@ +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/214-ath11k-qos-null-frame-tx-over-wmi.patch b/package/kernel/mac80211/patches/ath11k_nss/214-ath11k-qos-null-frame-tx-over-wmi.patch index bd8bd86146e9f5..a69c5b2af244f8 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/214-ath11k-qos-null-frame-tx-over-wmi.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/214-ath11k-qos-null-frame-tx-over-wmi.patch @@ -22,7 +22,7 @@ Signed-off-by: Sowmiya Sree Elavalagan --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6127,6 +6127,16 @@ static int ath11k_mac_mgmt_tx_wmi(struct +@@ -6129,6 +6129,16 @@ static int ath11k_mac_mgmt_tx_wmi(struct ATH11K_SKB_CB(skb)->paddr = paddr; @@ -39,7 +39,7 @@ Signed-off-by: Sowmiya Sree Elavalagan ret = ath11k_wmi_mgmt_send(ar, arvif->vdev_id, buf_id, skb); if (ret) { ath11k_warn(ar->ab, "failed to send mgmt frame: %d\n", ret); -@@ -6194,8 +6204,8 @@ static void ath11k_mgmt_over_wmi_tx_work +@@ -6196,8 +6206,8 @@ static void ath11k_mgmt_over_wmi_tx_work } } @@ -50,7 +50,7 @@ Signed-off-by: Sowmiya Sree Elavalagan { struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue; -@@ -6257,7 +6267,7 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6259,7 +6269,7 @@ static void ath11k_mac_op_tx(struct ieee } else if (ieee80211_is_mgmt(hdr->frame_control)) { frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, hdr->frame_control); is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control); @@ -59,7 +59,7 @@ Signed-off-by: Sowmiya Sree Elavalagan if (ret) { if (ret != -EBUSY) ath11k_warn(ar->ab, "failed to queue management frame %d\n", -@@ -6272,6 +6282,20 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6274,6 +6284,20 @@ static void ath11k_mac_op_tx(struct ieee spin_unlock_bh(&ar->data_lock); } return; diff --git a/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch b/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch index 72d27789b8c1e8..d64a258015780e 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch @@ -820,7 +820,7 @@ Signed-off-by: Ramya Gnanasekar { struct ath11k *ar = hw->priv; struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); -@@ -6336,6 +6336,7 @@ static int ath11k_mac_config_mon_status_ +@@ -6338,6 +6338,7 @@ static int ath11k_mac_config_mon_status_ tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar); } @@ -828,7 +828,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; ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, -@@ -9766,8 +9767,6 @@ static int __ath11k_mac_register(struct +@@ -9768,8 +9769,6 @@ static int __ath11k_mac_register(struct wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); 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 index db3b2820d0f738..a3e8b7961b01fc 100644 --- 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 @@ -106,17 +106,20 @@ Signed-off-by: Maharaja Kennadyrajan 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 -@@ -7,7 +7,6 @@ - - #include "debugfs_sta.h" - #include "core.h" --#include "peer.h" - #include "debug.h" - #include "dp_tx.h" - #include "debugfs_htt_stats.h" -@@ -146,9 +145,6 @@ static ssize_t ath11k_dbg_sta_dump_tx_st +@@ -146,9 +146,6 @@ static ssize_t ath11k_dbg_sta_dump_tx_st const int size = 2 * 4096; char *buf; @@ -126,7 +129,7 @@ Signed-off-by: Maharaja Kennadyrajan buf = kzalloc(size, GFP_KERNEL); if (!buf) return -ENOMEM; -@@ -156,6 +152,12 @@ static ssize_t ath11k_dbg_sta_dump_tx_st +@@ -156,6 +153,12 @@ static ssize_t ath11k_dbg_sta_dump_tx_st mutex_lock(&ar->conf_mutex); spin_lock_bh(&ar->data_lock); @@ -139,7 +142,7 @@ Signed-off-by: Maharaja Kennadyrajan 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 +231,11 @@ static ssize_t ath11k_dbg_sta_dump_tx_st +@@ -229,6 +232,11 @@ static ssize_t ath11k_dbg_sta_dump_tx_st mutex_unlock(&ar->conf_mutex); return retval; @@ -151,6 +154,222 @@ Signed-off-by: Maharaja Kennadyrajan } 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 @@ -249,7 +468,7 @@ Signed-off-by: Maharaja Kennadyrajan --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6250,6 +6250,7 @@ static void ath11k_mac_op_tx(struct ieee +@@ -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; @@ -257,7 +476,7 @@ Signed-off-by: Maharaja Kennadyrajan bool is_prb_rsp; u16 frm_type = 0; int ret; -@@ -6310,6 +6311,15 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6312,6 +6313,15 @@ static void ath11k_mac_op_tx(struct ieee ieee80211_free_txskb(ar->hw, skb); return; } 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 new file mode 100644 index 00000000000000..7488f0c2bfce6b --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/234-002-mac80211-account-tx-rx-packets-flow.patch @@ -0,0 +1,369 @@ +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/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch b/package/kernel/mac80211/patches/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch index 84f15426ec13b7..bb46abada6b9e3 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch @@ -395,7 +395,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 -@@ -5195,6 +5195,14 @@ static int ath11k_mac_op_sta_state(struc +@@ -5197,6 +5197,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/245-compilation_fix.patch b/package/kernel/mac80211/patches/ath11k_nss/245-compilation_fix.patch index f3ad6dea74e038..b4a735f10fc0e6 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/245-compilation_fix.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/245-compilation_fix.patch @@ -77,7 +77,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran /* then other type-dependent work */ --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4662,19 +4662,21 @@ static void ieee80211_8023_xmit(struct i +@@ -4668,19 +4668,21 @@ static void ieee80211_8023_xmit(struct i ieee80211_aggr_check(sdata, sta, skb); @@ -111,7 +111,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran } skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); -@@ -4730,7 +4732,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4739,7 +4741,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 +120,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran struct sta_info *sta; #ifdef CPTCFG_MAC80211_NSS_SUPPORT -@@ -4748,9 +4750,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4757,9 +4759,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 goto out; } @@ -137,7 +137,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran goto skip_offload; key = rcu_dereference(sta->ptk[sta->ptk_idx]); -@@ -4761,6 +4767,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4770,6 +4776,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); @@ -147,7 +147,16 @@ Signed-off-by: Gautham Kumar Senthilkumaran --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c -@@ -5429,8 +5429,6 @@ void ieee80211_rx_list(struct ieee80211_ +@@ -5342,7 +5342,7 @@ void ieee80211_rx_list(struct ieee80211_ + + 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; @@ -156,7 +165,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran /* * Frames with failed FCS/PLCP checksum are not returned, * all other frames are returned without radiotap header -@@ -5450,7 +5448,6 @@ void ieee80211_rx_list(struct ieee80211_ +@@ -5463,7 +5461,6 @@ void ieee80211_rx_list(struct ieee80211_ __ieee80211_rx_handle_packet(hw, pubsta, skb, list); } 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 index 79c179a2d1b55e..6f7c1aadd95b64 100644 --- 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 @@ -68,7 +68,7 @@ Signed-off-by: Tamizh Chelvam netif_receive_skb(skb); } } -@@ -2684,7 +2704,7 @@ ieee80211_deliver_skb(struct ieee80211_r +@@ -2686,7 +2706,7 @@ ieee80211_deliver_skb(struct ieee80211_r skb = rx->skb; xmit_skb = NULL; @@ -77,7 +77,7 @@ Signed-off-by: Tamizh Chelvam if (rx->sta) { /* The seqno index has the same property as needed -@@ -4095,7 +4115,7 @@ static void ieee80211_rx_cooked_monitor( +@@ -4098,7 +4118,7 @@ static void ieee80211_rx_cooked_monitor( } prev_dev = sdata->dev; @@ -86,7 +86,7 @@ Signed-off-by: Tamizh Chelvam } if (prev_dev) { -@@ -4803,7 +4823,7 @@ static void ieee80211_rx_8023(struct iee +@@ -4806,7 +4826,7 @@ static void ieee80211_rx_8023(struct iee skb->dev = fast_rx->dev; @@ -125,7 +125,7 @@ Signed-off-by: Tamizh Chelvam if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; -@@ -4343,7 +4355,7 @@ void __ieee80211_subif_start_xmit(struct +@@ -4346,7 +4358,7 @@ void __ieee80211_subif_start_xmit(struct goto out; } @@ -134,7 +134,7 @@ Signed-off-by: Tamizh Chelvam ieee80211_xmit(sdata, sta, skb); } -@@ -4711,7 +4723,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4717,7 +4729,7 @@ static void ieee80211_8023_xmit(struct i info->ack_frame_id = ieee80211_store_ack_skb(local, skb, &info->flags, NULL); diff --git a/package/kernel/mac80211/patches/ath11k_nss/335-0005-mac80211-simple-tx-for-AP-mode.patch b/package/kernel/mac80211/patches/ath11k_nss/335-0005-mac80211-simple-tx-for-AP-mode.patch new file mode 100644 index 00000000000000..d859d038003196 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/335-0005-mac80211-simple-tx-for-AP-mode.patch @@ -0,0 +1,99 @@ +From 190652ce1b56a41ed3a99d9f9c9160deba34810b Mon Sep 17 00:00:00 2001 +From: Venkateswara Naralasetty +Date: Thu, 18 Nov 2021 12:28:31 +0530 +Subject: [PATCH] mac80211: simple tx for AP mode + +Introduced new API ieee80211_8023_xmit_ap to make tx simple and +to avoid unnecessary checks for AP mode. + +Signed-off-by: Venkateswara Naralasetty +Signed-off-by: Aloka Dixit +--- + net/mac80211/tx.c | 40 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 40 insertions(+) + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -4748,6 +4748,70 @@ out_free: + kfree_skb(skb); + } + ++void ieee80211_8023_xmit_ap(struct ieee80211_sub_if_data *sdata, ++ struct net_device *dev, struct sta_info *sta, ++ struct ieee80211_key *key, struct sk_buff *skb) ++{ ++ struct ieee80211_tx_info *info; ++ struct ieee80211_local *local = sdata->local; ++ struct ieee80211_sta *pubsta = NULL; ++ struct ieee80211_tx_control control = {}; ++ unsigned long flags; ++ int q; ++ u16 q_map; ++ ++ /* ++ * If the skb is shared we need to obtain our own copy. ++ */ ++ skb = skb_share_check(skb, GFP_ATOMIC); ++ ++ if (unlikely(!skb)) ++ return; ++ ++ info = IEEE80211_SKB_CB(skb); ++ memset(info, 0, sizeof(*info)); ++ ++ if (unlikely(skb->sk && ++ skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) ++ info->ack_frame_id = ieee80211_store_ack_skb(local, skb, ++ &info->flags, NULL); ++ ++ info->flags |= IEEE80211_TX_CTL_HW_80211_ENCAP; ++ info->control.vif = &sdata->vif; ++ ++ if (key) ++ info->control.hw_key = &key->conf; ++ ++ q_map = skb_get_queue_mapping(skb); ++ q = sdata->vif.hw_queue[q_map]; ++ ++ 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); ++ ++ if (local->queue_stop_reasons[q] || !skb_queue_empty(&local->pending[q])) { ++ skb_queue_tail(&local->pending[q], skb); ++ spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); ++ return; ++ } ++ ++ spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); ++ ++ if (sta && sta->uploaded) ++ pubsta = &sta->sta; ++ ++ control.sta = pubsta; ++ ++ 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 + if (key && (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))) + goto skip_offload; + ++ if (sdata->vif.type == NL80211_IFTYPE_AP) { ++ ieee80211_8023_xmit_ap(sdata, dev, sta, key, skb); ++ goto out; ++ } ++ + sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift); + tx_offload: + ieee80211_8023_xmit(sdata, dev, sta, key, skb); diff --git a/package/kernel/mac80211/patches/ath11k_nss/342-mac80211-fix-unconditional-sta-usage.patch b/package/kernel/mac80211/patches/ath11k_nss/342-mac80211-fix-unconditional-sta-usage.patch index d8b3ff3f02e037..e4890a3654c3b3 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/342-mac80211-fix-unconditional-sta-usage.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/342-mac80211-fix-unconditional-sta-usage.patch @@ -33,7 +33,7 @@ Signed-off-by: Tamizh Chelvam --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4719,12 +4719,12 @@ static void ieee80211_8023_xmit(struct i +@@ -4725,12 +4725,12 @@ static void ieee80211_8023_xmit(struct i if (unlikely(skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS && diff --git a/package/kernel/mac80211/patches/ath11k_nss/357-ath11k-fix-clear-peer-keys-during-disassoc.patch b/package/kernel/mac80211/patches/ath11k_nss/357-ath11k-fix-clear-peer-keys-during-disassoc.patch new file mode 100644 index 00000000000000..5050192acc64ae --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/357-ath11k-fix-clear-peer-keys-during-disassoc.patch @@ -0,0 +1,50 @@ +From 451cd8d4f107750d86a51c3cf750015676991d17 Mon Sep 17 00:00:00 2001 +From: Karthikeyan Kathirvel +Date: Thu, 11 Aug 2022 21:27:16 +0530 +Subject: [PATCH] ath11k: fix clearing peer keys during sta state auth to assoc + +During station state change from AUTHORIZED to ASSOC, driver must clear its key +from hw. Ath11k clearing the keys during ASSOC to AUTH which is not a +valid sequence and there is a chance of accessing ptr after free. + +Clear the peer keys while the state of station changes from AUTHORIZED +to ASSOC. + +Signed-off-by: Karthikeyan Kathirvel +--- + drivers/net/wireless/ath/ath11k/mac.c | 37 ++++++++++++++++++++--------------- + 1 file changed, 21 insertions(+), 16 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -4708,12 +4708,6 @@ static int ath11k_station_disassoc(struc + return ret; + } + +- 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; +- } + return 0; + } + +@@ -5176,6 +5170,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); ++ ++ /* 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); 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 new file mode 100644 index 00000000000000..d8c907556645cf --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/359-ath11k-fix-tkip-encryption-traffic-failure.patch @@ -0,0 +1,25 @@ +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/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch b/package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch new file mode 100644 index 00000000000000..b64643140a14b1 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch @@ -0,0 +1,232 @@ +From f2c96599c02eb0d47602d000fe0f40358c10c892 Mon Sep 17 00:00:00 2001 +From: Aaradhana Sahu +Date: Fri, 26 Aug 2022 17:54:37 +0530 +Subject: [PATCH] mac80211: Avoid encapsulation of EAPOL frames if OFFLOAD_ENCAP is enabled + +EAP Frames over NL80211 Control port are 802.11 Native WiFi +encapsulated by default, but for a vdev operating in 802.3, when FW doesn’t +advertise WMI_SERVICE_EAPOL_OVER_NWIFI, it cannot accept an 802.11 +Native WiFi frame. + +Allow EAP Frames over NL80211 Control port to be passed as 802.3 +if vif has IEEE80211_OFFLOAD_ENCAP_ENABLED set. + +Signed-off-by: Rameshkumar Sundaram +Signed-off-by: Aaradhana Sahu +--- + net/mac80211/ieee80211_i.h | 5 ++++ + net/mac80211/tx.c | 58 ++++++++++++++++++++++++++------------ + 2 files changed, 45 insertions(+), 18 deletions(-) + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -2062,6 +2062,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); ++netdev_tx_t __ieee80211_subif_start_xmit_8023(struct sk_buff *skb, ++ struct net_device *dev, ++ u32 info_flags, ++ u32 ctrl_flags, ++ u64 *cookie); + void __ieee80211_subif_start_xmit(struct sk_buff *skb, + struct net_device *dev, + u32 info_flags, +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -39,7 +39,8 @@ + + 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); ++ struct ieee80211_key *key, struct sk_buff *skb, ++ u32 info_flags, u32 ctrl_flags, u64 *cookie); + + 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 && + !is_multicast_ether_addr(skb->data)) { + 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); + rcu_read_unlock(); + return; + } +@@ -4657,19 +4663,29 @@ 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, +- struct ieee80211_key *key, struct sk_buff *skb) ++ struct ieee80211_key *key, struct sk_buff *skb, ++ 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 + 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 + 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))) + info->ack_frame_id = ieee80211_store_ack_skb(local, skb, + &info->flags, NULL); + +@@ -4750,7 +4768,8 @@ out_free: + + void ieee80211_8023_xmit_ap(struct ieee80211_sub_if_data *sdata, + struct net_device *dev, struct sta_info *sta, +- struct ieee80211_key *key, struct sk_buff *skb) ++ struct ieee80211_key *key, struct sk_buff *skb, ++ u32 info_flags, u32 ctrl_flags, u64 *cookie) + { + struct ieee80211_tx_info *info; + struct ieee80211_local *local = sdata->local; +@@ -4759,6 +4778,9 @@ void ieee80211_8023_xmit_ap(struct ieee8 + unsigned long flags; + int q; + u16 q_map; ++ struct ethhdr *ehdr = (struct ethhdr *)skb->data; ++ unsigned char *ra = ehdr->h_dest; ++ bool multicast = is_multicast_ether_addr(ra); + + /* + * If the skb is shared we need to obtain our own copy. +@@ -4770,11 +4792,13 @@ void ieee80211_8023_xmit_ap(struct ieee8 + + info = IEEE80211_SKB_CB(skb); + memset(info, 0, sizeof(*info)); ++ info->flags |= info_flags; + +- if (unlikely(skb->sk && +- skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) ++ if (unlikely((skb->sk && ++ skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) || ++ ((ctrl_flags & IEEE80211_TX_CTL_REQ_TX_STATUS) && !multicast))) + info->ack_frame_id = ieee80211_store_ack_skb(local, skb, +- &info->flags, NULL); ++ &info->flags, cookie); + + 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); + } +- + 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); ++} ++ ++netdev_tx_t __ieee80211_subif_start_xmit_8023(struct sk_buff *skb, ++ struct net_device *dev, ++ u32 info_flags, ++ u32 ctrl_flags, ++ u64 *cookie) ++{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ethhdr *ehdr = (struct ethhdr *)skb->data; + struct ieee80211_key *key = NULL; + struct sta_info *sta; ++ bool is_eapol; + + #ifdef CPTCFG_MAC80211_NSS_SUPPORT + ieee80211_xmit_nss_fixup(skb, dev); +@@ -4834,14 +4867,15 @@ netdev_tx_t ieee80211_subif_start_xmit_8 + kfree_skb(skb); + goto out; + } ++ is_eapol = (sdata->control_port_protocol == ehdr->h_proto); + + if (ieee80211_hw_check(&sdata->local->hw, SUPPORTS_NSS_OFFLOAD)) { + if (unlikely(IS_ERR_OR_NULL(sta) || !sta->uploaded)) + sta = NULL; + goto tx_offload; + } else if (unlikely(IS_ERR_OR_NULL(sta) || !sta->uploaded || +- !test_sta_flag(sta, WLAN_STA_AUTHORIZED) || +- sdata->control_port_protocol == ehdr->h_proto)) ++ (!test_sta_flag(sta, WLAN_STA_AUTHORIZED) && !is_eapol) || ++ (is_eapol && !(sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)))) + goto skip_offload; + + key = rcu_dereference(sta->ptk[sta->ptk_idx]); +@@ -4852,13 +4886,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 + goto skip_offload; + + if (sdata->vif.type == NL80211_IFTYPE_AP) { +- ieee80211_8023_xmit_ap(sdata, dev, sta, key, skb); ++ ieee80211_8023_xmit_ap(sdata, dev, sta, key, skb, info_flags, ctrl_flags, cookie); + goto out; + } + + sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift); + tx_offload: +- ieee80211_8023_xmit(sdata, dev, sta, key, skb); ++ ieee80211_8023_xmit(sdata, dev, sta, key, skb, info_flags, ctrl_flags, cookie); + goto out; + + skip_offload: +@@ -6364,13 +6398,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_8023(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/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 new file mode 100644 index 00000000000000..1bfa9b89b45c5f --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/702-ath11k-fix-memory-leak-in-dp-rx.patch @@ -0,0 +1,48 @@ +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 new file mode 100644 index 00000000000000..31db236d5fd4ef --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch @@ -0,0 +1,74 @@ +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/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch b/package/kernel/mac80211/patches/ath11k_nss/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch index c0b787bd687dee..e5b4d7d9e7ef4e 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch @@ -30,8 +30,8 @@ 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); -@@ -3632,7 +3634,7 @@ ieee80211_sdata_netdev_features(struct i + struct ieee80211_key *key, struct sk_buff *skb, +@@ -3633,7 +3635,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; -@@ -3650,7 +3652,7 @@ ieee80211_tx_skb_fixup(struct sk_buff *s +@@ -3651,7 +3653,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) -@@ -3796,7 +3798,7 @@ static bool ieee80211_xmit_fast(struct i +@@ -3797,7 +3799,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; -@@ -4336,7 +4338,7 @@ void __ieee80211_subif_start_xmit(struct +@@ -4345,7 +4347,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,7 +67,15 @@ Signed-off-by: Tamizh Chelvam Raja if (!skb) { len = 0; goto out; -@@ -4691,7 +4693,7 @@ static void ieee80211_8023_xmit(struct i +@@ -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 } } @@ -76,6 +84,27 @@ 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 diff --git a/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch b/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch index 916f16eb81989f..67d6e5285bdd94 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch @@ -35,17 +35,7 @@ memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); } -@@ -2364,7 +2375,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); -@@ -2463,7 +2475,7 @@ static void ath11k_dp_rx_h_mpdu(struct a +@@ -2464,7 +2475,7 @@ static void ath11k_dp_rx_h_mpdu(struct a struct ieee80211_rx_status *rx_status, bool *fast_rx) { @@ -54,7 +44,7 @@ enum hal_encrypt_type enctype; bool is_decrypted = false; struct ath11k_skb_rxcb *rxcb; -@@ -2478,7 +2490,8 @@ static void ath11k_dp_rx_h_mpdu(struct a +@@ -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); From 217aed0bc13514b772907f7b683d6925d07cee17 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 25 Dec 2023 00:15:25 -0500 Subject: [PATCH 063/225] ath11k_nss: Remove unecessary clang-tidy formatting --- ...th11k-Enable-512MB-profile-in-ath11k.patch | 722 +----------------- 1 file changed, 10 insertions(+), 712 deletions(-) diff --git a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-512MB-profile-in-ath11k.patch b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-512MB-profile-in-ath11k.patch index 41c9bf698b3f87..0e7ddb8539a207 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-512MB-profile-in-ath11k.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-512MB-profile-in-ath11k.patch @@ -148,7 +148,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 @@ -217,17 +217,7 @@ Signed-off-by: Ramya Gnanasekar unsigned int nss_offload; #ifdef CPTCFG_ATH11K_NSS_SUPPORT -@@ -35,13 +37,16 @@ MODULE_PARM_DESC(crypto_mode, "crypto mo - /* frame mode values are mapped as per enum ath11k_hw_txrx_mode */ - unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_NATIVE_WIFI; - 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)"); -+MODULE_PARM_DESC( -+ frame_mode, -+ "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)"); - - bool ath11k_ftm_mode; +@@ -42,6 +44,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"); @@ -236,7 +226,7 @@ Signed-off-by: Ramya Gnanasekar static struct ath11k_hw_params ath11k_hw_params[] = { { .hw_rev = ATH11K_HW_IPQ8074, -@@ -100,6 +105,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -100,6 +104,7 @@ static struct ath11k_hw_params ath11k_hw .num_peers = 512, .supports_suspend = false, .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), @@ -244,7 +234,7 @@ Signed-off-by: Ramya Gnanasekar .supports_regdb = false, .fix_l1ss = true, .credit_flow = false, -@@ -177,7 +183,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -177,7 +182,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = true, .coldboot_cal_ftm = true, .cbcal_restart_fw = true, @@ -253,7 +243,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = false, -@@ -259,7 +265,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -259,7 +264,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -262,7 +252,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 +431,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -271,7 +261,7 @@ 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 +@@ -509,7 +514,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -280,7 +270,7 @@ 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 +@@ -593,7 +598,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = true, .coldboot_cal_ftm = true, .cbcal_restart_fw = false, @@ -289,7 +279,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, @@ -298,7 +288,7 @@ 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 +@@ -710,7 +715,23 @@ static struct ath11k_hw_params ath11k_hw }, }; @@ -323,698 +313,6 @@ Signed-off-by: Ramya Gnanasekar { WARN_ON(!ab->hw_params.single_pdev_only); -@@ -794,8 +816,10 @@ int ath11k_core_suspend(struct ath11k_ba - - ret = ath11k_dp_rx_pktlog_stop(ab, true); - if (ret) { -- ath11k_warn(ab, "failed to stop dp rx (and timer) pktlog during suspend: %d\n", -- ret); -+ ath11k_warn( -+ ab, -+ "failed to stop dp rx (and timer) pktlog during suspend: %d\n", -+ ret); - return ret; - } - -@@ -807,13 +831,15 @@ int ath11k_core_suspend(struct ath11k_ba - - ret = ath11k_wow_enable(ab); - if (ret) { -- ath11k_warn(ab, "failed to enable wow during suspend: %d\n", ret); -+ ath11k_warn(ab, "failed to enable wow during suspend: %d\n", -+ ret); - return ret; - } - - ret = ath11k_dp_rx_pktlog_stop(ab, false); - if (ret) { -- ath11k_warn(ab, "failed to stop dp rx pktlog during suspend: %d\n", -+ ath11k_warn(ab, -+ "failed to stop dp rx pktlog during suspend: %d\n", - ret); - return ret; - } -@@ -853,7 +879,8 @@ int ath11k_core_resume(struct ath11k_bas - - ret = ath11k_hif_resume(ab); - if (ret) { -- ath11k_warn(ab, "failed to resume hif during resume: %d\n", ret); -+ ath11k_warn(ab, "failed to resume hif during resume: %d\n", -+ ret); - return ret; - } - -@@ -869,7 +896,8 @@ int ath11k_core_resume(struct ath11k_bas - - ret = ath11k_wow_wakeup(ab); - if (ret) { -- ath11k_warn(ab, "failed to wakeup wow during resume: %d\n", ret); -+ ath11k_warn(ab, "failed to wakeup wow during resume: %d\n", -+ ret); - return ret; - } - -@@ -877,7 +905,8 @@ int ath11k_core_resume(struct ath11k_bas - } - EXPORT_SYMBOL(ath11k_core_resume); - --static void ath11k_core_check_cc_code_bdfext(const struct dmi_header *hdr, void *data) -+static void ath11k_core_check_cc_code_bdfext(const struct dmi_header *hdr, -+ void *data) - { - struct ath11k_base *ab = data; - const char *magic = ATH11K_SMBIOS_BDF_EXT_MAGIC; -@@ -914,7 +943,8 @@ static void ath11k_core_check_cc_code_bd - ath11k_dbg(ab, ATH11K_DBG_BOOT, "smbios worldwide regdomain\n"); - break; - default: -- ath11k_dbg(ab, ATH11K_DBG_BOOT, "ignore smbios country code setting %d\n", -+ ath11k_dbg(ab, ATH11K_DBG_BOOT, -+ "ignore smbios country code setting %d\n", - smbios->country_code_flag); - break; - } -@@ -922,7 +952,8 @@ static void ath11k_core_check_cc_code_bd - spin_unlock_bh(&ab->base_lock); - - if (!smbios->bdf_enabled) { -- ath11k_dbg(ab, ATH11K_DBG_BOOT, "bdf variant name not found.\n"); -+ ath11k_dbg(ab, ATH11K_DBG_BOOT, -+ "bdf variant name not found.\n"); - return; - } - -@@ -933,22 +964,26 @@ static void ath11k_core_check_cc_code_bd - return; - } - -- len = min_t(size_t, -- strlen(smbios->bdf_ext), sizeof(ab->qmi.target.bdf_ext)); -+ len = min_t(size_t, strlen(smbios->bdf_ext), -+ sizeof(ab->qmi.target.bdf_ext)); - for (i = 0; i < len; i++) { -- if (!isascii(smbios->bdf_ext[i]) || !isprint(smbios->bdf_ext[i])) { -- ath11k_dbg(ab, ATH11K_DBG_BOOT, -- "bdf variant name contains non ascii chars.\n"); -+ if (!isascii(smbios->bdf_ext[i]) || -+ !isprint(smbios->bdf_ext[i])) { -+ ath11k_dbg( -+ ab, ATH11K_DBG_BOOT, -+ "bdf variant name contains non ascii chars.\n"); - return; - } - } - - /* Copy extension name without magic prefix */ -- copied = strscpy(ab->qmi.target.bdf_ext, smbios->bdf_ext + strlen(magic), -+ copied = strscpy(ab->qmi.target.bdf_ext, -+ smbios->bdf_ext + strlen(magic), - sizeof(ab->qmi.target.bdf_ext)); - if (copied < 0) { -- ath11k_dbg(ab, ATH11K_DBG_BOOT, -- "bdf variant string is longer than the buffer can accommodate\n"); -+ ath11k_dbg( -+ ab, ATH11K_DBG_BOOT, -+ "bdf variant string is longer than the buffer can accommodate\n"); - return; - } - -@@ -984,9 +1019,10 @@ int ath11k_core_check_dt(struct ath11k_b - return -ENODATA; - - if (strscpy(ab->qmi.target.bdf_ext, variant, max_len) < 0) -- ath11k_dbg(ab, ATH11K_DBG_BOOT, -- "bdf variant string is longer than the buffer can accommodate (variant: %s)\n", -- variant); -+ ath11k_dbg( -+ ab, ATH11K_DBG_BOOT, -+ "bdf variant string is longer than the buffer can accommodate (variant: %s)\n", -+ variant); - - return 0; - } -@@ -1012,24 +1048,20 @@ static int __ath11k_core_create_board_na - case ATH11K_BDF_SEARCH_BUS_AND_BOARD: - switch (name_type) { - case ATH11K_BDF_NAME_FULL: -- scnprintf(name, name_len, -- "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x,qmi-chip-id=%d,qmi-board-id=%d%s", -- ath11k_bus_str(ab->hif.bus), -- ab->id.vendor, ab->id.device, -- ab->id.subsystem_vendor, -- ab->id.subsystem_device, -- ab->qmi.target.chip_id, -- ab->qmi.target.board_id, -- variant); -+ scnprintf( -+ name, name_len, -+ "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x,qmi-chip-id=%d,qmi-board-id=%d%s", -+ ath11k_bus_str(ab->hif.bus), ab->id.vendor, -+ ab->id.device, ab->id.subsystem_vendor, -+ ab->id.subsystem_device, ab->qmi.target.chip_id, -+ ab->qmi.target.board_id, variant); - break; - case ATH11K_BDF_NAME_BUS_NAME: -- scnprintf(name, name_len, -- "bus=%s", -+ scnprintf(name, name_len, "bus=%s", - ath11k_bus_str(ab->hif.bus)); - break; - case ATH11K_BDF_NAME_CHIP_ID: -- scnprintf(name, name_len, -- "bus=%s,qmi-chip-id=%d", -+ scnprintf(name, name_len, "bus=%s,qmi-chip-id=%d", - ath11k_bus_str(ab->hif.bus), - ab->qmi.target.chip_id); - break; -@@ -1038,8 +1070,7 @@ static int __ath11k_core_create_board_na - default: - scnprintf(name, name_len, - "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s", -- ath11k_bus_str(ab->hif.bus), -- ab->qmi.target.chip_id, -+ ath11k_bus_str(ab->hif.bus), ab->qmi.target.chip_id, - ab->qmi.target.board_id, variant); - break; - } -@@ -1056,22 +1087,22 @@ static int ath11k_core_create_board_name - ATH11K_BDF_NAME_FULL); - } - --static int ath11k_core_create_fallback_board_name(struct ath11k_base *ab, char *name, -- size_t name_len) -+static int ath11k_core_create_fallback_board_name(struct ath11k_base *ab, -+ char *name, size_t name_len) - { - return __ath11k_core_create_board_name(ab, name, name_len, false, - ATH11K_BDF_NAME_FULL); - } - --static int ath11k_core_create_bus_type_board_name(struct ath11k_base *ab, char *name, -- size_t name_len) -+static int ath11k_core_create_bus_type_board_name(struct ath11k_base *ab, -+ char *name, size_t name_len) - { - return __ath11k_core_create_board_name(ab, name, name_len, false, - ATH11K_BDF_NAME_BUS_NAME); - } - --static int ath11k_core_create_chip_id_board_name(struct ath11k_base *ab, char *name, -- size_t name_len) -+static int ath11k_core_create_chip_id_board_name(struct ath11k_base *ab, -+ char *name, size_t name_len) - { - return __ath11k_core_create_board_name(ab, name, name_len, false, - ATH11K_BDF_NAME_CHIP_ID); -@@ -1093,8 +1124,8 @@ const struct firmware *ath11k_core_firmw - if (ret) - return ERR_PTR(ret); - -- ath11k_dbg(ab, ATH11K_DBG_BOOT, "firmware request %s size %zu\n", -- path, fw->size); -+ ath11k_dbg(ab, ATH11K_DBG_BOOT, "firmware request %s size %zu\n", path, -+ fw->size); - - return fw; - } -@@ -1110,10 +1141,8 @@ void ath11k_core_free_bdf(struct ath11k_ - static int ath11k_core_parse_bd_ie_board(struct ath11k_base *ab, - struct ath11k_board_data *bd, - const void *buf, size_t buf_len, -- const char *boardname, -- int ie_id, -- int name_id, -- int data_id) -+ const char *boardname, int ie_id, -+ int name_id, int data_id) - { - const struct ath11k_fw_ie *hdr; - bool name_match_found; -@@ -1135,8 +1164,8 @@ static int ath11k_core_parse_bd_ie_board - - if (buf_len < ALIGN(board_ie_len, 4)) { - ath11k_err(ab, "invalid %s length: %zu < %zu\n", -- ath11k_bd_ie_type_str(ie_id), -- buf_len, ALIGN(board_ie_len, 4)); -+ ath11k_bd_ie_type_str(ie_id), buf_len, -+ ALIGN(board_ie_len, 4)); - ret = -EINVAL; - goto out; - } -@@ -1148,24 +1177,22 @@ static int ath11k_core_parse_bd_ie_board - if (board_ie_len != strlen(boardname)) - goto next; - -- ret = memcmp(board_ie_data, boardname, strlen(boardname)); -+ ret = memcmp(board_ie_data, boardname, -+ strlen(boardname)); - if (ret) - goto next; - - name_match_found = true; - ath11k_dbg(ab, ATH11K_DBG_BOOT, - "found match %s for name '%s'", -- ath11k_bd_ie_type_str(ie_id), -- boardname); -+ ath11k_bd_ie_type_str(ie_id), boardname); - } else if (board_ie_id == data_id) { - if (!name_match_found) - /* no match found */ - goto next; - -- ath11k_dbg(ab, ATH11K_DBG_BOOT, -- "found %s for '%s'", -- ath11k_bd_ie_type_str(ie_id), -- boardname); -+ ath11k_dbg(ab, ATH11K_DBG_BOOT, "found %s for '%s'", -+ ath11k_bd_ie_type_str(ie_id), boardname); - - bd->data = board_ie_data; - bd->len = board_ie_len; -@@ -1174,8 +1201,7 @@ static int ath11k_core_parse_bd_ie_board - goto out; - } else { - ath11k_warn(ab, "unknown %s id found: %d\n", -- ath11k_bd_ie_type_str(ie_id), -- board_ie_id); -+ ath11k_bd_ie_type_str(ie_id), board_ie_id); - } - next: - /* jump over the padding */ -@@ -1195,8 +1221,7 @@ out: - static int ath11k_core_fetch_board_data_api_n(struct ath11k_base *ab, - struct ath11k_board_data *bd, - const char *boardname, -- int ie_id_match, -- int name_id, -+ int ie_id_match, int name_id, - int data_id) - { - size_t len, magic_len; -@@ -1217,14 +1242,16 @@ static int ath11k_core_fetch_board_data_ - data = bd->fw->data; - len = bd->fw->size; - -- ath11k_core_create_firmware_path(ab, filename, -- filepath, sizeof(filepath)); -+ ath11k_core_create_firmware_path(ab, filename, filepath, -+ sizeof(filepath)); - - /* magic has extra null byte padded */ - magic_len = strlen(ATH11K_BOARD_MAGIC) + 1; - if (len < magic_len) { -- ath11k_err(ab, "failed to find magic value in %s, file too short: %zu\n", -- filepath, len); -+ ath11k_err( -+ ab, -+ "failed to find magic value in %s, file too short: %zu\n", -+ filepath, len); - ret = -EINVAL; - goto err; - } -@@ -1238,8 +1265,10 @@ static int ath11k_core_fetch_board_data_ - /* magic is padded to 4 bytes */ - magic_len = ALIGN(magic_len, 4); - if (len < magic_len) { -- ath11k_err(ab, "failed: %s too small to contain board data, len: %zu\n", -- filepath, len); -+ ath11k_err( -+ ab, -+ "failed: %s too small to contain board data, len: %zu\n", -+ filepath, len); - ret = -EINVAL; - goto err; - } -@@ -1256,19 +1285,19 @@ static int ath11k_core_fetch_board_data_ - data = hdr->data; - - if (len < ALIGN(ie_len, 4)) { -- ath11k_err(ab, "invalid length for board ie_id %d ie_len %zu len %zu\n", -- ie_id, ie_len, len); -+ ath11k_err( -+ ab, -+ "invalid length for board ie_id %d ie_len %zu len %zu\n", -+ ie_id, ie_len, len); - ret = -EINVAL; - goto err; - } - - if (ie_id == ie_id_match) { - ret = ath11k_core_parse_bd_ie_board(ab, bd, data, -- ie_len, -- boardname, -+ ie_len, boardname, - ie_id_match, -- name_id, -- data_id); -+ name_id, data_id); - if (ret == -ENOENT) - /* no match found, continue */ - goto next; -@@ -1290,8 +1319,8 @@ out: - if (!bd->data || !bd->len) { - ath11k_dbg(ab, ATH11K_DBG_BOOT, - "failed to fetch %s for %s from %s\n", -- ath11k_bd_ie_type_str(ie_id_match), -- boardname, filepath); -+ ath11k_bd_ie_type_str(ie_id_match), boardname, -+ filepath); - ret = -ENODATA; - goto err; - } -@@ -1321,7 +1350,8 @@ int ath11k_core_fetch_board_data_api_1(s - #define BOARD_NAME_SIZE 200 - int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd) - { -- char *boardname = NULL, *fallback_boardname = NULL, *chip_id_boardname = NULL; -+ char *boardname = NULL, *fallback_boardname = NULL, -+ *chip_id_boardname = NULL; - char *filename, filepath[100]; - int ret = 0; - -@@ -1388,15 +1418,18 @@ int ath11k_core_fetch_bdf(struct ath11k_ - goto exit; - - ab->bd_api = 1; -- ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_DEFAULT_BOARD_FILE); -+ ret = ath11k_core_fetch_board_data_api_1(ab, bd, -+ ATH11K_DEFAULT_BOARD_FILE); - if (ret) { -- ath11k_core_create_firmware_path(ab, filename, -- filepath, sizeof(filepath)); -+ ath11k_core_create_firmware_path(ab, filename, filepath, -+ sizeof(filepath)); - ath11k_err(ab, "failed to fetch board data for %s from %s\n", - boardname, filepath); - if (memcmp(boardname, fallback_boardname, strlen(boardname))) -- ath11k_err(ab, "failed to fetch board data for %s from %s\n", -- fallback_boardname, filepath); -+ ath11k_err( -+ ab, -+ "failed to fetch board data for %s from %s\n", -+ fallback_boardname, filepath); - - ath11k_err(ab, "failed to fetch board data for %s from %s\n", - chip_id_boardname, filepath); -@@ -1411,12 +1444,14 @@ exit: - kfree(chip_id_boardname); - - if (!ret) -- ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board api %d\n", ab->bd_api); -+ ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board api %d\n", -+ ab->bd_api); - - return ret; - } - --int ath11k_core_fetch_regdb(struct ath11k_base *ab, struct ath11k_board_data *bd) -+int ath11k_core_fetch_regdb(struct ath11k_base *ab, -+ struct ath11k_board_data *bd) - { - char boardname[BOARD_NAME_SIZE], default_boardname[BOARD_NAME_SIZE]; - int ret; -@@ -1439,7 +1474,8 @@ int ath11k_core_fetch_regdb(struct ath11 - BOARD_NAME_SIZE); - if (ret) { - ath11k_dbg(ab, ATH11K_DBG_BOOT, -- "failed to create default board name for regdb: %d", ret); -+ "failed to create default board name for regdb: %d", -+ ret); - goto exit; - } - -@@ -1450,7 +1486,8 @@ int ath11k_core_fetch_regdb(struct ath11 - if (!ret) - goto exit; - -- ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_REGDB_FILE_NAME); -+ ret = ath11k_core_fetch_board_data_api_1(ab, bd, -+ ATH11K_REGDB_FILE_NAME); - if (ret) - ath11k_dbg(ab, ATH11K_DBG_BOOT, "failed to fetch %s from %s\n", - ATH11K_REGDB_FILE_NAME, ab->hw_params.fw.dir); -@@ -1542,14 +1579,14 @@ static int ath11k_core_pdev_create(struc - - ret = ath11k_mac_register(ab); - if (ret) { -- ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret); -+ ath11k_err(ab, "failed register the radio with mac80211: %d\n", -+ ret); - goto err_nss_tear; - } - - ret = ath11k_thermal_register(ab); - if (ret) { -- ath11k_err(ab, "could not register thermal device: %d\n", -- ret); -+ ath11k_err(ab, "could not register thermal device: %d\n", ret); - goto err_mac_unregister; - } - -@@ -1637,14 +1674,16 @@ static int ath11k_core_start(struct ath1 - - ret = ath11k_wmi_wait_for_service_ready(ab); - if (ret) { -- ath11k_err(ab, "failed to receive wmi service ready event: %d\n", -+ ath11k_err(ab, -+ "failed to receive wmi service ready event: %d\n", - ret); - goto err_hif_stop; - } - - ret = ath11k_mac_allocate(ab); - if (ret) { -- ath11k_err(ab, "failed to create new hw device with mac80211 :%d\n", -+ ath11k_err(ab, -+ "failed to create new hw device with mac80211 :%d\n", - ret); - goto err_hif_stop; - } -@@ -1653,7 +1692,9 @@ static int ath11k_core_start(struct ath1 - - ret = ath11k_dp_pdev_reo_setup(ab); - if (ret) { -- ath11k_err(ab, "failed to initialize reo destination rings: %d\n", ret); -+ ath11k_err(ab, -+ "failed to initialize reo destination rings: %d\n", -+ ret); - goto err_mac_destroy; - } - -@@ -1665,13 +1706,15 @@ static int ath11k_core_start(struct ath1 - - ret = ath11k_wmi_wait_for_unified_ready(ab); - if (ret) { -- ath11k_err(ab, "failed to receive wmi unified ready event: %d\n", -+ ath11k_err(ab, -+ "failed to receive wmi unified ready event: %d\n", - ret); - goto err_reo_cleanup; - } - - /* put hardware to DBS mode */ -- if (ab->hw_params.single_pdev_only && ab->hw_params.num_rxmda_per_pdev > 1) { -+ if (ab->hw_params.single_pdev_only && -+ ab->hw_params.num_rxmda_per_pdev > 1) { - ret = ath11k_wmi_set_hw_mode(ab, WMI_HOST_HW_MODE_DBS); - if (ret) { - ath11k_err(ab, "failed to send dbs mode: %d\n", ret); -@@ -1681,7 +1724,8 @@ static int ath11k_core_start(struct ath1 - - ret = ath11k_dp_tx_htt_h2t_ver_req_msg(ab); - if (ret) { -- ath11k_err(ab, "failed to send htt version request message: %d\n", -+ ath11k_err(ab, -+ "failed to send htt version request message: %d\n", - ret); - goto err_reo_cleanup; - } -@@ -1749,7 +1793,8 @@ int ath11k_core_qmi_firmware_ready(struc - clear_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags); - break; - default: -- ath11k_info(ab, "invalid crypto_mode: %d\n", ath11k_crypto_mode); -+ ath11k_info(ab, "invalid crypto_mode: %d\n", -+ ath11k_crypto_mode); - return -EINVAL; - } - -@@ -1850,7 +1895,8 @@ void ath11k_core_halt(struct ath11k *ar) - - static void ath11k_update_11d(struct work_struct *work) - { -- struct ath11k_base *ab = container_of(work, struct ath11k_base, update_11d_work); -+ struct ath11k_base *ab = -+ container_of(work, struct ath11k_base, update_11d_work); - struct ath11k *ar; - struct ath11k_pdev *pdev; - struct wmi_set_current_country_params set_current_param = {}; -@@ -1861,19 +1907,20 @@ static void ath11k_update_11d(struct wor - spin_unlock_bh(&ab->base_lock); - - ath11k_dbg(ab, ATH11K_DBG_WMI, "update 11d new cc %c%c\n", -- set_current_param.alpha2[0], -- set_current_param.alpha2[1]); -+ set_current_param.alpha2[0], set_current_param.alpha2[1]); - - for (i = 0; i < ab->num_radios; i++) { - pdev = &ab->pdevs[i]; - ar = pdev->ar; - - memcpy(&ar->alpha2, &set_current_param.alpha2, 2); -- ret = ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param); -+ ret = ath11k_wmi_send_set_current_country_cmd( -+ ar, &set_current_param); - if (ret) -- ath11k_warn(ar->ab, -- "pdev id %d failed set current country code: %d\n", -- i, ret); -+ ath11k_warn( -+ ar->ab, -+ "pdev id %d failed set current country code: %d\n", -+ i, ret); - } - } - -@@ -1910,8 +1957,8 @@ void ath11k_core_pre_reconfigure_recover - complete(&ar->thermal.wmi_sync); - - wake_up(&ar->dp.tx_empty_waitq); -- idr_for_each(&ar->txmgmt_idr, -- ath11k_mac_tx_mgmt_pending_free, ar); -+ idr_for_each(&ar->txmgmt_idr, ath11k_mac_tx_mgmt_pending_free, -+ ar); - idr_destroy(&ar->txmgmt_idr); - wake_up(&ar->txmgmt_empty_waitq); - -@@ -1947,9 +1994,10 @@ static void ath11k_core_post_reconfigure - ieee80211_restart_hw(ar->hw); - break; - case ATH11K_STATE_OFF: -- ath11k_warn(ab, -- "cannot restart radio %d that hasn't been started\n", -- i); -+ ath11k_warn( -+ ab, -+ "cannot restart radio %d that hasn't been started\n", -+ i); - break; - case ATH11K_STATE_RESTARTING: - break; -@@ -1957,8 +2005,10 @@ static void ath11k_core_post_reconfigure - ar->state = ATH11K_STATE_WEDGED; - fallthrough; - case ATH11K_STATE_WEDGED: -- ath11k_warn(ab, -- "device is wedged, will not restart radio %d\n", i); -+ ath11k_warn( -+ ab, -+ "device is wedged, will not restart radio %d\n", -+ i); - break; - case ATH11K_STATE_FTM: - ath11k_dbg(ab, ATH11K_DBG_TESTMODE, -@@ -1973,12 +2023,14 @@ static void ath11k_core_post_reconfigure - - static void ath11k_core_restart(struct work_struct *work) - { -- struct ath11k_base *ab = container_of(work, struct ath11k_base, restart_work); -+ struct ath11k_base *ab = -+ container_of(work, struct ath11k_base, restart_work); - int ret; - - ret = ath11k_core_reconfigure_on_crash(ab); - if (ret) { -- ath11k_err(ab, "failed to reconfigure driver on crash recovery\n"); -+ ath11k_err(ab, -+ "failed to reconfigure driver on crash recovery\n"); - return; - } - -@@ -1991,12 +2043,14 @@ static void ath11k_core_restart(struct w - - static void ath11k_core_reset(struct work_struct *work) - { -- struct ath11k_base *ab = container_of(work, struct ath11k_base, reset_work); -+ struct ath11k_base *ab = -+ container_of(work, struct ath11k_base, reset_work); - int reset_count, fail_cont_count; - long time_left; - - if (!(test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))) { -- ath11k_warn(ab, "ignore reset dev flags 0x%lx\n", ab->dev_flags); -+ ath11k_warn(ab, "ignore reset dev flags 0x%lx\n", -+ ab->dev_flags); - return; - } - -@@ -2022,8 +2076,8 @@ static void ath11k_core_reset(struct wor - ath11k_warn(ab, "already resetting count %d\n", reset_count); - - reinit_completion(&ab->reset_complete); -- time_left = wait_for_completion_timeout(&ab->reset_complete, -- ATH11K_RESET_TIMEOUT_HZ); -+ time_left = wait_for_completion_timeout( -+ &ab->reset_complete, ATH11K_RESET_TIMEOUT_HZ); - - if (time_left) { - ath11k_dbg(ab, ATH11K_DBG_BOOT, "to skip reset\n"); -@@ -2050,8 +2104,8 @@ static void ath11k_core_reset(struct wor - - ath11k_dbg(ab, ATH11K_DBG_BOOT, "waiting recovery start...\n"); - -- time_left = wait_for_completion_timeout(&ab->recovery_start, -- ATH11K_RECOVER_START_TIMEOUT_HZ); -+ time_left = wait_for_completion_timeout( -+ &ab->recovery_start, ATH11K_RECOVER_START_TIMEOUT_HZ); - - ath11k_hif_power_down(ab); - ath11k_hif_power_up(ab); -@@ -2073,22 +2127,21 @@ static int ath11k_init_hw_params(struct - } - - if (i == ARRAY_SIZE(ath11k_hw_params)) { -- ath11k_err(ab, "Unsupported hardware version: 0x%x\n", ab->hw_rev); -+ ath11k_err(ab, "Unsupported hardware version: 0x%x\n", -+ ab->hw_rev); - return -EINVAL; - } - - ab->hw_params = *hw_params; - - ret = of_property_read_u32(ab->dev->of_node, -- "qcom,ath11k-fw-memory-mode", -- &fw_mem_mode); -+ "qcom,ath11k-fw-memory-mode", &fw_mem_mode); - if (!ret) { - if (fw_mem_mode == 0) { - ab->hw_params.fw_mem_mode = 0; - ab->hw_params.num_vdevs = 16 + 1; - ab->hw_params.num_peers = 512; -- } -- else if (fw_mem_mode == 1) { -+ } else if (fw_mem_mode == 1) { - ab->hw_params.fw_mem_mode = 1; - ab->hw_params.num_vdevs = 8; - ab->hw_params.num_peers = 128; -@@ -2099,7 +2152,8 @@ static int ath11k_init_hw_params(struct - ab->hw_params.coldboot_cal_mm = false; - ab->hw_params.coldboot_cal_ftm = false; - } else -- ath11k_info(ab, "Unsupported FW memory mode: %u\n", fw_mem_mode); -+ ath11k_info(ab, "Unsupported FW memory mode: %u\n", -+ fw_mem_mode); - } - - ath11k_info(ab, "%s\n", ab->hw_params.name); -@@ -2215,5 +2269,6 @@ err_sc_free: - } - EXPORT_SYMBOL(ath11k_core_alloc); - --MODULE_DESCRIPTION("Core module for Qualcomm Atheros 802.11ax wireless LAN cards."); -+MODULE_DESCRIPTION( -+ "Core module for Qualcomm Atheros 802.11ax wireless LAN cards."); - MODULE_LICENSE("Dual BSD/GPL"); --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c @@ -1592,10 +1592,13 @@ static ssize_t ath11k_dump_mgmt_stats(st From a10d039a71a70d597c84dcc438dddc7357bd2332 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 25 Dec 2023 17:10:55 -0500 Subject: [PATCH 064/225] ath11k_nss: add 'debug_mode' flag quiet warnings Will properly handle: ``` [Mon Dec 25 16:51:34 2023] ath11k c000000.wifi: encap mismatch in nss tx skb encap type 1 vif encap type 2 ``` should take the path for native wifi encap --- ...-ath11k_nss-add-nss-driver-interface.patch | 8 +-- .../199-003-ath11k-add-nss-support.patch | 50 +++++++------------ ...11k-Disable-rx_header-tlv-for-2K-SKB.patch | 4 +- ...01-ath11k-account-tx-rx-packets-flow.patch | 2 +- 4 files changed, 27 insertions(+), 37 deletions(-) diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch b/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch index 6a6b7905637b4a..beee16098f14c3 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch @@ -675,9 +675,9 @@ 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(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); ++ " vif encap type %d\n", encap_type, arvif->nss.encap); + goto drop; + } + @@ -2443,7 +2443,7 @@ Signed-off-by: Sriram R +} --- /dev/null +++ b/drivers/net/wireless/ath/ath11k/nss.h -@@ -0,0 +1,305 @@ +@@ -0,0 +1,307 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. @@ -2623,6 +2623,8 @@ Signed-off-by: Sriram R + void* ctx; + /* if_num to be used for soc related nss messages */ + int if_num; ++ /* debug mode to disable the regular mesh configuration from mac80211 */ ++ bool debug_mode; + /* Completion to nss message response */ + struct completion complete; + /* Response to nss messages are stored here on msg callback diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch b/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch index af04672a2498ae..082f8fccbbe0a1 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch @@ -294,21 +294,7 @@ Signed-off-by: Sriram R i = fls(ab->hw_params.ring_mask->rx[grp_id]) - 1; work_done = ath11k_dp_process_rx(ab, i, napi, budget); -@@ -822,9 +841,10 @@ int ath11k_dp_service_srng(struct ath11k - if (ab->hw_params.ring_mask->rx_mon_status[grp_id] & - BIT(id)) { - work_done = -- ath11k_dp_rx_process_mon_rings(ab, -- id, -- napi, budget); -+ ath11k_dp_rx_process_mon_rings(ab, -+ id, -+ napi, -+ budget); - budget -= work_done; - tot_work_done += work_done; - -@@ -838,7 +858,7 @@ int ath11k_dp_service_srng(struct ath11k +@@ -838,7 +857,7 @@ int ath11k_dp_service_srng(struct ath11k if (ab->hw_params.ring_mask->reo_status[grp_id]) ath11k_dp_process_reo_status(ab); @@ -571,13 +557,15 @@ Signed-off-by: Sriram R exit: mutex_unlock(&ar->conf_mutex); return ret; -@@ -6216,10 +6279,14 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6216,10 +6279,16 @@ static void ath11k_mac_op_tx(struct ieee if (control->sta) arsta = ath11k_sta_to_arsta(control->sta); - ret = ath11k_dp_tx(ar, arvif, arsta, skb); -+ if (ar->ab->nss.enabled) -+ ret = ath11k_nss_tx(arvif,skb); ++ if (ar->ab->nss.enabled) { ++ arvif->ar->ab->nss.debug_mode = true; ++ ret = ath11k_nss_tx(arvif, skb); ++ } + else + ret = ath11k_dp_tx(ar, arvif, arsta, skb); if (unlikely(ret)) { @@ -587,7 +575,7 @@ Signed-off-by: Sriram R } } -@@ -6241,6 +6308,8 @@ static int ath11k_mac_config_mon_status_ +@@ -6241,6 +6310,8 @@ static int ath11k_mac_config_mon_status_ if (enable) { tlv_filter = ath11k_mac_mon_status_filter_default; @@ -596,7 +584,7 @@ Signed-off-by: Sriram R if (ath11k_debugfs_rx_filter(ar)) tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar); } -@@ -6539,7 +6608,7 @@ static int ath11k_mac_setup_vdev_create_ +@@ -6539,7 +6610,7 @@ static int ath11k_mac_setup_vdev_create_ return 0; } @@ -605,7 +593,7 @@ Signed-off-by: Sriram R struct ieee80211_vif *vif) { struct ath11k *ar = hw->priv; -@@ -6585,6 +6654,8 @@ static void ath11k_mac_op_update_vif_off +@@ -6585,6 +6656,8 @@ static void ath11k_mac_op_update_vif_off arvif->vdev_id, ret); vif->offload_flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED; } @@ -614,7 +602,7 @@ Signed-off-by: Sriram R } static bool ath11k_mac_vif_ap_active_any(struct ath11k_base *ab) -@@ -6715,6 +6786,8 @@ static int ath11k_mac_vdev_delete(struct +@@ -6715,6 +6788,8 @@ static int ath11k_mac_vdev_delete(struct reinit_completion(&ar->vdev_delete_done); @@ -623,7 +611,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 +6928,34 @@ static int ath11k_mac_op_add_interface(s +@@ -6855,7 +6930,34 @@ static int ath11k_mac_op_add_interface(s list_add(&arvif->list, &ar->arvifs); spin_unlock_bh(&ar->data_lock); @@ -659,7 +647,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 +7079,7 @@ err_peer_del: +@@ -6979,6 +7081,7 @@ err_peer_del: } err_vdev_del: @@ -667,7 +655,7 @@ Signed-off-by: Sriram R ath11k_mac_vdev_delete(ar, arvif); spin_lock_bh(&ar->data_lock); list_del(&arvif->list); -@@ -7489,6 +7590,10 @@ ath11k_mac_update_vif_chan(struct ath11k +@@ -7489,6 +7592,10 @@ ath11k_mac_update_vif_chan(struct ath11k arvif->vdev_id, ret); continue; } @@ -678,7 +666,7 @@ Signed-off-by: Sriram R } /* Restart the internal monitor vdev on new channel */ -@@ -8771,6 +8876,8 @@ static void ath11k_mac_op_sta_statistics +@@ -8771,6 +8878,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); @@ -687,7 +675,7 @@ Signed-off-by: Sriram R } #if IS_ENABLED(CONFIG_IPV6) -@@ -9190,6 +9297,7 @@ static const struct ieee80211_ops ath11k +@@ -9190,6 +9299,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, @@ -695,7 +683,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, -@@ -9575,7 +9683,8 @@ static int __ath11k_mac_register(struct +@@ -9575,7 +9685,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); @@ -705,7 +693,7 @@ Signed-off-by: Sriram R } ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; -@@ -9690,6 +9799,9 @@ static int __ath11k_mac_register(struct +@@ -9690,6 +9801,9 @@ static int __ath11k_mac_register(struct ab->hw_params.bios_sar_capa) ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa; @@ -1167,7 +1155,7 @@ Signed-off-by: Sriram R enum ath11k_nss_opmode { ATH11K_NSS_OPMODE_UNKNOWN, ATH11K_NSS_OPMODE_AP, -@@ -190,7 +197,8 @@ struct ath11k_soc_nss { +@@ -192,7 +199,8 @@ struct ath11k_soc_nss { #ifdef CPTCFG_ATH11K_NSS_SUPPORT int ath11k_nss_tx(struct ath11k_vif *arvif, struct sk_buff *skb); @@ -1177,7 +1165,7 @@ Signed-off-by: Sriram R int ath11k_nss_vdev_create(struct ath11k_vif *arvif); void ath11k_nss_vdev_delete(struct ath11k_vif *arvif); int ath11k_nss_vdev_up(struct ath11k_vif *arvif); -@@ -217,7 +225,8 @@ static inline int ath11k_nss_tx(struct a +@@ -219,7 +227,8 @@ static inline int ath11k_nss_tx(struct a return 0; } diff --git a/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch b/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch index d64a258015780e..25e461e1bc88df 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch @@ -820,7 +820,7 @@ Signed-off-by: Ramya Gnanasekar { struct ath11k *ar = hw->priv; struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); -@@ -6338,6 +6338,7 @@ static int ath11k_mac_config_mon_status_ +@@ -6340,6 +6340,7 @@ static int ath11k_mac_config_mon_status_ tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar); } @@ -828,7 +828,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; ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, -@@ -9768,8 +9769,6 @@ static int __ath11k_mac_register(struct +@@ -9770,8 +9771,6 @@ static int __ath11k_mac_register(struct wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); 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 index a3e8b7961b01fc..08e158a407ca8f 100644 --- 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 @@ -476,7 +476,7 @@ Signed-off-by: Maharaja Kennadyrajan bool is_prb_rsp; u16 frm_type = 0; int ret; -@@ -6312,6 +6313,15 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6314,6 +6315,15 @@ static void ath11k_mac_op_tx(struct ieee ieee80211_free_txskb(ar->hw, skb); return; } From ac8a5052804e0d5677a8afad87652b89afcbc000 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 25 Dec 2023 23:51:12 -0500 Subject: [PATCH 065/225] ath11k_nss: Rework depends, make `nss_redirect` optional 1.) Added a reworked `qca-nss-pbuf` init script from QSDK that will set sysctl NSS `n2hcfg` wifi options based on board type and available RAM. 2.) ath11k is fully capable of offloading wifi, it does not need mac80211 to create any NSS vifs. This lowers overhead and has actually shown considerable speed improvements for CPU programs on the router side (i.e. SMB). I believe ax3600's IoT (ath10k) would require it for offloading. I've added 2 new makemenu options, `MAC80211_NSS_SUPPORT` which enables NSS related features, and `MAC80211_NSS_REDIRECT` which provides the option to autoload the module on boot with `nss_redirect=1`. 3.) Reverted the option that deafulted `ATH11K_MEM_PROFILE_512M` to true. This was not required for platforms with 1GB or more memory (which is most of them). The default is 1GB. Select for platforms like Xiaomi AX3600. --- package/kernel/mac80211/Makefile | 32 ++++++++- package/kernel/mac80211/ath.mk | 5 +- .../mac80211/files/etc/init.d/qca-nss-pbuf | 67 +++++++++++++++++++ 3 files changed, 99 insertions(+), 5 deletions(-) create mode 100755 package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index f5147d7982aba6..2785c23ac47aa5 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 PKG_VERSION:=6.5 -PKG_RELEASE:=2 +PKG_RELEASE:=3 # PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.15.58/ PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/ PKG_HASH:=908c22dceba185eab83caa5a1e58ce6b3ebdc58f099c3fd3e11c7352ebfab2d7 @@ -34,6 +34,8 @@ PKG_CONFIG_DEPENDS:= \ CONFIG_PACKAGE_MAC80211_DEBUGFS \ CONFIG_PACKAGE_MAC80211_MESH \ CONFIG_PACKAGE_MAC80211_TRACING \ + CONFIG_PACKAGE_MAC80211_NSS_SUPPORT \ + CONFIG_PACKAGE_MAC80211_NSS_REDIRECT \ CONFIG_PACKAGE_IWLWIFI_DEBUG \ CONFIG_PACKAGE_IWLWIFI_DEBUGFS \ CONFIG_PACKAGE_RTLWIFI_DEBUG \ @@ -126,8 +128,8 @@ define KernelPackage/mac80211 KCONFIG:=\ CONFIG_AVERAGE=y FILES:= $(PKG_BUILD_DIR)/net/mac80211/mac80211.ko -ifdef CONFIG_ATH11K_NSS_SUPPORT - AUTOLOAD:=$(call AutoProbe,mac80211) +ifdef CONFIG_PACKAGE_MAC80211_NSS_REDIRECT + AUTOLOAD:=$(call AutoProbe, mac80211) MODPARAMS.mac80211:=nss_redirect=1 endif ABI_VERSION:=$(PKG_VERSION)-$(PKG_RELEASE) @@ -137,6 +139,21 @@ endef define KernelPackage/mac80211/config if PACKAGE_kmod-mac80211 + if PACKAGE_kmod-qca-nss-drv + config PACKAGE_MAC80211_NSS_SUPPORT + bool "Enable NSS support" + default y + help + This option enables support for NSS in QCA boards. + config PACKAGE_MAC80211_NSS_REDIRECT + bool "Enable autoloading with 'nss_redirect=1' (not needed on ath11k)" + depends on PACKAGE_MAC80211_NSS_SUPPORT + default n + help + This option enables autoloading mac80211 with 'nss_redirect=1'. + However, it is not required for wifi offloading. + endif + config PACKAGE_MAC80211_DEBUGFS bool "Export mac80211 internals in DebugFS" select KERNEL_DEBUG_FS @@ -282,6 +299,8 @@ ifdef CONFIG_ATH11K_NSS_SUPPORT IREMAP_CFLAGS+=-I$(STAGING_DIR)/usr/include/qca-nss-drv endif +config-$(CONFIG_PACKAGE_MAC80211_NSS_SUPPORT) += MAC80211_NSS_SUPPORT + MAKE_OPTS:= \ $(subst -C $(LINUX_DIR),-C "$(PKG_BUILD_DIR)",$(KERNEL_MAKEOPTS)) \ EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/include $(IREMAP_CFLAGS) $(C_DEFINES)" \ @@ -403,6 +422,13 @@ define KernelPackage/cfg80211/install $(INSTALL_DATA) ./files/mac80211.hotplug $(1)/etc/hotplug.d/ieee80211/10-wifi-detect endef +ifdef CONFIG_ATH11K_NSS_SUPPORT +define KernelPackage/ath11k/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/etc/init.d/qca-nss-pbuf $(1)/etc/init.d +endef +endif + $(eval $(foreach drv,$(PKG_DRIVERS),$(call KernelPackage,$(drv)))) $(eval $(call KernelPackage,cfg80211)) $(eval $(call KernelPackage,mac80211)) diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk index 170bb26b4d4c87..d2dd07794aafea 100644 --- a/package/kernel/mac80211/ath.mk +++ b/package/kernel/mac80211/ath.mk @@ -336,9 +336,10 @@ define KernelPackage/ath11k/config config ATH11K_MEM_PROFILE_512M bool "Use limits for the 512MB memory size" - default y if ATH11K_NSS_SUPPORT + default n help - This allows selecting the ath11k memory size profile to be used. + For IPQ devices with 512MB RAM (i.e. Xiaomi AX3600). + Unselected is 1GB. endif endef diff --git a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf new file mode 100755 index 00000000000000..a4d944153b5122 --- /dev/null +++ b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf @@ -0,0 +1,67 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (c) 2021 The Linux Foundation. All rights reserved. +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +START=71 + +apply_nss_config() { + 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 + + case "$(board_name)" in + # 1GB+ RAM Boards + buffalo,wxr-5950ax12|\ + dynalink,dl-wrx36|\ + edgecore,eap102|\ + netgear,rax120v2|\ + netgear,wax620|\ + netgear,wax630|\ + prpl,haze|\ + qnap,301w|\ + xiaomi,ax9000|\ + zyxel,nbg7815) + sysctl -w dev.nss.n2hcfg.extra_pbuf_core0=9000000 > /dev/null 2> /dev/null + sysctl -w dev.nss.n2hcfg.n2h_high_water_core0=67392 > /dev/null 2> /dev/null + sysctl -w dev.nss.n2hcfg.n2h_wifi_pool_buf=40960 > /dev/null 2> /dev/null + ;; + # < 256MB Boards + netgear,wax218) + sysctl -w dev.nss.n2hcfg.extra_pbuf_core0=3100000 > /dev/null 2> /dev/null + sysctl -w dev.nss.n2hcfg.n2h_high_water_core0=30528 > /dev/null 2> /dev/null + sysctl -w dev.nss.n2hcfg.n2h_wifi_pool_buf=4096 > /dev/null 2> /dev/null + ;; + # 512MB+ Boards + *) + #default settings + sysctl -w dev.nss.n2hcfg.extra_pbuf_core0=7800000 > /dev/null 2> /dev/null + sysctl -w dev.nss.n2hcfg.n2h_high_water_core0=60176 > /dev/null 2> /dev/null + sysctl -w dev.nss.n2hcfg.n2h_wifi_pool_buf=35840 > /dev/null 2> /dev/null + ;; + esac +} + +start() { + if [ -d "/sys/kernel/debug/ath11k" ]; then + enable_nss_offload=$(cat /sys/module/ath11k/parameters/nss_offload) + if [ "$enable_nss_offload" -eq 1 ]; then + /etc/init.d/qca-nss-ecm start + apply_nss_config + fi + + if [ "$enable_nss_offload" -eq 0 ]; then + /etc/init.d/qca-nss-ecm stop + fi + fi +} From a356f3760dddd032fa839257a69ada57c8676f8b Mon Sep 17 00:00:00 2001 From: Qosmio Date: Tue, 26 Dec 2023 00:32:10 -0500 Subject: [PATCH 066/225] ath11k_nss: remove requirement for '/sys/kernel/debug/ath11k' --- package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf | 2 -- 1 file changed, 2 deletions(-) diff --git a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf index a4d944153b5122..4593420d7c2128 100755 --- a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf +++ b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf @@ -53,7 +53,6 @@ apply_nss_config() { } start() { - if [ -d "/sys/kernel/debug/ath11k" ]; then enable_nss_offload=$(cat /sys/module/ath11k/parameters/nss_offload) if [ "$enable_nss_offload" -eq 1 ]; then /etc/init.d/qca-nss-ecm start @@ -63,5 +62,4 @@ start() { if [ "$enable_nss_offload" -eq 0 ]; then /etc/init.d/qca-nss-ecm stop fi - fi } From b9b340823ae79256035a613437d4bf858ff5edf6 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Tue, 26 Dec 2023 18:28:57 -0500 Subject: [PATCH 067/225] ath11k_nss: set default values lower to avoid eating up memory --- package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf index 4593420d7c2128..5abb9d7df0a9df 100755 --- a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf +++ b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf @@ -45,9 +45,9 @@ apply_nss_config() { # 512MB+ Boards *) #default settings - sysctl -w dev.nss.n2hcfg.extra_pbuf_core0=7800000 > /dev/null 2> /dev/null - sysctl -w dev.nss.n2hcfg.n2h_high_water_core0=60176 > /dev/null 2> /dev/null - sysctl -w dev.nss.n2hcfg.n2h_wifi_pool_buf=35840 > /dev/null 2> /dev/null + sysctl -w dev.nss.n2hcfg.extra_pbuf_core0=3100000 >/dev/null 2>/dev/null + sysctl -w dev.nss.n2hcfg.n2h_high_water_core0=30624 >/dev/null 2>/dev/null + sysctl -w dev.nss.n2hcfg.n2h_wifi_pool_buf=8192 >/dev/null 2>/dev/null ;; esac } From 9523d00152c33909183f89a7e61b3435fbb2fdab Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 7 Jan 2024 18:41:24 -0500 Subject: [PATCH 068/225] ath11k_nss: Add NSS VLAN support + improvements 1) tweaked qca-nss-pbuf script to better handle different board configs 2) added some QSDK NSS patches for dynamic vlan, WDS. 3) added QSDK fixes for beacon, and bt-coex For devices that keep getting disconnected (mostly on 2G). It is recommended to use the following settings for wifi. Change for your country. config wifi-device 'radio0' option type 'mac80211' option path 'platform/soc/c000000.wifi' option band '5g' option txpower '24' option country 'PA' option channel '100' option htmode 'HE160' option cell_density '0' config wifi-iface 'default_radio0' option device 'radio0' option network 'lan' option mode 'ap' option encryption 'psk2' option key 'SOME_PASSWORD' option ssid 'EXAMPLE_5G' option dtim_period '3' option max_inactivity '86400' option disassoc_low_ack '0' config wifi-device 'radio1' option type 'mac80211' option path 'platform/soc/c000000.wifi+1' option band '2g' option htmode 'HT20' option channel '1' option txpower '36' option country 'PA' option cell_density '0' config wifi-iface 'default_radio1' option device 'radio1' option network 'lan' option mode 'ap' option ssid 'EXAMPLE_2G' option encryption 'psk2' option key 'SOME_PASSWORD' option max_inactivity '86400' option dtim_period '3' option disassoc_low_ack '0' WPA3 should be disabled, and left as WPA2. Experimenting with max_inactivity, dtim_period, and disassoc_low_ack to hopefully resolve the deauth disconnects. --- package/kernel/mac80211/Makefile | 2 +- package/kernel/mac80211/ath.mk | 17 +- .../mac80211/files/etc/init.d/qca-nss-pbuf | 96 +- ...-drop-pending-packet-for-ath11k_mac_.patch | 87 -- ...91-ath11k-add-mgmt-and-data-ack-rssi.patch | 2 +- .../199-003-ath11k-add-nss-support.patch | 8 +- ...03-mac80211-ath11k-fw-dynamic-muedca.patch | 203 ---- ...11k-Disable-rx_header-tlv-for-2K-SKB.patch | 2 +- ...th11k-Add-support-for-beacon-tx-mode.patch | 45 + ...80211-Add-support-for-beacon-tx-mode.patch | 159 +++ ...N-iftype-support-on-NSS-offload-case.patch | 206 ++++ ...load-changes-to-NSS-driver-interface.patch | 701 +++++++++++++ ...-dynamic-VLAN-support-on-NSS-offload.patch | 102 ++ ...-support-on-NSS-offload-for-STA-mode.patch | 973 ++++++++++++++++++ ...02-ath11k-add-HE-stats-in-peer-stats.patch | 777 ++++++++++++++ .../902-ath11k-add-btcoex-config.patch | 612 +++++++++++ ...vdev-in-NSS-for-AP_VLAN-vif-handling.patch | 784 ++++++++++++++ ...pport-for-WDS-offload-in-NSS-offload.patch | 575 +++++++++++ ...dev-in-NSS-for-dynamic-VLAN-handling.patch | 213 ++++ ...-dynamic-VLAN-support-in-NSS-offload.patch | 557 ++++++++++ .../patches-6.1/9999-add-btcoex-dts.patch | 30 + 21 files changed, 5812 insertions(+), 339 deletions(-) delete mode 100644 package/kernel/mac80211/patches/ath11k/999-wifi-ath11k-HACK-drop-pending-packet-for-ath11k_mac_.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/203-mac80211-ath11k-fw-dynamic-muedca.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/235-001-ath11k-Add-support-for-beacon-tx-mode.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/235-002-mac80211-Add-support-for-beacon-tx-mode.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/902-000-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/902-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/902-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/902-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-HE-stats-in-peer-stats.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-btcoex-config.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/903-002-ath11k-add-support-for-ext-vdev-in-NSS-for-AP_VLAN-vif-handling.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/904-002-ath11k-extend-ext-vdev-in-NSS-for-dynamic-VLAN-handling.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/904-003-ath11k-add-dynamic-VLAN-support-in-NSS-offload.patch create mode 100644 target/linux/qualcommax/patches-6.1/9999-add-btcoex-dts.patch diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 2785c23ac47aa5..4886723758f54f 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -296,7 +296,7 @@ ifeq ($(BUILD_VARIANT),smallbuffers) endif ifdef CONFIG_ATH11K_NSS_SUPPORT - IREMAP_CFLAGS+=-I$(STAGING_DIR)/usr/include/qca-nss-drv + IREMAP_CFLAGS+=-I$(STAGING_DIR)/usr/include/qca-nss-drv -I$(STAGING_DIR)/usr/include/qca-nss-clients endif config-$(CONFIG_PACKAGE_MAC80211_NSS_SUPPORT) += MAC80211_NSS_SUPPORT diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk index d2dd07794aafea..a94f24f7df6dca 100644 --- a/package/kernel/mac80211/ath.mk +++ b/package/kernel/mac80211/ath.mk @@ -15,7 +15,8 @@ PKG_CONFIG_DEPENDS += \ CONFIG_ATH11K_THERMAL \ CONFIG_ATH_USER_REGD \ CONFIG_ATH11K_MEM_PROFILE_512M \ - CONFIG_ATH11K_NSS_SUPPORT + CONFIG_ATH11K_NSS_SUPPORT \ + CONFIG_ATH11K_SMART_ANT_ALG ifdef CONFIG_PACKAGE_MAC80211_DEBUGFS config-y += \ @@ -60,6 +61,7 @@ config-$(CONFIG_ATH10K_THERMAL) += ATH10K_THERMAL config-$(CONFIG_ATH11K_THERMAL) += ATH11K_THERMAL config-$(CONFIG_ATH11K_MEM_PROFILE_512M) += ATH11K_MEM_PROFILE_512M config-$(CONFIG_ATH11K_NSS_SUPPORT) += ATH11K_NSS_SUPPORT +config-$(CONFIG_ATH11K_SMART_ANT_ALG) += ATH11K_SMART_ANT_ALG config-$(call config_package,ath9k-htc) += ATH9K_HTC config-$(call config_package,ath10k) += ATH10K ATH10K_PCI @@ -332,15 +334,16 @@ define KernelPackage/ath11k/config bool "Enable NSS WiFi offload" default y if TARGET_qualcommax - if PACKAGE_kmod-ath11k - - config ATH11K_MEM_PROFILE_512M + config ATH11K_MEM_PROFILE_512M bool "Use limits for the 512MB memory size" default n help - For IPQ devices with 512MB RAM (i.e. Xiaomi AX3600). - Unselected is 1GB. - endif + This allows selecting the ath11k memory size profile to be used. + + config ATH11K_SMART_ANT_ALG + bool "Enable smart antenna" + depends on PACKAGE_ATH_DEBUG + default n endef define KernelPackage/ath11k-ahb diff --git a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf index 5abb9d7df0a9df..40f05c46fb28fb 100755 --- a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf +++ b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf @@ -14,52 +14,78 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # -START=71 +START=20 + +apply_sysctl() { + [ $(sysctl -n -e dev.nss.general.redirect) = "0" ] && /etc/init.d/qca-nss-ecm start + + 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 + + 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 > /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 > /dev/null 2> /dev/null + +} apply_nss_config() { + 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 - case "$(board_name)" in - # 1GB+ RAM Boards - buffalo,wxr-5950ax12|\ - dynalink,dl-wrx36|\ - edgecore,eap102|\ - netgear,rax120v2|\ - netgear,wax620|\ - netgear,wax630|\ - prpl,haze|\ - qnap,301w|\ - xiaomi,ax9000|\ - zyxel,nbg7815) - sysctl -w dev.nss.n2hcfg.extra_pbuf_core0=9000000 > /dev/null 2> /dev/null - sysctl -w dev.nss.n2hcfg.n2h_high_water_core0=67392 > /dev/null 2> /dev/null - sysctl -w dev.nss.n2hcfg.n2h_wifi_pool_buf=40960 > /dev/null 2> /dev/null + board=$(board_name) + + case "$board" in + # 1GB+ profile + buffalo,wxr-5950ax12 | \ + dynalink,dl-wrx36 | \ + edgecore,eap102 | \ + linksys,mx5300 | \ + linksys,mx4200v2 | \ + netgear,rax120v2 | \ + netgear,wax620 | \ + netgear,wax630 | \ + prpl,haze | \ + qnap,301w | \ + xiaomi,ax9000 | \ + zyxel,nbg7815) + extra_pbuf_core0=10000000 n2h_high_water_core0=72512 n2h_wifi_pool_buf=36864 apply_sysctl ;; - # < 256MB Boards - netgear,wax218) - sysctl -w dev.nss.n2hcfg.extra_pbuf_core0=3100000 > /dev/null 2> /dev/null - sysctl -w dev.nss.n2hcfg.n2h_high_water_core0=30528 > /dev/null 2> /dev/null - sysctl -w dev.nss.n2hcfg.n2h_wifi_pool_buf=4096 > /dev/null 2> /dev/null + # 512MB profile + edimax,cax1800 | \ + linksys,mx4200v1 | \ + xiaomi,ax3600) # 512MB profile + extra_pbuf_core0=3100000 n2h_high_water_core0=30624 n2h_wifi_pool_buf=8192 apply_sysctl ;; - # 512MB+ Boards - *) - #default settings - sysctl -w dev.nss.n2hcfg.extra_pbuf_core0=3100000 >/dev/null 2>/dev/null - sysctl -w dev.nss.n2hcfg.n2h_high_water_core0=30624 >/dev/null 2>/dev/null - sysctl -w dev.nss.n2hcfg.n2h_wifi_pool_buf=8192 >/dev/null 2>/dev/null + # 256MB profile + netgear,wax218) + extra_pbuf_core0=3100000 n2h_high_water_core0=30258 n2h_wifi_pool_buf=4096 apply_sysctl ;; esac } start() { - enable_nss_offload=$(cat /sys/module/ath11k/parameters/nss_offload) - if [ "$enable_nss_offload" -eq 1 ]; then - /etc/init.d/qca-nss-ecm start - apply_nss_config - fi + 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 + + enable_nss_offload=$(cat /sys/module/ath11k/parameters/nss_offload) + + if [ "$enable_nss_offload" = "0" ]; then + logger -t ath11k_nss "Module parameter 'nss_offload=0'. Skipping applying wifi nss configs" + exit 1 + fi + + # 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. + extra_pbuf_core0=$(sysctl -n -e dev.nss.n2hcfg.extra_pbuf_core0) - if [ "$enable_nss_offload" -eq 0 ]; then - /etc/init.d/qca-nss-ecm stop - fi + if [ "$extra_pbuf_core0" = "0" ]; then + apply_nss_config + else + logger -t ath11k_nss "Sysctl key 'extra_pbuf_core0' already set to '"$extra_pbuf_core0"'. Skipping applying wifi nss configs" + fi } diff --git a/package/kernel/mac80211/patches/ath11k/999-wifi-ath11k-HACK-drop-pending-packet-for-ath11k_mac_.patch b/package/kernel/mac80211/patches/ath11k/999-wifi-ath11k-HACK-drop-pending-packet-for-ath11k_mac_.patch deleted file mode 100644 index d92f86f24d15f5..00000000000000 --- a/package/kernel/mac80211/patches/ath11k/999-wifi-ath11k-HACK-drop-pending-packet-for-ath11k_mac_.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 97a3daa845cfe96d07fb270df72bf7c3e05dd866 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 10 Oct 2022 17:04:36 +0200 -Subject: [PATCH] wifi: ath11k: HACK drop pending packet for - ath11k_mac_flush_tx_complete - -Some packets may be lost and stay in the tx_pending counter. Drop them -when an interface is torn down. - -THIS IS NOT A FIX AS AFTER A LONG TIME WE WILL END UP WITH FILLED RING -AND NOTHING WILL WORK - -Signed-off-by: Christian Marangi ---- - drivers/net/wireless/ath/ath11k/mac.c | 53 +++++++++++++++++++++++++++ - 1 file changed, 53 insertions(+) - -diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c -index 110a38cce0a7..101b54a6749e 100644 ---- a/drivers/net/wireless/ath/ath11k/mac.c -+++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -7387,8 +7387,62 @@ static int ath11k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value) - - static int ath11k_mac_flush_tx_complete(struct ath11k *ar) - { -+ struct ath11k_base *ab = ar->ab; - long time_left; - int ret = 0; -+ int i; -+ -+ time_left = wait_event_timeout(ar->dp.tx_empty_waitq, -+ (atomic_read(&ar->dp.num_tx_pending) == 0), -+ ATH11K_FLUSH_TIMEOUT); -+ /* XXX: hack some packets are lost for some reason. Drop pending idr. -+ * THIS IS NOT A FIX AS AFTER A LONG TIME WE WILL END UP WITH FILLED RING -+ * AND NOTHING WILL WORK -+ */ -+ if (time_left == 0) { -+ int msdu_id, num_tx_pending_dropped; -+ struct ath11k_dp *dp = &ab->dp; -+ struct ath11k_skb_cb *skb_cb; -+ struct dp_tx_ring *tx_ring; -+ struct sk_buff *msdu; -+ -+ ath11k_warn(ar->ab, "failed to flush transmit queue, data pkts pending %d\n", -+ atomic_read(&ar->dp.num_tx_pending)); -+ -+ for (i = 0; i < ab->hw_params.max_tx_ring; i++) { -+ tx_ring = &dp->tx_ring[i]; -+ -+ spin_lock(&tx_ring->tx_idr_lock); -+ } -+ -+ for (i = 0; i < ab->hw_params.max_tx_ring; i++) { -+ num_tx_pending_dropped = 0; -+ tx_ring = &dp->tx_ring[i]; -+ -+ idr_for_each_entry(&tx_ring->txbuf_idr, msdu, msdu_id) { -+ idr_remove(&tx_ring->txbuf_idr, msdu_id); -+ -+ skb_cb = ATH11K_SKB_CB(msdu); -+ -+ dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, -+ DMA_TO_DEVICE); -+ dev_kfree_skb_any(msdu); -+ -+ atomic_dec(&ar->dp.num_tx_pending); -+ num_tx_pending_dropped++; -+ } -+ -+ if (num_tx_pending_dropped > 0) -+ ath11k_err(ar->ab, "pkts stuck in tx_ring %d, DROPPED %d pkts\n", -+ i, num_tx_pending_dropped); -+ } -+ -+ for (i = 0; i < ab->hw_params.max_tx_ring; i++) { -+ tx_ring = &dp->tx_ring[i]; -+ -+ spin_unlock(&tx_ring->tx_idr_lock); -+ } -+ } - - time_left = wait_event_timeout(ar->dp.tx_empty_waitq, - (atomic_read(&ar->dp.num_tx_pending) == 0), --- -2.39.2 - diff --git a/package/kernel/mac80211/patches/ath11k_nss/191-ath11k-add-mgmt-and-data-ack-rssi.patch b/package/kernel/mac80211/patches/ath11k_nss/191-ath11k-add-mgmt-and-data-ack-rssi.patch index 9059e5180f63f0..dea5600324f536 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/191-ath11k-add-mgmt-and-data-ack-rssi.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/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 -@@ -9625,6 +9625,8 @@ static int __ath11k_mac_register(struct +@@ -9571,6 +9571,8 @@ static int __ath11k_mac_register(struct wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch b/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch index 082f8fccbbe0a1..cfe11083939837 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch @@ -666,7 +666,7 @@ Signed-off-by: Sriram R } /* Restart the internal monitor vdev on new channel */ -@@ -8771,6 +8878,8 @@ static void ath11k_mac_op_sta_statistics +@@ -8717,6 +8824,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); @@ -675,7 +675,7 @@ Signed-off-by: Sriram R } #if IS_ENABLED(CONFIG_IPV6) -@@ -9190,6 +9299,7 @@ static const struct ieee80211_ops ath11k +@@ -9136,6 +9245,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, @@ -683,7 +683,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, -@@ -9575,7 +9685,8 @@ static int __ath11k_mac_register(struct +@@ -9521,7 +9631,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); @@ -693,7 +693,7 @@ Signed-off-by: Sriram R } ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; -@@ -9690,6 +9801,9 @@ static int __ath11k_mac_register(struct +@@ -9636,6 +9747,9 @@ static int __ath11k_mac_register(struct ab->hw_params.bios_sar_capa) ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa; diff --git a/package/kernel/mac80211/patches/ath11k_nss/203-mac80211-ath11k-fw-dynamic-muedca.patch b/package/kernel/mac80211/patches/ath11k_nss/203-mac80211-ath11k-fw-dynamic-muedca.patch deleted file mode 100644 index df2d3f73da286c..00000000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/203-mac80211-ath11k-fw-dynamic-muedca.patch +++ /dev/null @@ -1,203 +0,0 @@ -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 -@@ -9304,4 +9304,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 -@@ -7358,6 +7358,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 -@@ -7927,3 +7927,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 -@@ -20133,6 +20133,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/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch b/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch index 25e461e1bc88df..0b9d559a4857ae 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch @@ -828,7 +828,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; ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, -@@ -9770,8 +9771,6 @@ static int __ath11k_mac_register(struct +@@ -9716,8 +9717,6 @@ static int __ath11k_mac_register(struct wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); 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 new file mode 100644 index 00000000000000..a95308a74ed223 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/235-001-ath11k-Add-support-for-beacon-tx-mode.patch @@ -0,0 +1,45 @@ +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 +@@ -3483,7 +3483,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) +@@ -3491,8 +3494,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 new file mode 100644 index 00000000000000..6fb460f6b4f740 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/235-002-mac80211-Add-support-for-beacon-tx-mode.patch @@ -0,0 +1,159 @@ +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/902-000-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch b/package/kernel/mac80211/patches/ath11k_nss/902-000-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch new file mode 100644 index 00000000000000..f0fc8c14ec1efd --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/902-000-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch @@ -0,0 +1,206 @@ +From 05d9bff2eb8b057d34c7c4b24329dd92cf4faddb Mon Sep 17 00:00:00 2001 +From: Sathishkumar Muruganandam +Date: Wed, 18 Nov 2020 23:54:38 +0530 +Subject: [PATCH 1/3] mac80211: add AP_VLAN iftype support on NSS offload case + +- allow AP_VLAN iftype to get added, removed +- add new callback for 4addr rx_notify to get AP_VLAN created from hostapd +- modify sta_use_4addr drv callback to advertise AP_VLAN vif instead of AP vif +- modify drv_tx callback to use AP_VLAN vif on NSS offload case + +Signed-off-by: Sathishkumar Muruganandam +--- + include/net/mac80211.h | 11 +++++++++++ + net/mac80211/cfg.c | 5 ++++- + net/mac80211/driver-ops.c | 9 +++++---- + net/mac80211/iface.c | 10 ++++++---- + net/mac80211/rx.c | 6 ++++++ + net/mac80211/tx.c | 14 ++++++++++---- + net/mac80211/util.c | 6 ++---- + 7 files changed, 44 insertions(+), 17 deletions(-) + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -5100,6 +5100,17 @@ void ieee80211_sta_pspoll(struct ieee802 + */ + void ieee80211_sta_uapsd_trigger(struct ieee80211_sta *sta, u8 tid); + ++/** ++ * ieee80211_rx_nss_notify_4addr - notify userspace about 4addr frame rx ++ * @dev: The device the frame matched to ++ * @addr: the transmitter address of 4addr sta ++ * ++ * When operating in AP mode with NSS offload enabled, this function is used ++ * to invoke cfg80211 callback to notify userspace that an associated station ++ * sent a 4addr frame. ++ */ ++void ieee80211_rx_nss_notify_4addr(struct net_device *dev, u8* sta_addr); ++ + /* + * The TX headroom reserved by mac80211 for its own tx_status functions. + * This is enough for the radiotap header. +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -2176,7 +2176,13 @@ static int ieee80211_change_station(stru + + rcu_assign_pointer(vlansdata->u.vlan.sta, sta); + __ieee80211_check_fast_rx_iface(vlansdata); +- drv_sta_set_4addr(local, sta->sdata, &sta->sta, true); ++ ++ if (ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) ++ drv_sta_set_4addr(local, vlansdata, &sta->sta, ++ true); ++ else ++ drv_sta_set_4addr(local, sta->sdata, &sta->sta, ++ true); + } + + if (sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN && +--- a/net/mac80211/driver-ops.c ++++ b/net/mac80211/driver-ops.c +@@ -59,10 +59,9 @@ int drv_add_interface(struct ieee80211_l + + might_sleep(); + +- if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN || +- (sdata->vif.type == NL80211_IFTYPE_MONITOR && ++ if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_MONITOR && + !ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) && +- !(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE)))) ++ !(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))) + return -EINVAL; + + trace_drv_add_interface(local, sdata); +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -676,6 +676,9 @@ static void ieee80211_do_stop(struct iee + + switch (sdata->vif.type) { + case NL80211_IFTYPE_AP_VLAN: ++ if (ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD) && ++ going_down) ++ drv_remove_interface(local, sdata); + break; + case NL80211_IFTYPE_MONITOR: + if (local->monitors == 0) +@@ -960,6 +963,7 @@ static bool ieee80211_iftype_supports_hd + switch (iftype) { + /* P2P GO and client are mapped to AP/STATION types */ + case NL80211_IFTYPE_AP: ++ case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_STATION: + return true; + default: +@@ -1014,7 +1018,8 @@ static void ieee80211_set_vif_encap_ops( + struct ieee80211_sub_if_data *bss = sdata; + bool enabled; + +- if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { ++ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && ++ !ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) { + if (!sdata->bss) + return; + +@@ -1359,10 +1364,17 @@ int ieee80211_do_open(struct wireless_de + + switch (sdata->vif.type) { + case NL80211_IFTYPE_AP_VLAN: +- /* no need to tell driver, but set carrier and chanctx */ + if (sdata->bss->active) { + ieee80211_link_vlan_copy_chanctx(&sdata->deflink); + netif_carrier_on(dev); ++ ++ if (ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) { ++ ieee80211_set_sdata_offload_flags(sdata); ++ res = drv_add_interface(local, sdata); ++ if (res) ++ goto err_del_interface; ++ } ++ + ieee80211_set_vif_encap_ops(sdata); + } else { + netif_carrier_off(dev); +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1759,6 +1759,12 @@ void ieee80211_sta_uapsd_trigger(struct + } + EXPORT_SYMBOL(ieee80211_sta_uapsd_trigger); + ++void ieee80211_rx_nss_notify_4addr(struct net_device *dev, u8 *sta_addr) ++{ ++ cfg80211_rx_unexpected_4addr_frame(dev, sta_addr, GFP_ATOMIC); ++} ++EXPORT_SYMBOL(ieee80211_rx_nss_notify_4addr); ++ + static ieee80211_rx_result debug_noinline + ieee80211_rx_h_uapsd_and_pspoll(struct ieee80211_rx_data *rx) + { +--- 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; + info->hw_queue = sdata->vif.hw_queue[queue]; + +- if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) ++ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && ++ !ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) + sdata = container_of(sdata->bss, + struct ieee80211_sub_if_data, u.ap); + +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -2410,6 +2410,9 @@ static void ieee80211_assign_chanctx(str + if (!local->use_chanctx) + return; + ++ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) ++ return; ++ + mutex_lock(&local->chanctx_mtx); + conf = rcu_dereference_protected(link->conf->chanctx_conf, + lockdep_is_held(&local->chanctx_mtx)); +@@ -2615,7 +2618,8 @@ int ieee80211_reconfig(struct ieee80211_ + } + + list_for_each_entry(sdata, &local->interfaces, list) { +- if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && ++ if ((sdata->vif.type != NL80211_IFTYPE_AP_VLAN || ++ ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) && + sdata->vif.type != NL80211_IFTYPE_MONITOR && + ieee80211_sdata_running(sdata)) { + res = drv_add_interface(local, sdata); +@@ -2630,7 +2634,8 @@ int ieee80211_reconfig(struct ieee80211_ + if (res) { + list_for_each_entry_continue_reverse(sdata, &local->interfaces, + list) +- if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && ++ if ((sdata->vif.type != NL80211_IFTYPE_AP_VLAN || ++ ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) && + sdata->vif.type != NL80211_IFTYPE_MONITOR && + ieee80211_sdata_running(sdata)) + 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 + * 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 + */ +- if (ifmgd->use_4addr) ++ if (ifmgd->use_4addr && ++ (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD))) + ieee80211_send_4addr_nullfunc(local, sdata); + + /* +--- a/net/mac80211/driver-ops.h ++++ b/net/mac80211/driver-ops.h +@@ -1457,7 +1457,9 @@ static inline void drv_sta_set_4addr(str + struct ieee80211_sub_if_data *sdata, + struct ieee80211_sta *sta, bool enabled) + { +- sdata = get_bss_sdata(sdata); ++ if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) ++ sdata = get_bss_sdata(sdata); ++ + if (!check_sdata_in_driver(sdata)) + return; + 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/ath11k_nss/902-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch new file mode 100644 index 00000000000000..7e2a9f0ee4dd4b --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/902-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch @@ -0,0 +1,701 @@ +From d4c3b17e66243a2d6d8845192453ef7da568bac2 Mon Sep 17 00:00:00 2001 +From: Sathishkumar Muruganandam +Date: Thu, 10 Sep 2020 15:58:53 +0530 +Subject: [PATCH 1/2] ath11k: add WDS offload changes to NSS driver interface + +add WDS and MEC AST handling to NSS + +Signed-off-by: Sathishkumar Muruganandam +--- + drivers/net/wireless/ath/ath11k/nss.c | 465 ++++++++++++++++++++++++++++++++-- + drivers/net/wireless/ath/ath11k/nss.h | 36 ++- + 2 files changed, 473 insertions(+), 28 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/nss.c ++++ b/drivers/net/wireless/ath/ath11k/nss.c +@@ -9,10 +9,12 @@ + #include "nss.h" + #include "core.h" + #include "peer.h" ++#include "dp_tx.h" + #include "dp_rx.h" + #include "dp_tx.h" + #include "hif.h" + #include "wmi.h" ++#include "wmi.h" + #include "../../../../../net/mac80211/sta_info.h" + + /*-----------------------------ATH11K-NSS Helpers--------------------------*/ +@@ -348,6 +350,22 @@ void ath11k_nss_wifili_event_receive(str + ath11k_nss_wifili_link_desc_return(ab, + (void *)&msg->msg.linkdescinfomsg); + 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", ++ msg_type, response, error); ++ break; ++ case NSS_WIFILI_WDS_PEER_UPDATE_MSG: ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, "nss wifili wds peer update event received %d response %d error %d\n", ++ msg_type, response, error); ++ break; ++ case NSS_WIFILI_WDS_PEER_MAP_MSG: ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, "nss wifili wds peer map event received %d response %d error %d\n", ++ msg_type, response, error); ++ break; ++ case NSS_WIFILI_WDS_PEER_DEL_MSG: ++ 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; + 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 + /*TODO*/ + } + +-static void +-ath11k_nss_vdev_special_data_receive(struct net_device *dev, struct sk_buff *skb, +- __attribute__((unused)) struct napi_struct *napi) +-{ +- /* TODO */ +-} +- + /* 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 + return 0; + } + ++static void ath11k_nss_wds_type_rx(struct ath11k *ar, u8* src_mac, u8 is_sa_valid, ++ u8 addr4_valid, u16 peer_id) ++{ ++ struct ath11k_base *ab = ar->ab; ++ struct ath11k_ast_entry *ast_entry = NULL; ++ struct ath11k_peer *ta_peer = NULL; ++ ++ spin_lock_bh(&ab->base_lock); ++ ta_peer = ath11k_peer_find_by_id(ab, peer_id); ++ ++ if (!ta_peer) { ++ spin_unlock_bh(&ab->base_lock); ++ return; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS,"ath11k_nss_wds_type_rx ta_peer %pM\n", ++ ta_peer->addr); ++ ++ if (addr4_valid) { ++ ast_entry = ath11k_peer_ast_find_by_addr(ab, src_mac); ++ if (!is_sa_valid) { ++ ath11k_peer_add_ast(ar, ta_peer, src_mac, ++ ATH11K_AST_TYPE_WDS); ++ ath11k_nss_add_wds_peer(ar, ta_peer, ++ src_mac, ATH11K_AST_TYPE_WDS); ++ } else { ++ if (!ast_entry) { ++ ath11k_peer_add_ast(ar, ta_peer, src_mac, ++ ATH11K_AST_TYPE_WDS); ++ ath11k_nss_add_wds_peer(ar, ta_peer, src_mac, ++ ATH11K_AST_TYPE_WDS); ++ } else { ++ ath11k_peer_update_ast(ar, ta_peer, ast_entry); ++ ath11k_nss_update_wds_peer(ar, ta_peer, src_mac); ++ } ++ } ++ } ++ ++ spin_unlock_bh(&ab->base_lock); ++} ++ ++static void ath11k_nss_mec_handler(struct ath11k *ar, u8* mec_mac_addr) ++{ ++ struct ath11k_base *ab = ar->ab; ++ struct ath11k_peer *peer = ar->bss_peer; ++ u8 mac_addr[ETH_ALEN]; ++ u32 *mac_addr_l32; ++ u16 *mac_addr_h16; ++ ++ if (!peer) ++ return; ++ ++ /* mec_mac_addr has the swapped mac_addr after 4 bytes (sizeof(u32)) ++ * mec_mac_addr[0] ++ * | ++ * 03:0a:00:00:2d:15:22:f0:fd:8c ++ * ^ ++ * Swapped MAC address present after 4 bytes ++ * MAC address after swapping is 8c:fd:f0:22:15:2d */ ++ ++ mac_addr_l32 = (u32 *) (mec_mac_addr + sizeof(u32)); ++ mac_addr_h16 = (u16 *) (mec_mac_addr + sizeof(u32) + sizeof(u32)); ++ ++ *mac_addr_l32 = swab32(*mac_addr_l32); ++ *mac_addr_h16 = swab16(*mac_addr_h16); ++ ++ memcpy(mac_addr, mac_addr_h16, ETH_ALEN - 4); ++ memcpy(mac_addr + 2, mac_addr_l32, 4); ++ ++ if (!ether_addr_equal(ar->mac_addr, mac_addr)) { ++ spin_lock_bh(&ab->base_lock); ++ ath11k_peer_add_ast(ar, peer, mac_addr, ++ ATH11K_AST_TYPE_MEC); ++ spin_unlock_bh(&ab->base_lock); ++ } ++} ++ ++static void ath11k_nss_vdev_spl_receive_ext_wdsdata(struct ath11k_vif *arvif, ++ struct sk_buff *skb, ++ struct nss_wifi_vdev_wds_per_packet_metadata *wds_metadata) ++{ ++ struct ath11k *ar = arvif->ar; ++ struct ath11k_base *ab = ar->ab; ++ enum wifi_vdev_ext_wds_info_type wds_type; ++ u8 is_sa_valid = 0, addr4_valid = 0; ++ u16 peer_id; ++ u8 src_mac[ETH_ALEN]; ++ ++ is_sa_valid = wds_metadata->is_sa_valid; ++ addr4_valid = wds_metadata->addr4_valid; ++ wds_type = wds_metadata->wds_type; ++ peer_id = wds_metadata->peer_id; ++ ++ memcpy(src_mac, ((struct ethhdr *)skb->data)->h_source, ETH_ALEN); ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS,"receive_ext_wdsdata wds_type %d peer id %u sa_valid %d addr4_valid %d src_mac %pM\n", ++ wds_type, peer_id, is_sa_valid, addr4_valid, src_mac); ++ ++ switch (wds_type) { ++ case NSS_WIFI_VDEV_WDS_TYPE_RX: ++ ath11k_nss_wds_type_rx(ar, src_mac, is_sa_valid, ++ addr4_valid, peer_id); ++ break; ++ case NSS_WIFI_VDEV_WDS_TYPE_MEC: ++ ath11k_nss_mec_handler(ar, (u8 *)(skb->data)); ++ break; ++ default: ++ ath11k_warn(ab, "unsupported wds_type %d\n", wds_type); ++ break; ++ } ++} ++ ++static bool ath11k_nss_vdev_data_receive_mec_check(struct ath11k *ar, ++ struct sk_buff *skb) ++{ ++ struct ath11k_base *ab = ar->ab; ++ struct ath11k_ast_entry *ast_entry = NULL; ++ u8 src_mac[ETH_ALEN]; ++ ++ memcpy(src_mac, ((struct ethhdr *)skb->data)->h_source, ETH_ALEN); ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, ++ "ath11k_nss_vdev_data_receive_mec_check src mac %pM\n", ++ src_mac); ++ ++ spin_lock_bh(&ab->base_lock); ++ ast_entry = ath11k_peer_ast_find_by_addr(ab, src_mac); ++ ++ if (ast_entry && ast_entry->type == ATH11K_AST_TYPE_MEC) { ++ spin_unlock_bh(&ab->base_lock); ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, ++ "dropping mec traffic from %pM\n", ast_entry->addr); ++ return true; ++ } ++ ++ spin_unlock_bh(&ab->base_lock); ++ return false; ++} ++ ++static int ath11k_nss_undecap(struct ath11k_vif *arvif, struct sk_buff *skb, ++ int *data_offs, bool *eth_decap) ++{ ++ enum ath11k_hw_txrx_mode decap_type; ++ ++ decap_type = arvif->nss.decap; ++ ++ switch (decap_type) { ++ case ATH11K_HW_TXRX_RAW: ++ return ath11k_nss_undecap_raw(arvif, skb, data_offs); ++ case ATH11K_HW_TXRX_NATIVE_WIFI: ++ return ath11k_nss_undecap_nwifi(arvif, skb, data_offs); ++ case ATH11K_HW_TXRX_ETHERNET: ++ *eth_decap = true; ++ return 0; ++ default: ++ return -EINVAL; ++ } ++} ++ ++static void ++ath11k_nss_vdev_special_data_receive(struct net_device *dev, struct sk_buff *skb, ++ __attribute__((unused)) struct napi_struct *napi) ++{ ++ 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 eth_decap = false; ++ 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; ++ if (!arvif) { ++ dev_kfree_skb_any(skb); ++ return; ++ } ++ ++ ab = arvif->ar->ab; ++ ++ skb->dev = dev; ++ ++ dma_unmap_single(ab->dev, virt_to_phys(skb->head), ++ NSS_WIFI_VDEV_PER_PACKET_METADATA_OFFSET + ++ sizeof(struct nss_wifi_vdev_per_packet_metadata), ++ DMA_FROM_DEVICE); ++ ++ wifi_metadata = (struct nss_wifi_vdev_per_packet_metadata *)(skb->head + ++ NSS_WIFI_VDEV_PER_PACKET_METADATA_OFFSET); ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, ++ "dp special data from nss: wifi_metadata->pkt_type %d", ++ wifi_metadata->pkt_type); ++ ++ ret = ath11k_nss_undecap(arvif, skb, &data_offs, ð_decap); ++ if (ret) { ++ ath11k_warn(ab, "error in nss rx undecap, type %d err %d\n", ++ arvif->nss.decap, ret); ++ dev_kfree_skb_any(skb); ++ return; ++ } ++ ++ if (eth_decap && wifi_metadata->pkt_type == ++ 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, ++ wds_metadata); ++ } ++ ++ ath11k_nss_deliver_rx(arvif->vif, skb, eth_decap, data_offs, napi); ++} ++ + static void + ath11k_nss_vdev_data_receive(struct net_device *dev, struct sk_buff *skb, + __attribute__((unused)) struct napi_struct *napi) + { +- enum ath11k_hw_txrx_mode decap_type; + struct wireless_dev *wdev; + struct ieee80211_vif *vif; + struct ath11k_vif *arvif; +@@ -632,28 +871,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); + +- decap_type = arvif->nss.decap; +- +- switch (decap_type) { +- case ATH11K_HW_TXRX_RAW: +- ret = ath11k_nss_undecap_raw(arvif, skb, &data_offs); +- break; +- case ATH11K_HW_TXRX_NATIVE_WIFI: +- ret = ath11k_nss_undecap_nwifi(arvif, skb, &data_offs); +- break; +- case ATH11K_HW_TXRX_ETHERNET: +- /* no changes required for ethernet decap */ +- ret = 0; +- eth_decap = true; +- break; +- default: +- ret = -EINVAL; +- break; ++ if ((vif->type == NL80211_IFTYPE_STATION && wdev->use_4addr) && ++ ath11k_nss_vdev_data_receive_mec_check(arvif->ar, skb)) { ++ dev_kfree_skb_any(skb); ++ return; + } + ++ ret = ath11k_nss_undecap(arvif, skb, &data_offs, ð_decap); + if (ret) { +- ath11k_warn(ab, "error in nss rx undecap, type %d err %d\n", decap_type, +- ret); ++ ath11k_warn(ab, "error in nss rx undecap, type %d err %d\n", ++ arvif->nss.decap, ret); + dev_kfree_skb_any(skb); + return; + } +@@ -1362,7 +1589,7 @@ void ath11k_nss_update_sta_rxrate(struct + peer->nss.nss_stats->rxrate.bw = ath11k_mac_bw_to_mac80211_bw(ppdu_info->bw); + } + +-int ath11k_nss_peer_delete(struct ath11k_base *ab, const u8 *addr) ++int ath11k_nss_peer_delete(struct ath11k_base *ab, u32 vdev_id, const u8 *addr) + { + struct nss_wifili_peer_msg *peer_msg; + struct nss_wifili_msg *wlmsg = NULL; +@@ -1376,9 +1603,10 @@ int ath11k_nss_peer_delete(struct ath11k + + spin_lock_bh(&ab->base_lock); + +- peer = ath11k_peer_find_by_addr(ab, addr); ++ peer = ath11k_peer_find(ab, vdev_id, addr); + if (!peer) { +- ath11k_warn(ab, "peer (%pM) not found for nss peer delete\n", addr); ++ ath11k_warn(ab, "peer (%pM) not found on vdev_id %d for nss peer delete\n", ++ addr, vdev_id); + spin_unlock_bh(&ab->base_lock); + return -EINVAL; + } +@@ -1451,8 +1679,9 @@ free_peer: + return ret; + } + +-int ath11k_nss_peer_create(struct ath11k_base *ab, struct ath11k_peer *peer) ++int ath11k_nss_peer_create(struct ath11k *ar, struct ath11k_peer *peer) + { ++ struct ath11k_base *ab = ar->ab; + 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 + status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg); + if (status != NSS_TX_SUCCESS) { + ret = -EINVAL; +- ath11k_warn(ab, "nss send peer (%pM) create msg tx error\n", +- peer->addr); ++ ath11k_warn(ab, "nss send peer (%pM) create msg tx error: %d\n", ++ peer->addr, status); + goto peer_mem_free; + } + +- ret = 0; + ath11k_dbg(ab, ATH11K_DBG_NSS, + "nss peer_create msg success mac:%pM vdev:%d peer_id:%d hw_ast_idx:%d ast_hash:%d\n", + peer_msg->peer_mac_addr, peer_msg->vdev_id, peer_msg->peer_id, + peer_msg->hw_ast_idx, peer_msg->tx_ast_hash); + ++ ret = ath11k_peer_add_ast(ar, peer, peer->addr, ++ ATH11K_AST_TYPE_STATIC); ++ if (ret) { ++ ath11k_warn(ab, "failed to add STATIC ast: %d\n", ret); ++ goto peer_mem_free; ++ } ++ + 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: + return ret; + } + ++int ath11k_nss_add_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, ++ u8 *dest_mac, enum ath11k_ast_entry_type type) ++{ ++ struct ath11k_base *ab = ar->ab; ++ struct nss_wifili_wds_peer_msg *wds_peer_msg; ++ 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 == NULL) ++ return -ENOMEM; ++ ++ wds_peer_msg = &wlmsg->msg.wdspeermsg; ++ ++ wds_peer_msg->pdev_id = ar->pdev->pdev_id; ++ wds_peer_msg->ast_type = type; ++ wds_peer_msg->peer_id = peer->peer_id; ++ ++ if (type == ATH11K_AST_TYPE_MEC) ++ ether_addr_copy(wds_peer_msg->peer_mac, ar->mac_addr); ++ else ++ ether_addr_copy(wds_peer_msg->peer_mac, peer->addr); ++ ++ ether_addr_copy(wds_peer_msg->dest_mac, dest_mac); ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_WDS_PEER_ADD_MSG, ++ sizeof(struct nss_wifili_wds_peer_msg), ++ msg_cb, NULL); ++ ++ status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ret = -EINVAL; ++ ath11k_warn(ab, "nss send wds add peer msg tx error: %d\n", ++ status); ++ goto msg_free; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, ++ "nss add wds peer success peer mac:%pM dest mac:%pM peer_id:%d\n", ++ wds_peer_msg->peer_mac, wds_peer_msg->dest_mac, wds_peer_msg->peer_id); ++ ++msg_free: ++ kfree(wlmsg); ++ return ret; ++} ++ ++int ath11k_nss_update_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, ++ u8 *dest_mac) ++{ ++ struct ath11k_base *ab = ar->ab; ++ struct nss_wifili_wds_peer_msg *wds_peer_msg; ++ 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 == NULL) ++ return -ENOMEM; ++ ++ wds_peer_msg = &wlmsg->msg.wdspeermsg; ++ ++ wds_peer_msg->pdev_id = ar->pdev->pdev_id; ++ wds_peer_msg->ast_type = ATH11K_AST_TYPE_WDS; ++ wds_peer_msg->peer_id = peer->peer_id; ++ ether_addr_copy(wds_peer_msg->peer_mac, peer->addr); ++ ether_addr_copy(wds_peer_msg->dest_mac, dest_mac); ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_WDS_PEER_UPDATE_MSG, ++ sizeof(struct nss_wifili_wds_peer_msg), ++ msg_cb, NULL); ++ ++ status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ret = -EINVAL; ++ ath11k_warn(ab, "nss send wds update peer msg tx error: %d\n", ++ status); ++ goto msg_free; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, ++ "nss update wds peer success peer mac:%pM dest mac:%pM peer_id:%d\n", ++ wds_peer_msg->peer_mac, wds_peer_msg->dest_mac, wds_peer_msg->peer_id); ++ ++msg_free: ++ kfree(wlmsg); ++ return ret; ++} ++ ++int ath11k_nss_map_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, ++ u8 *dest_mac, enum ath11k_ast_entry_type type) ++{ ++ struct ath11k_base *ab = ar->ab; ++ struct nss_wifili_wds_peer_map_msg *wds_peer_map_msg; ++ 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 == NULL) ++ return -ENOMEM; ++ ++ wds_peer_map_msg = &wlmsg->msg.wdspeermapmsg; ++ ++ wds_peer_map_msg->vdev_id = peer->vdev_id; ++ wds_peer_map_msg->ast_idx = peer->hw_peer_id; ++ ++ if (type == ATH11K_AST_TYPE_MEC) ++ wds_peer_map_msg->peer_id = NSS_WIFILI_MEC_PEER_ID; ++ else ++ wds_peer_map_msg->peer_id = peer->peer_id; ++ ++ ether_addr_copy(wds_peer_map_msg->dest_mac, dest_mac); ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_WDS_PEER_MAP_MSG, ++ sizeof(struct nss_wifili_wds_peer_map_msg), ++ msg_cb, NULL); ++ ++ status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ret = -EINVAL; ++ ath11k_warn(ab, "nss send wds peer map msg tx error: %d\n", ++ status); ++ goto msg_free; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, ++ "nss wds peer map success mac:%pM hw_ast_idx:%d peer_id:%d\n", ++ wds_peer_map_msg->dest_mac, wds_peer_map_msg->ast_idx, wds_peer_map_msg->peer_id); ++ ++msg_free: ++ kfree(wlmsg); ++ return ret; ++} ++ ++int ath11k_nss_del_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, ++ u8 *dest_mac) ++{ ++ struct ath11k_base *ab = ar->ab; ++ struct nss_wifili_wds_peer_msg *wds_peer_msg; ++ 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 == NULL) ++ return -ENOMEM; ++ ++ wds_peer_msg = &wlmsg->msg.wdspeermsg; ++ ++ wds_peer_msg->pdev_id = ar->pdev->pdev_id; ++ wds_peer_msg->ast_type = ATH11K_AST_TYPE_NONE; ++ wds_peer_msg->peer_id = peer->peer_id; ++ ether_addr_copy(wds_peer_msg->peer_mac, peer->addr); ++ ether_addr_copy(wds_peer_msg->dest_mac, dest_mac); ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_WDS_PEER_DEL_MSG, ++ sizeof(struct nss_wifili_wds_peer_msg), ++ msg_cb, NULL); ++ ++ status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ret = -EINVAL; ++ ath11k_warn(ab, "nss send wds del peer msg tx error: %d\n", ++ status); ++ goto msg_free; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, ++ "nss del wds peer success peer mac:%pM dest mac:%pM peer_id:%d\n", ++ wds_peer_msg->peer_mac, wds_peer_msg->dest_mac, wds_peer_msg->peer_id); ++ ++msg_free: ++ kfree(wlmsg); ++ return ret; ++} ++ + /*-------------------------------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 + + status = nss_wifili_tx_msg(nss_contex, wlmsg); + if (status != NSS_TX_SUCCESS) { +- ath11k_warn(ab, "failure to send nss init msg\n"); ++ ath11k_warn(ab, "failure to send nss init msg: %d \n", status); + goto unregister; + } + +@@ -1985,7 +2413,8 @@ static int ath11k_nss_stats_cfg(struct a + + status = nss_wifili_tx_msg(ar->nss.ctx, wlmsg); + if (status != NSS_TX_SUCCESS) { +- ath11k_warn(ab, "nss stats cfg %d msg tx failure\n", nss_msg); ++ ath11k_warn(ab, "nss stats cfg %d msg tx failure: %d\n", ++ nss_msg, status); + ret = -EINVAL; + goto free; + } +--- a/drivers/net/wireless/ath/ath11k/nss.h ++++ b/drivers/net/wireless/ath/ath11k/nss.h +@@ -17,12 +17,14 @@ struct ath11k_base; + struct ath11k_vif; + struct ath11k_peer; + struct ath11k_sta; ++enum ath11k_ast_entry_type; + struct hal_rx_mon_ppdu_info; + 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 0x80000000 ++#define ATH11K_DBG_NSS 0x40000000 ++#define ATH11K_DBG_NSS_WDS 0x80000000 + + /* WIFILI Supported Target Types */ + #define ATH11K_WIFILI_TARGET_TYPE_UNKNOWN 0xFF +@@ -208,11 +210,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); +-int ath11k_nss_peer_delete(struct ath11k_base *ab, const u8 *addr); ++int ath11k_nss_peer_delete(struct ath11k_base *ab, u32 vdev_id, const u8 *addr); + int ath11k_nss_set_peer_authorize(struct ath11k *ar, u16 peer_id); +-int ath11k_nss_peer_create(struct ath11k_base *ab, struct ath11k_peer *peer); ++int ath11k_nss_peer_create(struct ath11k *ar, struct ath11k_peer *peer); + void ath11k_nss_peer_stats_enable(struct ath11k *ar); + void ath11k_nss_peer_stats_disable(struct ath11k *ar); ++int ath11k_nss_add_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, ++ u8 *dest_mac, enum ath11k_ast_entry_type type); ++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, ++ 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); + 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 + return 0; + } + +-static inline int ath11k_nss_peer_delete(struct ath11k_base *ab, const u8 *addr) ++static inline int ath11k_nss_peer_delete(struct ath11k_base *ab, u32 vdev_id, ++ const u8 *addr) + { + return 0; + } + +-static inline int ath11k_nss_peer_create(struct ath11k_base *ab, struct ath11k_peer *peer) ++static inline int ath11k_nss_add_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, ++ u8 *dest_mac, int type) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_update_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, ++ u8 *dest_mac) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_map_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, ++ u8 *dest_mac, int type) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_del_wds_peer(struct ath11k_vif *arvif, struct ath11k_peer *peer, ++ u8 *dest_mac) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_peer_create(struct ath11k *ar, struct ath11k_peer *peer) + { + return 0; + } 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/ath11k_nss/902-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch new file mode 100644 index 00000000000000..143191f6a9bca9 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/902-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch @@ -0,0 +1,102 @@ +From 36ee9d37b53c933f4dd8f934f8e0273b5e901549 Mon Sep 17 00:00:00 2001 +From: Sathishkumar Muruganandam +Date: Fri, 8 Jan 2021 00:02:54 +0530 +Subject: [PATCH 1/3] mac80211: add dynamic VLAN support on NSS offload + +NSS requires dynamic AP_VLAN vif ifnum and its corresponding VLAN ID +and group key index to configure dynamic VLAN ext VDEV in NSS. + +Hence mac80211 set_key and sta_state callbacks are modified to advertise +AP_VLAN vif when NSS offload is enabled and VLAN ID provided by hostapd +in key params is stored to ieee80211_key_conf for the driver. + +Co-Developed-by: Seevalamuthu Mariappan +Signed-off-by: Seevalamuthu Mariappan +Signed-off-by: Sathishkumar Muruganandam +--- + include/net/mac80211.h | 3 +++ + net/mac80211/cfg.c | 1 + + net/mac80211/driver-ops.c | 4 +++- + net/mac80211/driver-ops.h | 4 +++- + net/mac80211/key.c | 5 ++++- + net/mac80211/tx.c | 4 ++++ + 6 files changed, 18 insertions(+), 3 deletions(-) + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -2089,6 +2089,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. ++ * @vlan_id: VLAN ID corresponding to the group key. ++ * For VLAN interfaces 1-4096, 0 for non-vlan interfaces + * @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) +@@ -2108,6 +2110,7 @@ struct ieee80211_key_conf { + u8 hw_key_idx; + s8 keyidx; + u16 flags; ++ u16 vlan_id; + s8 link_id; + u8 keylen; + u8 key[]; +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -538,6 +538,7 @@ static int ieee80211_add_key(struct wiph + break; + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_AP_VLAN: ++ key->conf.vlan_id = params->vlan_id; + /* Keys without a station are used for TX only */ + if (sta && test_sta_flag(sta, WLAN_STA_MFP)) + key->conf.flags |= IEEE80211_KEY_FLAG_RX_MGMT; +--- a/net/mac80211/driver-ops.c ++++ b/net/mac80211/driver-ops.c +@@ -116,7 +116,11 @@ int drv_sta_state(struct ieee80211_local + + might_sleep(); + +- sdata = get_bss_sdata(sdata); ++ if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD) || ++ !(old_state == IEEE80211_STA_ASSOC && ++ new_state == IEEE80211_STA_AUTHORIZED)) ++ sdata = get_bss_sdata(sdata); ++ + if (!check_sdata_in_driver(sdata)) + return -EIO; + +--- a/net/mac80211/driver-ops.h ++++ b/net/mac80211/driver-ops.h +@@ -453,7 +453,9 @@ static inline int drv_sta_add(struct iee + + might_sleep(); + +- sdata = get_bss_sdata(sdata); ++ if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) ++ sdata = get_bss_sdata(sdata); ++ + if (!check_sdata_in_driver(sdata)) + return -EIO; + +--- a/net/mac80211/key.c ++++ b/net/mac80211/key.c +@@ -166,7 +166,8 @@ static int ieee80211_key_enable_hw_accel + if (sta && !sta->uploaded) + goto out_unsupported; + +- if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { ++ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && ++ !ieee80211_hw_check(&key->local->hw, SUPPORTS_NSS_OFFLOAD)) { + /* + * The driver doesn't know anything about VLAN interfaces. + * Hence, don't send GTKs for VLAN interfaces to the driver. +@@ -610,6 +611,8 @@ ieee80211_key_alloc(u32 cipher, int idx, + */ + key->conf.flags = 0; + key->flags = 0; ++ /* VLAN ID initialised to zero for non-vlan interfaces */ ++ key->conf.vlan_id = 0; + + key->conf.link_id = -1; + key->conf.cipher = cipher; 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/ath11k_nss/902-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch new file mode 100644 index 00000000000000..12d42ddaa9ba9c --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/902-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch @@ -0,0 +1,973 @@ +From e6ecf9e1cc115b5821a880c6dccc5d8c9cd76fbd Mon Sep 17 00:00:00 2001 +From: Sathishkumar Muruganandam +Date: Tue, 15 Sep 2020 21:12:37 +0530 +Subject: [PATCH] ath11k: add WDS offload support on NSS offload for STA mode + +When 4addr is set ON for STA interface along with NSS enabled case, WDS +offload is enabled for ethernet mode. + +STA mode uses MEC (Multicast Echo Check) AST (Address Search Table) entry +to update the bridge MAC address from NSS to drop the locally generated +multicast/broadcast frames as multicast echo frames. + +AST handling and callbacks to NSS WDS APIs are added. + +Signed-off-by: Sathishkumar Muruganandam +--- + drivers/net/wireless/ath/ath11k/core.h | 8 +- + drivers/net/wireless/ath/ath11k/dp.h | 6 +- + drivers/net/wireless/ath/ath11k/dp_rx.c | 18 +- + drivers/net/wireless/ath/ath11k/dp_tx.c | 2 +- + drivers/net/wireless/ath/ath11k/peer.c | 389 +++++++++++++++++++++++++++++++- + drivers/net/wireless/ath/ath11k/peer.h | 117 ++++++++++ + drivers/net/wireless/ath/ath11k/wmi.c | 99 +++++++- + drivers/net/wireless/ath/ath11k/wmi.h | 33 +++ + 8 files changed, 658 insertions(+), 14 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -655,6 +655,7 @@ struct ath11k { + struct ath11k_pdev_wmi *wmi; + #ifdef CPTCFG_ATH11K_NSS_SUPPORT + struct ath11k_nss nss; ++ struct ath11k_peer *bss_peer; + #endif + struct ath11k_pdev_dp dp; + u8 mac_addr[ETH_ALEN]; +@@ -1065,6 +1066,8 @@ struct ath11k_base { + u32 rx_hash; + bool stats_disable; + ++ 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 +@@ -1181,13 +1181,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 +-#define HTT_T2H_PEER_MAP_INFO1_NEXT_HOP_M HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_M +-#define HTT_T2H_PEER_MAP_INFO1_NEXT_HOP_S HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_S ++#define HTT_T2H_PEER_UNMAP_INFO1_NEXT_HOP_M HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_M ++#define HTT_T2H_PEER_UNMAP_INFO1_NEXT_HOP_S HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_S ++#define HTT_T2H_PEER_UNMAP_INFO3_WDS_FREE_COUNT GENMASK(15, 0) + + struct htt_t2h_peer_unmap_event { + u32 info; + u32 mac_addr_l32; + u32 info1; ++ u32 info2; ++ u32 info3; + } __packed; + + struct htt_resp_msg { +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -1890,6 +1890,8 @@ void ath11k_dp_htt_htc_t2h_msg_handler(s + u16 peer_mac_h16; + u16 ast_hash; + u16 hw_peer_id; ++ u32 free_wds_count; ++ bool is_wds = false; + + ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "dp_htt rx msg type :0x%0x\n", type); + +@@ -1925,15 +1927,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); +- ath11k_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash, +- hw_peer_id); ++ is_wds = FIELD_GET(HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_M, ++ resp->peer_map_ev.info2); ++ ath11k_peer_map_v2_event(ab, vdev_id, peer_id, mac_addr, ast_hash, ++ hw_peer_id, is_wds); + break; + case HTT_T2H_MSG_TYPE_PEER_UNMAP: +- case HTT_T2H_MSG_TYPE_PEER_UNMAP2: + peer_id = FIELD_GET(HTT_T2H_PEER_UNMAP_INFO_PEER_ID, + resp->peer_unmap_ev.info); + ath11k_peer_unmap_event(ab, peer_id); + break; ++ case HTT_T2H_MSG_TYPE_PEER_UNMAP2: ++ peer_id = FIELD_GET(HTT_T2H_PEER_UNMAP_INFO_PEER_ID, ++ resp->peer_unmap_ev.info); ++ peer_mac_h16 = FIELD_GET(HTT_T2H_PEER_UNMAP_INFO1_MAC_ADDR_H16, ++ resp->peer_unmap_ev.info1); ++ ath11k_dp_get_mac_addr(resp->peer_map_ev.mac_addr_l32, ++ peer_mac_h16, mac_addr); ++ is_wds = FIELD_GET(HTT_T2H_PEER_UNMAP_INFO1_NEXT_HOP_M, ++ resp->peer_unmap_ev.info1); ++ free_wds_count = FIELD_GET(HTT_T2H_PEER_UNMAP_INFO3_WDS_FREE_COUNT, ++ resp->peer_unmap_ev.info3); ++ ath11k_peer_unmap_v2_event(ab, peer_id, mac_addr, is_wds, free_wds_count); ++ break; + case HTT_T2H_MSG_TYPE_PPDU_STATS_IND: + ath11k_htt_pull_ppdu_stats(ab, skb); + 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 + break; + case HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY: + /* This event is to be handled only when the driver decides to +- * use WDS offload functionality. ++ * use WDS offload functionality on NSS disabled case. + */ + break; + 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_ + 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, ++ u8* addr) ++{ ++ struct ath11k_ast_entry *ast_entry; ++ ++ lockdep_assert_held(&ab->base_lock); ++ ++ list_for_each_entry(ast_entry, &peer->ast_entry_list, ase_list) ++ if (ether_addr_equal(ast_entry->addr, addr)) ++ return ast_entry; ++ ++ return NULL; ++} ++ ++struct ath11k_ast_entry *ath11k_peer_ast_find_by_addr(struct ath11k_base *ab, ++ u8* addr) ++{ ++ struct ath11k_ast_entry *ast_entry; ++ struct ath11k_peer *peer; ++ ++ lockdep_assert_held(&ab->base_lock); ++ ++ list_for_each_entry(peer, &ab->peers, list) ++ list_for_each_entry(ast_entry, &peer->ast_entry_list, ase_list) ++ if (ether_addr_equal(ast_entry->addr, addr)) ++ return ast_entry; ++ ++ return NULL; ++} ++ ++void ath11k_peer_ast_wds_wmi_wk(struct work_struct *wk) ++{ ++ struct ath11k_ast_entry *ast_entry = container_of(wk, ++ struct ath11k_ast_entry, ++ wds_wmi_wk); ++ struct ath11k *ar; ++ struct ath11k_peer *peer; ++ int ret; ++ ++ if (!ast_entry) ++ return; ++ ++ ar = ast_entry->ar; ++ peer = ast_entry->peer; ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "ath11k_peer_ast_wds_wmi_wk action %d ast_entry %pM next_node %pM vdev %d\n", ++ ast_entry->action, ast_entry->addr, ast_entry->next_node_mac, ++ ast_entry->vdev_id); ++ ++ if (ast_entry->action == ATH11K_WDS_WMI_ADD) { ++ ret = ath11k_wmi_send_add_update_wds_entry_cmd(ar, ++ ast_entry->next_node_mac, ++ ast_entry->addr, ++ ast_entry->vdev_id, ++ true); ++ if (ret) { ++ ath11k_warn(ar->ab, "add wds_entry_cmd failed %d for %pM next_node %pM\n", ++ ret, ast_entry->addr, ++ ast_entry->next_node_mac); ++ if (peer) ++ ath11k_nss_del_wds_peer(ar, peer, ++ ast_entry->addr); ++ } ++ } else if (ast_entry->action == ATH11K_WDS_WMI_UPDATE) { ++ if (!peer) ++ return; ++ ++ ret = ath11k_wmi_send_add_update_wds_entry_cmd(ar, peer->addr, ++ ast_entry->addr, ++ ast_entry->vdev_id, ++ false); ++ if (ret) ++ ath11k_warn(ar->ab, "update wds_entry_cmd failed %d for %pM on peer %pM\n", ++ ret, ast_entry->addr, peer->addr); ++ } ++} ++ ++int ath11k_peer_add_ast(struct ath11k *ar, struct ath11k_peer *peer, ++ u8* mac_addr, enum ath11k_ast_entry_type type) ++{ ++ struct ath11k_ast_entry *ast_entry = NULL; ++ struct ath11k_base *ab = ar->ab; ++ ++ if (ab->num_ast_entries == ab->max_ast_index) { ++ ath11k_warn(ab, "failed to add ast for %pM due to insufficient ast entry resource %d in target\n", ++ mac_addr, ab->max_ast_index); ++ return -ENOBUFS; ++ } ++ ++ if (type != ATH11K_AST_TYPE_STATIC) { ++ ast_entry = ath11k_peer_ast_find_by_addr(ab, mac_addr); ++ if (ast_entry) { ++ ath11k_dbg(ab, ATH11K_DBG_MAC, "ast_entry %pM already present on peer %pM\n", ++ mac_addr, ast_entry->peer->addr); ++ return 0; ++ } ++ } ++ ++ ast_entry = kzalloc(sizeof(*ast_entry), GFP_ATOMIC); ++ if (!ast_entry) { ++ ath11k_warn(ab, "failed to alloc ast_entry for %pM\n", ++ mac_addr); ++ return -ENOMEM; ++ } ++ ++ switch (type) { ++ case ATH11K_AST_TYPE_STATIC: ++ peer->self_ast_entry = ast_entry; ++ ast_entry->type = ATH11K_AST_TYPE_STATIC; ++ break; ++ case ATH11K_AST_TYPE_SELF: ++ peer->self_ast_entry = ast_entry; ++ ast_entry->type = ATH11K_AST_TYPE_SELF; ++ break; ++ case ATH11K_AST_TYPE_WDS: ++ ast_entry->type = ATH11K_AST_TYPE_WDS; ++ ast_entry->next_hop = 1; ++ break; ++ case ATH11K_AST_TYPE_MEC: ++ ast_entry->type = ATH11K_AST_TYPE_MEC; ++ ast_entry->next_hop = 1; ++ break; ++ default: ++ ath11k_warn(ab, "unsupported ast_type %d", type); ++ kfree(ast_entry); ++ return -EINVAL; ++ } ++ ++ INIT_LIST_HEAD(&ast_entry->ase_list); ++ INIT_WORK(&ast_entry->wds_wmi_wk, ath11k_peer_ast_wds_wmi_wk); ++ ast_entry->vdev_id = peer->vdev_id; ++ ast_entry->pdev_idx = peer->pdev_idx; ++ ast_entry->is_mapped = false; ++ ast_entry->is_active = true; ++ ast_entry->peer = peer; ++ ast_entry->ar = ar; ++ ether_addr_copy(ast_entry->addr, mac_addr); ++ ++ list_add_tail(&ast_entry->ase_list, &peer->ast_entry_list); ++ ++ ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_add_ast peer %pM ast_entry %pM, ast_type %d\n", ++ peer->addr, mac_addr, ast_entry->type); ++ ++ if (type == ATH11K_AST_TYPE_MEC) ++ ether_addr_copy(ast_entry->next_node_mac, ar->mac_addr); ++ else if (type == ATH11K_AST_TYPE_WDS) ++ ether_addr_copy(ast_entry->next_node_mac, peer->addr); ++ ++ if ((ast_entry->type == ATH11K_AST_TYPE_WDS) || ++ (ast_entry->type == ATH11K_AST_TYPE_MEC)) { ++ ath11k_nss_add_wds_peer(ar, peer, mac_addr, ast_entry->type); ++ ast_entry->action = ATH11K_WDS_WMI_ADD; ++ ieee80211_queue_work(ar->hw, &ast_entry->wds_wmi_wk); ++ } ++ ++ ab->num_ast_entries++; ++ return 0; ++} ++ ++int ath11k_peer_update_ast(struct ath11k *ar, struct ath11k_peer *peer, ++ struct ath11k_ast_entry *ast_entry) ++{ ++ struct ath11k_peer *old_peer = ast_entry->peer; ++ struct ath11k_base *ab = ar->ab; ++ ++ if (!ast_entry->is_mapped) { ++ ath11k_warn(ab, "ath11k_peer_update_ast: ast_entry %pM not mapped yet\n", ++ ast_entry->addr); ++ return -EINVAL; ++ } ++ ++ if (ether_addr_equal(old_peer->addr, peer->addr) && ++ (ast_entry->type == ATH11K_AST_TYPE_WDS) && ++ (ast_entry->vdev_id == peer->vdev_id) && ++ (ast_entry->is_active)) ++ return 0; ++ ++ ast_entry->vdev_id = peer->vdev_id; ++ ast_entry->pdev_idx = peer->pdev_idx; ++ ast_entry->type = ATH11K_AST_TYPE_WDS; ++ ast_entry->is_active = true; ++ ast_entry->peer = peer; ++ ++ list_move_tail(&ast_entry->ase_list, &peer->ast_entry_list); ++ ++ 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); ++ ++ flush_work(&ast_entry->wds_wmi_wk); ++ ast_entry->action = ATH11K_WDS_WMI_UPDATE; ++ ieee80211_queue_work(ar->hw, &ast_entry->wds_wmi_wk); ++ ++ return 0; ++} ++ ++void ath11k_peer_map_ast(struct ath11k *ar, struct ath11k_peer *peer, ++ u8* mac_addr, u16 hw_peer_id, u16 ast_hash) ++{ ++ struct ath11k_ast_entry *ast_entry = NULL; ++ struct ath11k_base *ab = ar->ab; ++ ++ if (!peer) ++ return; ++ ++ ast_entry = ath11k_peer_ast_find_by_peer(ab, peer, mac_addr); ++ ++ if (ast_entry) { ++ ast_entry->ast_idx = hw_peer_id; ++ ast_entry->is_active = true; ++ ast_entry->is_mapped = true; ++ ast_entry->ast_hash_value = ast_hash; ++ ++ if ((ast_entry->type == ATH11K_AST_TYPE_WDS) || ++ (ast_entry->type == ATH11K_AST_TYPE_MEC)) ++ ath11k_nss_map_wds_peer(ar, peer, mac_addr, ++ ast_entry->type); ++ ++ ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_map_ast peer %pM ast_entry %pM\n", ++ peer->addr, ast_entry->addr); ++ } ++ ++} ++ ++void ath11k_peer_del_ast(struct ath11k *ar, struct ath11k_ast_entry *ast_entry) ++{ ++ struct ath11k_peer *peer; ++ struct ath11k_base *ab = ar->ab; ++ ++ if (!ast_entry || !ast_entry->peer) ++ return; ++ ++ peer = ast_entry->peer; ++ ++ ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_del_ast peer %pM ast_entry %pM\n", ++ peer->addr, ast_entry->addr); ++ ++ if (ast_entry->is_mapped) ++ list_del(&ast_entry->ase_list); ++ ++ /* WDS, MEC type AST entries need to be deleted on NSS */ ++ if (ast_entry->next_hop) ++ ath11k_nss_del_wds_peer(ar, peer, ast_entry->addr); ++ ++ cancel_work_sync(&ast_entry->wds_wmi_wk); ++ kfree(ast_entry); ++ ++ ab->num_ast_entries--; ++} ++ ++void ath11k_peer_ast_cleanup(struct ath11k *ar, struct ath11k_peer *peer, ++ bool is_wds, u32 free_wds_count) ++{ ++ struct ath11k_ast_entry *ast_entry, *tmp; ++ u32 ast_deleted_count = 0; ++ ++ if (peer->self_ast_entry) { ++ ath11k_peer_del_ast(ar, peer->self_ast_entry); ++ peer->self_ast_entry = NULL; ++ } ++ ++ list_for_each_entry_safe(ast_entry, tmp, &peer->ast_entry_list, ++ ase_list) { ++ if ((ast_entry->type == ATH11K_AST_TYPE_WDS) || ++ (ast_entry->type == ATH11K_AST_TYPE_MEC)) ++ ast_deleted_count++; ++ ath11k_peer_del_ast(ar, ast_entry); ++ } ++ ++ if (!is_wds) { ++ if (ast_deleted_count != free_wds_count) ++ ath11k_warn(ar->ab, "ast_deleted_count (%d) mismatch on peer %pM free_wds_count (%d)!\n", ++ ast_deleted_count, peer->addr, free_wds_count); ++ else ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "ast_deleted_count (%d) on peer %pM free_wds_count (%d)\n", ++ ast_deleted_count, peer->addr, free_wds_count); ++ } ++} ++#endif ++ + void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id) + { + struct ath11k_peer *peer; +@@ -118,11 +399,67 @@ exit: + spin_unlock_bh(&ab->base_lock); + } + ++void ath11k_peer_unmap_v2_event(struct ath11k_base *ab, u16 peer_id, u8 *mac_addr, ++ bool is_wds, u32 free_wds_count) ++{ ++ struct ath11k_peer *peer; ++ struct ath11k *ar; ++ ++ spin_lock_bh(&ab->base_lock); ++ ++ peer = ath11k_peer_find_list_by_id(ab, peer_id); ++ if (!peer) { ++ ath11k_warn(ab, "peer-unmap-event: unknown peer id %d\n", ++ peer_id); ++ goto exit; ++ } ++ ++ rcu_read_lock(); ++ ar = ath11k_mac_get_ar_by_vdev_id(ab, peer->vdev_id); ++ if (!ar) { ++ ath11k_warn(ab, "peer-unmap-event: unknown peer vdev id %d\n", ++ peer->vdev_id); ++ goto free_peer; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "htt peer unmap vdev %d peer %pM id %d is_wds %d free_wds_count %d\n", ++ peer->vdev_id, peer->addr, peer_id, is_wds, free_wds_count); ++ ++ if (ab->nss.enabled) { ++ if (is_wds) { ++ struct ath11k_ast_entry *ast_entry = ++ ath11k_peer_ast_find_by_peer(ab, peer, mac_addr); ++ ++ if (ast_entry) ++ ath11k_peer_del_ast(ar, ast_entry); ++ rcu_read_unlock(); ++ goto exit; ++ } else ++ ath11k_peer_ast_cleanup(ar, peer, is_wds, free_wds_count); ++ } ++ ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ if (ar->bss_peer && ether_addr_equal(ar->bss_peer->addr, peer->addr)) ++ ar->bss_peer = NULL; ++#endif ++free_peer: ++ rcu_read_unlock(); ++ list_del(&peer->list); ++ kfree(peer); ++ wake_up(&ab->peer_mapping_wq); ++ ++exit: ++ spin_unlock_bh(&ab->base_lock); ++} ++ + void ath11k_peer_map_event(struct ath11k_base *ab, u8 vdev_id, u16 peer_id, + u8 *mac_addr, u16 ast_hash, u16 hw_peer_id) + { + struct ath11k_peer *peer; ++ struct ath11k *ar = NULL; + ++ rcu_read_lock(); ++ ar = ath11k_mac_get_ar_by_vdev_id(ab, vdev_id); + 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 + ether_addr_copy(peer->addr, mac_addr); + list_add(&peer->list, &ab->peers); + wake_up(&ab->peer_mapping_wq); +- if (ab->nss.enabled) +- ath11k_nss_peer_create(ab, peer); ++ if (ab->nss.enabled && ar) ++ ath11k_nss_peer_create(ar, peer); + } + + 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 + + exit: + spin_unlock_bh(&ab->base_lock); ++ rcu_read_unlock(); ++} ++ ++void ath11k_peer_map_v2_event(struct ath11k_base *ab, u8 vdev_id, u16 peer_id, ++ u8 *mac_addr, u16 ast_hash, u16 hw_peer_id, ++ bool is_wds) ++{ ++ struct ath11k_peer *peer; ++ struct ath11k *ar = NULL; ++ int ret; ++ ++ rcu_read_lock(); ++ ar = ath11k_mac_get_ar_by_vdev_id(ab, vdev_id); ++ spin_lock_bh(&ab->base_lock); ++ peer = ath11k_peer_find(ab, vdev_id, mac_addr); ++ if (!peer && !is_wds) { ++ peer = kzalloc(sizeof(*peer), GFP_ATOMIC); ++ if (!peer) { ++ ath11k_warn(ab, "failed to allocated peer for %pM vdev_id %d\n", ++ mac_addr, vdev_id); ++ spin_unlock_bh(&ab->base_lock); ++ goto exit; ++ } ++ ++ peer->vdev_id = vdev_id; ++ peer->peer_id = peer_id; ++ peer->ast_hash = ast_hash; ++ peer->hw_peer_id = hw_peer_id; ++ ether_addr_copy(peer->addr, mac_addr); ++ list_add(&peer->list, &ab->peers); ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ INIT_LIST_HEAD(&peer->ast_entry_list); ++#endif ++ if (ab->nss.enabled && ar) { ++ ret = ath11k_nss_peer_create(ar, peer); ++ if (ret) { ++ ath11k_warn(ab, "failed to do nss peer create: %d\n", ++ ret); ++ goto peer_free; ++ } ++ } ++ wake_up(&ab->peer_mapping_wq); ++ } ++ ++ if (is_wds) ++ peer = ath11k_peer_find_by_id(ab, peer_id); ++ ++ if (ab->nss.enabled && ar) ++ ath11k_peer_map_ast(ar, peer, mac_addr, hw_peer_id, ast_hash); ++ ++ ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "htt peer map vdev %d peer %pM id %d is_wds %d\n", ++ vdev_id, mac_addr, peer_id, is_wds); ++ ++ spin_unlock_bh(&ab->base_lock); ++ goto exit; ++ ++peer_free: ++ spin_unlock_bh(&ab->base_lock); ++ mutex_lock(&ar->conf_mutex); ++ ath11k_peer_delete(ar, vdev_id, mac_addr); ++ mutex_unlock(&ar->conf_mutex); ++exit: ++ rcu_read_unlock(); + } + + static int ath11k_wait_for_peer_common(struct ath11k_base *ab, int vdev_id, +@@ -242,20 +642,34 @@ err_clean: + + void ath11k_peer_cleanup(struct ath11k *ar, u32 vdev_id) + { +- struct ath11k_peer *peer, *tmp; ++ struct ath11k_peer *peer, *tmp_peer; + struct ath11k_base *ab = ar->ab; ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ struct ath11k_ast_entry *ast_entry, *tmp_ast; ++#endif + + lockdep_assert_held(&ar->conf_mutex); + + mutex_lock(&ab->tbl_mtx_lock); + spin_lock_bh(&ab->base_lock); +- list_for_each_entry_safe(peer, tmp, &ab->peers, list) { ++ list_for_each_entry_safe(peer, tmp_peer, &ab->peers, list) { + if (peer->vdev_id != vdev_id) + continue; + + ath11k_warn(ab, "removing stale peer %pM from vdev_id %d\n", + peer->addr, vdev_id); + ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ if (peer->self_ast_entry) { ++ ath11k_peer_del_ast(ar, peer->self_ast_entry); ++ peer->self_ast_entry = NULL; ++ } ++ ++ list_for_each_entry_safe(ast_entry, tmp_ast, ++ &peer->ast_entry_list, ase_list) ++ ath11k_peer_del_ast(ar, ast_entry); ++#endif ++ + ath11k_peer_rhash_delete(ab, peer); + list_del(&peer->list); + kfree(peer); +@@ -302,7 +716,7 @@ static int __ath11k_peer_delete(struct a + lockdep_assert_held(&ar->conf_mutex); + + reinit_completion(&ar->peer_delete_done); +- ath11k_nss_peer_delete(ar->ab, addr); ++ ath11k_nss_peer_delete(ar->ab, vdev_id, addr); + + mutex_lock(&ab->tbl_mtx_lock); + spin_lock_bh(&ab->base_lock); +@@ -377,6 +791,7 @@ int ath11k_peer_create(struct ath11k *ar + struct ieee80211_sta *sta, struct peer_create_params *param) + { + struct ath11k_peer *peer; ++ struct ieee80211_vif *vif = arvif->vif; + 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; + peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; +- peer->vif = arvif->vif; ++ peer->vif = 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) { +--- a/drivers/net/wireless/ath/ath11k/peer.h ++++ b/drivers/net/wireless/ath/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 */ ++ ATH11K_AST_TYPE_STATIC, /* static ast entry for connected peer */ ++ ATH11K_AST_TYPE_SELF, /* static ast entry for self peer (STA mode) */ ++ ATH11K_AST_TYPE_WDS, /* WDS peer ast entry type*/ ++ ATH11K_AST_TYPE_MEC, /* Multicast echo ast entry type */ ++ ATH11K_AST_TYPE_WDS_HM, /* HM WDS entry */ ++ ATH11K_AST_TYPE_STA_BSS, /* BSS entry(STA mode) */ ++ ATH11K_AST_TYPE_DA, /* AST entry based on Destination address */ ++ ATH11K_AST_TYPE_WDS_HM_SEC, /* HM WDS entry for secondary radio */ ++ ATH11K_AST_TYPE_MAX ++}; ++ ++enum ath11k_wds_wmi_action { ++ ATH11K_WDS_WMI_ADD = 1, ++ ATH11K_WDS_WMI_UPDATE, ++ ++ ATH11K_WDS_WMI_MAX ++}; ++ ++struct ath11k_ast_entry { ++ u16 ast_idx; ++ u8 addr[ETH_ALEN]; ++ u8 next_node_mac[ETH_ALEN]; ++ enum ath11k_wds_wmi_action action; ++ struct work_struct wds_wmi_wk; ++ struct ath11k_peer *peer; ++ struct ath11k *ar; ++ bool next_hop; ++ bool is_active; ++ bool is_mapped; ++ u8 pdev_idx; ++ u8 vdev_id; ++ 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 ath11k_peer { + struct list_head list; + struct ieee80211_sta *sta; +@@ -29,6 +70,10 @@ struct ath11k_peer { + u8 pdev_idx; + u16 hw_peer_id; + struct ath11k_nss_peer nss; ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ struct ath11k_ast_entry *self_ast_entry; ++ struct list_head ast_entry_list; ++#endif + + /* protected by ab->data_lock */ + struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; +@@ -54,8 +99,13 @@ struct ath11k_peer { + }; + + void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id); ++void ath11k_peer_unmap_v2_event(struct ath11k_base *ab, u16 peer_id, u8 *mac_addr, ++ bool is_wds, u32 free_wds_count); + void ath11k_peer_map_event(struct ath11k_base *ab, u8 vdev_id, u16 peer_id, + u8 *mac_addr, u16 ast_hash, u16 hw_peer_id); ++void ath11k_peer_map_v2_event(struct ath11k_base *ab, u8 vdev_id, u16 peer_id, ++ u8 *mac_addr, u16 ast_hash, u16 hw_peer_id, ++ bool is_wds); + 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, +@@ -72,4 +122,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); ++ ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++struct ath11k_ast_entry *ath11k_peer_ast_find_by_addr(struct ath11k_base *ab, ++ u8* addr); ++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, ++ struct ath11k_ast_entry *ast_entry); ++void ath11k_peer_map_ast(struct ath11k *ar, struct ath11k_peer *peer, ++ u8* mac_addr, u16 hw_peer_id, u16 ast_hash); ++void ath11k_peer_del_ast(struct ath11k *ar, struct ath11k_ast_entry *ast_entry); ++void ath11k_peer_ast_cleanup(struct ath11k *ar, struct ath11k_peer *peer, ++ bool is_wds, u32 free_wds_count); ++void ath11k_peer_ast_wds_wmi_wk(struct work_struct *wk); ++struct ath11k_ast_entry *ath11k_peer_ast_find_by_peer(struct ath11k_base *ab, ++ struct ath11k_peer *peer, ++ u8* addr); ++#else ++static inline struct ath11k_ast_entry *ath11k_peer_ast_find_by_addr(struct ath11k_base *ab, ++ u8* addr) ++{ ++ return NULL; ++} ++ ++static inline int ath11k_peer_add_ast(struct ath11k *ar, struct ath11k_peer *peer, ++ u8* mac_addr, enum ath11k_ast_entry_type type) ++{ ++ return 0; ++} ++ ++static inline int ath11k_peer_update_ast(struct ath11k *ar, struct ath11k_peer *peer, ++ struct ath11k_ast_entry *ast_entry) ++{ ++ return 0; ++} ++ ++static inline void ath11k_peer_map_ast(struct ath11k *ar, struct ath11k_peer *peer, ++ u8* mac_addr, u16 hw_peer_id, u16 ast_hash) ++{ ++ return; ++} ++ ++static inline void ath11k_peer_del_ast(struct ath11k *ar, ++ struct ath11k_ast_entry *ast_entry) ++{ ++ return; ++} ++ ++static inline void ath11k_peer_ast_cleanup(struct ath11k *ar, ++ struct ath11k_peer *peer, ++ bool is_wds, u32 free_wds_count) ++{ ++ return; ++} ++ ++static inline void ath11k_peer_ast_wds_wmi_wk(struct work_struct *wk) ++{ ++ return; ++} ++ ++static inline struct ath11k_ast_entry *ath11k_peer_ast_find_by_peer(struct ath11k_base *ab, ++ struct ath11k_peer *peer, ++ u8* addr) ++{ ++ return NULL; ++} ++#endif /* CPTCFG_ATH11K_NSS_SUPPORT */ + #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" }, + [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" }, + }; + + #define PRIMAP(_hw_mode_) \ +@@ -1174,6 +1175,51 @@ int ath11k_wmi_send_peer_delete_cmd(stru + return ret; + } + ++int ath11k_wmi_send_add_update_wds_entry_cmd(struct ath11k *ar, ++ const u8 *peer_addr, ++ const u8 *wds_addr, u8 vdev_id, ++ bool add_wds) ++{ ++ struct ath11k_pdev_wmi *wmi = ar->wmi; ++ struct wmi_add_wds_entry_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_add_wds_entry_cmd *)skb->data; ++ if (add_wds) ++ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PEER_ADD_WDS_ENTRY_CMD) | ++ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); ++ else ++ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PEER_UPDATE_WDS_ENTRY_CMD) | ++ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); ++ ++ ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); ++ ether_addr_copy(cmd->wds_macaddr.addr, wds_addr); ++ cmd->vdev_id = vdev_id; ++ cmd->flags = WMI_WDS_FLAG_STATIC; ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, ++ "WMI add WDS entry vdev_id %d peer_addr %pM, wds_addr %pM flags %x\n", ++ vdev_id, peer_addr, wds_addr, cmd->flags); ++ ++ if (add_wds) ++ ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PEER_ADD_WDS_ENTRY_CMDID); ++ else ++ ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PEER_UPDATE_WDS_ENTRY_CMDID); ++ ++ if (ret) { ++ ath11k_warn(ar->ab, "failed to send WMI_PEER_%s_WDS_ENTRY cmd\n", ++ add_wds ? "ADD" : "UPDATE"); ++ dev_kfree_skb(skb); ++ } ++ ++ return ret; ++} ++ + int ath11k_wmi_send_pdev_set_regdomain(struct ath11k *ar, + struct pdev_set_regdomain_params *param) + { +@@ -6484,6 +6530,36 @@ static int ath11k_pull_peer_assoc_conf_e + return 0; + } + ++static int ath11k_pull_wds_addr_ev(struct ath11k_base *ab, struct sk_buff *skb, ++ struct wmi_wds_addr_arg *wds_addr_arg) ++{ ++ const void **tb; ++ const struct wmi_wds_addr_event *ev; ++ 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 ret; ++ } ++ ++ ev = tb[WMI_TAG_WDS_ADDR_EVENT]; ++ if (!ev) { ++ ath11k_warn(ab, "failed to fetch wds peer ev"); ++ kfree(tb); ++ return -EPROTO; ++ } ++ ++ memcpy(wds_addr_arg->event_type, ev->event_type, WMI_NUM_WDS_EVENTS); ++ wds_addr_arg->vdev_id = ev->vdev_id; ++ wds_addr_arg->peer_macaddr = ev->peer_macaddr.addr; ++ wds_addr_arg->dst_macaddr = ev->dst_macaddr.addr; ++ ++ kfree(tb); ++ return 0; ++} ++ + static void ath11k_wmi_pull_pdev_stats_base(const struct wmi_pdev_stats_base *src, + struct ath11k_fw_stats_pdev *dst) + { +@@ -7399,6 +7475,7 @@ static int ath11k_wmi_tlv_rdy_parse(stru + + ether_addr_copy(ab->mac_addr, + fixed_param.ready_event_min.mac_addr.addr); ++ ab->max_ast_index = fixed_param.max_ast_index + 1; + ab->pktlog_defs_checksum = fixed_param.pktlog_defs_checksum; + break; + case WMI_TAG_ARRAY_FIXED_STRUCT: +@@ -8870,6 +8947,22 @@ static void ath11k_wmi_gtk_offload_statu + kfree(tb); + } + ++static void ath11k_wmi_wds_peer_event(struct ath11k_base *ab, ++ struct sk_buff *skb) ++{ ++ struct wmi_wds_addr_arg wds_addr_arg = {0}; ++ ++ if (ath11k_pull_wds_addr_ev(ab, skb, &wds_addr_arg) != 0) { ++ ath11k_warn(ab, "failed to extract wds addr event"); ++ return; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_WMI, ++ "wds addr event vdev id %d peer macaddr %pM dst macaddr %pM\n", ++ wds_addr_arg.vdev_id, wds_addr_arg.peer_macaddr, ++ wds_addr_arg.dst_macaddr); ++} ++ + static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb) + { + struct wmi_cmd_hdr *cmd_hdr; +@@ -9000,6 +9093,9 @@ static void ath11k_wmi_tlv_op_rx(struct + case WMI_QOS_NULL_FRAME_TX_COMPLETION_EVENTID: + ath11k_qos_null_compl_event(ab, skb); + break; ++ case WMI_WDS_PEER_EVENTID: ++ ath11k_wmi_wds_peer_event(ab, skb); ++ break; + default: + ath11k_dbg(ab, ATH11K_DBG_WMI, "unsupported event id 0x%x\n", id); + 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 { + struct wmi_mac_addr peer_macaddr; + } __packed; + ++#define WMI_WDS_FLAG_STATIC 0x1 /* Disable aging & learning */ ++struct wmi_add_wds_entry_cmd { ++ u32 tlv_header; ++ struct wmi_mac_addr peer_macaddr; ++ struct wmi_mac_addr wds_macaddr; ++ u32 flags; ++ u32 vdev_id; ++} __packed; ++ ++struct wmi_remove_wds_entry_cmd { ++ u32 tlv_header; ++ struct wmi_mac_addr wds_macaddr; ++ u32 vdev_id; ++} __packed; ++ + struct wmi_peer_reorder_queue_setup_cmd { + u32 tlv_header; + u32 vdev_id; +@@ -4629,6 +4644,21 @@ struct wmi_probe_resp_tx_status_event { + u32 tx_status; + } __packed; + ++#define WMI_NUM_WDS_EVENTS 4 ++struct wmi_wds_addr_arg { ++ u32 event_type[WMI_NUM_WDS_EVENTS]; ++ const u8 *peer_macaddr; ++ const u8 *dst_macaddr; ++ u32 vdev_id; ++}; ++ ++struct wmi_wds_addr_event { ++ u32 event_type[WMI_NUM_WDS_EVENTS]; ++ struct wmi_mac_addr peer_macaddr; ++ struct wmi_mac_addr dst_macaddr; ++ u32 vdev_id; ++} __packed; ++ + /* + * PDEV statistics + */ +@@ -6503,6 +6533,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); ++int ath11k_wmi_send_add_update_wds_entry_cmd(struct ath11k *ar, ++ const u8 *peer_addr, const u8 *wds_addr, ++ u8 vdev_id, bool add_wds); + int ath11k_wmi_vdev_delete(struct ath11k *ar, u8 vdev_id); + void ath11k_wmi_start_scan_init(struct ath11k *ar, struct scan_req_params *arg); + int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar, diff --git a/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-HE-stats-in-peer-stats.patch b/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-HE-stats-in-peer-stats.patch new file mode 100644 index 00000000000000..edb60ac18bef10 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-HE-stats-in-peer-stats.patch @@ -0,0 +1,777 @@ +From e4f16128c53b48f166301085cecc23f77bf3ff8e Mon Sep 17 00:00:00 2001 +From: Miles Hu +Date: Fri, 11 Oct 2019 19:24:06 -0700 +Subject: [PATCH] ath11k: add HE stats in peer stats packet counters for MIMO + and OFDMA + +Signed-off-by: Miles Hu +--- + drivers/net/wireless/ath/ath11k/core.h | 23 ++++- + drivers/net/wireless/ath/ath11k/debugfs_sta.c | 127 +++++++++++++++++++++++++- + drivers/net/wireless/ath/ath11k/dp.h | 21 ++++- + drivers/net/wireless/ath/ath11k/dp_rx.c | 17 +++- + drivers/net/wireless/ath/ath11k/rx_desc.h | 5 + + 5 files changed, 185 insertions(+), 8 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -29,6 +29,7 @@ + #include "dbring.h" + #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 { + 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]; ++ u64 transmit_type[ATH11K_COUNTER_TYPE_MAX][HAL_RX_RECEPTION_TYPE_MAX]; ++ u64 ru_loc[ATH11K_COUNTER_TYPE_MAX][HAL_RX_RU_ALLOC_TYPE_MAX]; + }; + + struct ath11k_htt_tx_stats { +@@ -483,6 +486,9 @@ struct ath11k_htt_tx_stats { + u64 tx_duration; + u64 ba_fails; + u64 ack_fails; ++ u16 ru_start; ++ u16 ru_tones; ++ u32 mu_group[MAX_MU_GROUP_ID]; + }; + + struct ath11k_per_ppdu_tx_stats { +@@ -615,11 +621,16 @@ struct ath11k_per_peer_tx_stats { + u32 succ_bytes; + u32 retry_bytes; + u32 failed_bytes; ++ u32 duration; + u16 succ_pkts; + u16 retry_pkts; + u16 failed_pkts; +- u32 duration; ++ u16 ru_start; ++ u16 ru_tones; + u8 ba_fails; ++ u8 ppdu_type; ++ u32 mu_grpid; ++ u32 mu_pos; + bool is_ampdu; + }; + +--- 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" + #include "debugfs_htt_stats.h" + ++static inline u32 ath11k_he_tones_in_ru_to_nl80211_he_ru_alloc(u16 ru_tones) ++{ ++ u32 ret = 0; ++ switch (ru_tones) { ++ case 26: ++ ret = NL80211_RATE_INFO_HE_RU_ALLOC_26; ++ break; ++ case 52: ++ ret = NL80211_RATE_INFO_HE_RU_ALLOC_52; ++ break; ++ case 106: ++ ret = NL80211_RATE_INFO_HE_RU_ALLOC_106; ++ break; ++ case 242: ++ ret = NL80211_RATE_INFO_HE_RU_ALLOC_242; ++ break; ++ case 484: ++ ret = NL80211_RATE_INFO_HE_RU_ALLOC_484; ++ break; ++ case 996: ++ ret = NL80211_RATE_INFO_HE_RU_ALLOC_996; ++ break; ++ } ++ return ret; ++} ++ + void ath11k_debugfs_sta_add_tx_stats(struct ath11k_sta *arsta, + struct ath11k_per_peer_tx_stats *peer_stats, + u8 legacy_rate_idx) + { + struct rate_info *txrate = &arsta->txrate; + struct ath11k_htt_tx_stats *tx_stats; +- int gi, mcs, bw, nss; ++ int gi, mcs, bw, nss, ru_type, ppdu_type; + + if (!arsta->tx_stats) + return; +@@ -63,6 +89,43 @@ void ath11k_debugfs_sta_add_tx_stats(str + STATS_OP_FMT(RETRY).legacy[1][mcs] += peer_stats->retry_pkts; + } + ++ ppdu_type = peer_stats->ppdu_type; ++ if ((ppdu_type == HTT_PPDU_STATS_PPDU_TYPE_MU_OFDMA || ++ ppdu_type == HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO_OFDMA) && ++ (txrate->flags & RATE_INFO_FLAGS_HE_MCS)){ ++ ru_type = peer_stats->ru_tones; ++ ++ if (ru_type <= NL80211_RATE_INFO_HE_RU_ALLOC_996) { ++ STATS_OP_FMT(SUCC).ru_loc[0][ru_type] += peer_stats->succ_bytes; ++ STATS_OP_FMT(SUCC).ru_loc[1][ru_type] += peer_stats->succ_pkts; ++ STATS_OP_FMT(FAIL).ru_loc[0][ru_type] += peer_stats->failed_bytes; ++ STATS_OP_FMT(FAIL).ru_loc[1][ru_type] += peer_stats->failed_pkts; ++ STATS_OP_FMT(RETRY).ru_loc[0][ru_type] += peer_stats->retry_bytes; ++ STATS_OP_FMT(RETRY).ru_loc[1][ru_type] += peer_stats->retry_pkts; ++ if (peer_stats->is_ampdu) { ++ STATS_OP_FMT(AMPDU).ru_loc[0][ru_type] += ++ peer_stats->succ_bytes + peer_stats->retry_bytes; ++ STATS_OP_FMT(AMPDU).ru_loc[1][ru_type] += ++ peer_stats->succ_pkts + peer_stats->retry_pkts; ++ } ++ } ++ } ++ ++ if (ppdu_type < HTT_PPDU_STATS_PPDU_TYPE_MAX) { ++ STATS_OP_FMT(SUCC).transmit_type[0][ppdu_type] += peer_stats->succ_bytes; ++ STATS_OP_FMT(SUCC).transmit_type[1][ppdu_type] += peer_stats->succ_pkts; ++ STATS_OP_FMT(FAIL).transmit_type[0][ppdu_type] += peer_stats->failed_bytes; ++ STATS_OP_FMT(FAIL).transmit_type[1][ppdu_type] += peer_stats->failed_pkts; ++ STATS_OP_FMT(RETRY).transmit_type[0][ppdu_type] += peer_stats->retry_bytes; ++ STATS_OP_FMT(RETRY).transmit_type[1][ppdu_type] += peer_stats->retry_pkts; ++ if (peer_stats->is_ampdu) { ++ STATS_OP_FMT(AMPDU).transmit_type[0][ppdu_type] += ++ peer_stats->succ_bytes + peer_stats->retry_bytes; ++ STATS_OP_FMT(AMPDU).transmit_type[1][ppdu_type] += ++ peer_stats->succ_pkts + peer_stats->retry_pkts; ++ } ++ } ++ + 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 + STATS_OP_FMT(RETRY).gi[1][gi] += peer_stats->retry_pkts; + + tx_stats->tx_duration += peer_stats->duration; ++ ++ tx_stats->ru_start = peer_stats->ru_start; ++ tx_stats->ru_tones = peer_stats->ru_tones; ++ ++ if (peer_stats->mu_grpid <= MAX_MU_GROUP_ID && ++ peer_stats->ppdu_type != HTT_PPDU_STATS_PPDU_TYPE_SU) { ++ if (peer_stats->mu_grpid & (MAX_MU_GROUP_ID - 1)) ++ tx_stats->mu_group[peer_stats->mu_grpid] = ++ (peer_stats->mu_pos + 1); ++ } ++ + } + + void ath11k_debugfs_sta_update_txcompl(struct ath11k *ar, +@@ -139,12 +213,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; +- static const char *str_name[ATH11K_STATS_TYPE_MAX] = {"succ", "fail", ++ static const char *str_name[ATH11K_STATS_TYPE_MAX] = {"success", "fail", + "retry", "ampdu"}; + static const char *str[ATH11K_COUNTER_TYPE_MAX] = {"bytes", "packets"}; + int len = 0, i, j, k, retval = 0; + const int size = 2 * 4096; +- char *buf; ++ 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 + len += scnprintf(buf + len, size - len, "%s_%s\n", + str_name[k], + str[j]); ++ len += scnprintf(buf + len, size - len, "==========\n"); + len += scnprintf(buf + len, size - len, +- " HE MCS %s\n", ++ " HE MCS %s\n\t", + str[j]); + for (i = 0; i < ATH11K_HE_MCS_NUM; i++) + len += scnprintf(buf + len, size - len, +- " %llu ", ++ "%llu ", + stats->he[j][i]); + len += scnprintf(buf + len, size - len, "\n"); + len += scnprintf(buf + len, size - len, +- " VHT MCS %s\n", ++ " VHT MCS %s\n\t", + str[j]); + for (i = 0; i < ATH11K_VHT_MCS_NUM; i++) + len += scnprintf(buf + len, size - len, +- " %llu ", ++ "%llu ", + stats->vht[j][i]); + len += scnprintf(buf + len, size - len, "\n"); +- len += scnprintf(buf + len, size - len, " HT MCS %s\n", ++ len += scnprintf(buf + len, size - len, " HT MCS %s\n\t", + str[j]); + for (i = 0; i < ATH11K_HT_MCS_NUM; i++) + len += scnprintf(buf + len, size - len, +- " %llu ", stats->ht[j][i]); ++ "%llu ", stats->ht[j][i]); + len += scnprintf(buf + len, size - len, "\n"); + len += scnprintf(buf + len, size - len, + " BW %s (20,40,80,160 MHz)\n", str[j]); + len += scnprintf(buf + len, size - len, +- " %llu %llu %llu %llu\n", ++ "\t%llu %llu %llu %llu\n", + stats->bw[j][0], stats->bw[j][1], + stats->bw[j][2], stats->bw[j][3]); + len += scnprintf(buf + len, size - len, + " NSS %s (1x1,2x2,3x3,4x4)\n", str[j]); + len += scnprintf(buf + len, size - len, +- " %llu %llu %llu %llu\n", ++ "\t%llu %llu %llu %llu\n", + stats->nss[j][0], stats->nss[j][1], + stats->nss[j][2], stats->nss[j][3]); + len += scnprintf(buf + len, size - len, + " GI %s (0.4us,0.8us,1.6us,3.2us)\n", + str[j]); + len += scnprintf(buf + len, size - len, +- " %llu %llu %llu %llu\n", ++ "\t%llu %llu %llu %llu\n", + 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 + for (i = 0; i < ATH11K_LEGACY_NUM; i++) + len += scnprintf(buf + len, size - len, "%llu ", + stats->legacy[j][i]); +- len += scnprintf(buf + len, size - len, "\n"); ++ ++ len += scnprintf(buf + len, size - len, "\n ru %s: \n", str[j]); ++ len += scnprintf(buf + len, size - len, ++ "\tru 26: %llu\n", stats->ru_loc[j][0]); ++ len += scnprintf(buf + len, size - len, ++ "\tru 52: %llu \n", stats->ru_loc[j][1]); ++ len += scnprintf(buf + len, size - len, ++ "\tru 106: %llu \n", stats->ru_loc[j][2]); ++ len += scnprintf(buf + len, size - len, ++ "\tru 242: %llu \n", stats->ru_loc[j][3]); ++ len += scnprintf(buf + len, size - len, ++ "\tru 484: %llu \n", stats->ru_loc[j][4]); ++ len += scnprintf(buf + len, size - len, ++ "\tru 996: %llu \n", stats->ru_loc[j][5]); ++ ++ len += scnprintf(buf + len, size - len, ++ " ppdu type %s: \n", str[j]); ++ if (k == ATH11K_STATS_TYPE_FAIL || ++ k == ATH11K_STATS_TYPE_RETRY) { ++ len += scnprintf(buf + len, size - len, ++ "\tSU/MIMO: %llu\n", ++ stats->transmit_type[j][0]); ++ len += scnprintf(buf + len, size - len, ++ "\tOFDMA/OFDMA_MIMO: %llu\n", ++ stats->transmit_type[j][2]); ++ } else { ++ len += scnprintf(buf + len, size - len, ++ "\tSU: %llu\n", ++ stats->transmit_type[j][0]); ++ len += scnprintf(buf + len, size - len, ++ "\tMIMO: %llu\n", ++ stats->transmit_type[j][1]); ++ len += scnprintf(buf + len, size - len, ++ "\tOFDMA: %llu\n", ++ stats->transmit_type[j][2]); ++ len += scnprintf(buf + len, size - len, ++ "\tOFDMA_MIMO: %llu\n", ++ stats->transmit_type[j][3]); ++ } + } + } + ++ len += scnprintf(buf + len, size - len, "\n"); ++ ++ for (i = 0; i < MAX_MU_GROUP_ID;) { ++ index = 0; ++ for (j = 0; j < MAX_MU_GROUP_SHOW && i < MAX_MU_GROUP_ID; ++ j++) { ++ index += snprintf(&mu_group_id[index], ++ MAX_MU_GROUP_LENGTH - index, ++ " %d", ++ arsta->tx_stats->mu_group[i]); ++ i++; ++ } ++ len += scnprintf(buf + len, size - len, ++ "User position list for GID %02d->%d: [%s]\n", ++ i - MAX_MU_GROUP_SHOW, i - 1, mu_group_id); ++ } ++ len += scnprintf(buf + len, size - len, ++ "\nLast Packet RU index [%d], Size [%d]\n", ++ arsta->tx_stats->ru_start, arsta->tx_stats->ru_tones); ++ + 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 + "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); ++ + spin_unlock_bh(&ar->data_lock); + + 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 { + BIT(HTT_PPDU_STATS_TAG_TX_MGMTCTRL_PAYLOAD) | \ + HTT_PPDU_STATS_TAG_DEFAULT) + ++#define HTT_STATS_FRAMECTRL_TYPE_MASK 0x0C ++#define HTT_STATS_GET_FRAME_CTRL_TYPE(_val) \ ++ (((_val) & HTT_STATS_FRAMECTRL_TYPE_MASK) >> 2) ++#define HTT_STATS_FRAME_CTRL_TYPE_MGMT 0x0 ++#define HTT_STATS_FRAME_CTRL_TYPE_CTRL 0x1 ++#define HTT_STATS_FRAME_CTRL_TYPE_DATA 0x2 ++#define HTT_STATS_FRAME_CTRL_TYPE_RESV 0x3 ++ ++enum htt_stats_frametype { ++ HTT_STATS_FTYPE_SGEN_NDPA = 0, ++ HTT_STATS_FTYPE_SGEN_NDP, ++ HTT_STATS_FTYPE_SGEN_BRP, ++ HTT_STATS_FTYPE_SGEN_BAR, ++ HTT_STATS_FTYPE_SGEN_RTS, ++ HTT_STATS_FTYPE_SGEN_CTS, ++ HTT_STATS_FTYPE_SGEN_CFEND, ++ HTT_STATS_FTYPE_SGEN_AX_NDPA, ++ HTT_STATS_FTYPE_SGEN_AX_NDP, ++ HTT_STATS_FTYPE_SGEN_MU_TRIG, ++ HTT_STATS_FTYPE_SGEN_MU_BAR, ++ HTT_STATS_FTYPE_SGEN_MU_BRP, ++ HTT_STATS_FTYPE_SGEN_MU_RTS, ++ HTT_STATS_FTYPE_SGEN_MU_BSR, ++ HTT_STATS_FTYPE_SGEN_UL_BSR, ++ HTT_STATS_FTYPE_SGEN_UL_BSR_TRIGGER = HTT_STATS_FTYPE_SGEN_UL_BSR, ++ HTT_STATS_FTYPE_TIDQ_DATA_SU, ++ HTT_STATS_FTYPE_TIDQ_DATA_MU, ++ HTT_STATS_FTYPE_SGEN_UL_BSR_RESP, ++ HTT_STATS_FTYPE_SGEN_QOS_NULL, ++ HTT_STATS_FTYPE_MAX, ++}; ++ ++enum htt_stats_internal_ppdu_frametype { ++ HTT_STATS_PPDU_FTYPE_CTRL, ++ HTT_STATS_PPDU_FTYPE_DATA, ++ HTT_STATS_PPDU_FTYPE_BAR, ++ HTT_STATS_PPDU_FTYPE_MAX ++}; ++ + /* HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG Message + * + * details: +@@ -1312,6 +1351,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) + ++enum HTT_PPDU_STATS_PPDU_TYPE { ++ HTT_PPDU_STATS_PPDU_TYPE_SU, ++ HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO, ++ HTT_PPDU_STATS_PPDU_TYPE_MU_OFDMA, ++ HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO_OFDMA, ++ HTT_PPDU_STATS_PPDU_TYPE_UL_TRIG, ++ HTT_PPDU_STATS_PPDU_TYPE_BURST_BCN, ++ HTT_PPDU_STATS_PPDU_TYPE_UL_BSR_RESP, ++ HTT_PPDU_STATS_PPDU_TYPE_UL_BSR_TRIG, ++ HTT_PPDU_STATS_PPDU_TYPE_UL_RESP, ++ HTT_PPDU_STATS_PPDU_TYPE_MAX ++}; ++ + #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) + +@@ -1339,6 +1391,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) ++#define HTT_USR_RATE_PPDU_TYPE(_val) \ ++ FIELD_GET(HTT_PPDU_STATS_USER_RATE_INFO1_PPDU_TYPE_M, _val) ++#define HTT_USR_RATE_MU_GRPID(_val) \ ++ FIELD_GET(HTT_PPDU_STATS_USER_RATE_INFO0_MU_GROUP_ID_M, _val) ++#define HTT_USR_RATE_USR_POS(_val) \ ++ FIELD_GET(HTT_PPDU_STATS_USER_RATE_INFO0_USER_POS_M, _val) + + #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) +@@ -1442,6 +1500,21 @@ struct htt_ppdu_stats_usr_cmpltn_ack_ba_ + u32 success_bytes; + } __packed; + ++#define HTT_PPDU_STATS_USR_CMN_FLAG_DELAYBA BIT(14) ++#define HTT_PPDU_STATS_USR_CMN_HDR_SW_PEERID GENMASK(31, 16) ++#define HTT_PPDU_STATS_USR_CMN_CTL_FRM_CTRL GENMASK(15, 0) ++ ++struct htt_ppdu_stats_user_common { ++ u8 tid_num; ++ u8 vdev_id; ++ u16 sw_peer_id; ++ u32 info; ++ u32 ctrl; ++ u32 buffer_paddr_31_0; ++ u32 buffer_paddr_39_32; ++ u32 host_opaque_cookie; ++} __packed; ++ + struct htt_ppdu_stats_usr_cmn_array { + struct htt_tlv tlv_hdr; + u32 num_ppdu_stats; +@@ -1455,14 +1528,16 @@ struct htt_ppdu_stats_usr_cmn_array { + + struct htt_ppdu_user_stats { + u16 peer_id; ++ u16 delay_ba; + u32 tlv_flags; + bool is_valid_peer_id; + 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; + }; + +-#define HTT_PPDU_STATS_MAX_USERS 8 ++#define HTT_PPDU_STATS_MAX_USERS 37 + #define HTT_PPDU_DESC_MAX_DEPTH 16 + + struct htt_ppdu_stats { +@@ -1471,7 +1546,7 @@ struct htt_ppdu_stats { + }; + + struct htt_ppdu_stats_info { +- u32 ppdu_id; ++ u32 tlv_bitmap, ppdu_id, frame_type, frame_ctrl, delay_ba, bar_num_users; + struct htt_ppdu_stats ppdu_stats; + struct list_head list; + }; +--- 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 + void *data) + { + struct htt_ppdu_stats_info *ppdu_info; +- struct htt_ppdu_user_stats *user_stats; ++ struct htt_ppdu_user_stats *user_stats = NULL; + int cur_user; + u16 peer_id; ++ u32 frame_type; + + ppdu_info = data; + +@@ -1334,6 +1335,26 @@ static int ath11k_htt_tlv_ppdu_stats_par + } + memcpy((void *)&ppdu_info->ppdu_stats.common, ptr, + sizeof(struct htt_ppdu_stats_common)); ++ frame_type = ++ FIELD_GET(HTT_PPDU_STATS_CMN_FLAGS_FRAME_TYPE_M, ++ ppdu_info->ppdu_stats.common.flags); ++ switch (frame_type) { ++ case HTT_STATS_FTYPE_TIDQ_DATA_SU: ++ case HTT_STATS_FTYPE_TIDQ_DATA_MU: ++ if (HTT_STATS_GET_FRAME_CTRL_TYPE(ppdu_info->frame_ctrl) <= HTT_STATS_FRAME_CTRL_TYPE_CTRL) ++ ppdu_info->frame_type = HTT_STATS_PPDU_FTYPE_CTRL; ++ else ++ ppdu_info->frame_type = HTT_STATS_PPDU_FTYPE_DATA; ++ break; ++ case HTT_STATS_FTYPE_SGEN_MU_BAR: ++ case HTT_STATS_FTYPE_SGEN_BAR: ++ ppdu_info->frame_type = HTT_STATS_PPDU_FTYPE_BAR; ++ break; ++ default: ++ ppdu_info->frame_type = HTT_STATS_PPDU_FTYPE_CTRL; ++ break; ++ } ++ + 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 + peer_id); + if (cur_user < 0) + return -EINVAL; ++ ppdu_info->bar_num_users += 1; + 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 + sizeof(struct htt_ppdu_stats_usr_cmpltn_ack_ba_status)); + user_stats->tlv_flags |= BIT(tag); + break; +- } +- return 0; +-} +- +-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), +- void *data) +-{ +- const struct htt_tlv *tlv; +- const void *begin = ptr; +- u16 tlv_tag, tlv_len; +- int ret = -EINVAL; +- +- while (len > 0) { +- if (len < sizeof(*tlv)) { +- ath11k_err(ab, "htt tlv parse failure at byte %zd (%zu bytes left, %zu expected)\n", +- ptr - begin, len, sizeof(*tlv)); ++ case HTT_PPDU_STATS_TAG_USR_COMMON: ++ if (len < sizeof(struct htt_ppdu_stats_user_common)) { ++ ath11k_warn(ab, "Invalid len %d for the tag 0x%x\n", ++ len, tag); + return -EINVAL; + } +- tlv = (struct htt_tlv *)ptr; +- tlv_tag = FIELD_GET(HTT_TLV_TAG, tlv->header); +- tlv_len = FIELD_GET(HTT_TLV_LEN, tlv->header); +- ptr += sizeof(*tlv); +- len -= sizeof(*tlv); +- +- if (tlv_len > len) { +- ath11k_err(ab, "htt tlv parse failure of tag %u at byte %zd (%zu bytes left, %u expected)\n", +- tlv_tag, ptr - begin, len, tlv_len); ++ peer_id = ((struct htt_ppdu_stats_user_common *)ptr)->sw_peer_id; ++ cur_user = ath11k_get_ppdu_user_index(&ppdu_info->ppdu_stats, ++ peer_id); ++ if (cur_user < 0) + return -EINVAL; +- } +- ret = iter(ab, tlv_tag, tlv_len, ptr, data); +- if (ret == -ENOMEM) +- return ret; +- +- ptr += tlv_len; +- len -= tlv_len; ++ user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user]; ++ memcpy(&user_stats->common, ptr, ++ sizeof(struct htt_ppdu_stats_user_common)); ++ ppdu_info->frame_ctrl = FIELD_GET(HTT_PPDU_STATS_USR_CMN_CTL_FRM_CTRL, ++ user_stats->common.ctrl); ++ user_stats->delay_ba = FIELD_GET(HTT_PPDU_STATS_USR_CMN_FLAG_DELAYBA, ++ user_stats->common.info); ++ ppdu_info->delay_ba = user_stats->delay_ba; ++ break; ++ default: ++ break; + } ++ ppdu_info->tlv_bitmap |= BIT(tag); + return 0; + } + +@@ -1449,8 +1457,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; +- u32 succ_bytes = 0; +- u16 rate = 0, succ_pkts = 0; ++ u32 succ_bytes = 0, ppdu_type, mu_grpid, mu_pos; ++ u16 rate = 0, succ_pkts = 0, ru_tone, ru_start; + 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 + 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); ++ ppdu_type = HTT_USR_RATE_PPDU_TYPE(user_rate->info1); ++ mu_grpid = HTT_USR_RATE_MU_GRPID(user_rate->info0); ++ mu_pos = HTT_USR_RATE_USR_POS(user_rate->info0); ++ ru_start = user_rate->ru_start; ++ ru_tone = user_rate->ru_end; + + /* 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 + peer_stats->ba_fails = + HTT_USR_CMPLTN_LONG_RETRY(usr_stats->cmpltn_cmn.flags) + + HTT_USR_CMPLTN_SHORT_RETRY(usr_stats->cmpltn_cmn.flags); ++ peer_stats->ppdu_type = ppdu_type; ++ peer_stats->ru_tones = ru_tone; ++ peer_stats->ru_start = ru_start; ++ peer_stats->mu_grpid = mu_grpid; ++ peer_stats->mu_pos = mu_pos; ++ peer_stats->ru_tones = arsta->txrate.he_ru_alloc; + + 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 + return ppdu_info; + } + ++void ath11k_copy_to_delay_stats(struct ath11k_peer *peer, ++ struct htt_ppdu_user_stats* usr_stats) ++{ ++ peer->ppdu_stats_delayba.reserved0 = usr_stats->rate.reserved0; ++ peer->ppdu_stats_delayba.sw_peer_id = usr_stats->rate.sw_peer_id; ++ peer->ppdu_stats_delayba.info0 = usr_stats->rate.info0; ++ peer->ppdu_stats_delayba.ru_end = usr_stats->rate.ru_end; ++ peer->ppdu_stats_delayba.ru_start = usr_stats->rate.ru_start; ++ peer->ppdu_stats_delayba.info1 = usr_stats->rate.info1; ++ peer->ppdu_stats_delayba.rate_flags = usr_stats->rate.rate_flags; ++ peer->ppdu_stats_delayba.resp_rate_flags = usr_stats->rate.resp_rate_flags; ++ ++ peer->delayba_flag = true; ++} ++ ++void ath11k_copy_to_bar(struct ath11k_peer *peer, ++ struct htt_ppdu_user_stats* usr_stats) ++{ ++ usr_stats->rate.reserved0 = peer->ppdu_stats_delayba.reserved0; ++ usr_stats->rate.sw_peer_id = peer->ppdu_stats_delayba.sw_peer_id; ++ usr_stats->rate.info0 = peer->ppdu_stats_delayba.info0; ++ usr_stats->rate.ru_end = peer->ppdu_stats_delayba.ru_end; ++ usr_stats->rate.ru_start = peer->ppdu_stats_delayba.ru_start; ++ usr_stats->rate.info1 = peer->ppdu_stats_delayba.info1; ++ usr_stats->rate.rate_flags = peer->ppdu_stats_delayba.rate_flags; ++ usr_stats->rate.resp_rate_flags = peer->ppdu_stats_delayba.resp_rate_flags; ++ ++ peer->delayba_flag = false; ++} ++ ++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), ++ void *data) ++{ ++ const struct htt_tlv *tlv; ++ const void *begin = ptr; ++ u16 tlv_tag, tlv_len; ++ int ret = -EINVAL; ++ struct htt_ppdu_stats_info * ppdu_info = NULL; ++ ++ 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", ++ ptr - begin, len, sizeof(*tlv)); ++ return -EINVAL; ++ } ++ tlv = (struct htt_tlv *)ptr; ++ tlv_tag = FIELD_GET(HTT_TLV_TAG, tlv->header); ++ tlv_len = FIELD_GET(HTT_TLV_LEN, tlv->header); ++ ptr += sizeof(*tlv); ++ 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", ++ tlv_tag, ptr - begin, len, tlv_len); ++ return -EINVAL; ++ } ++ ++ ret = iter(ab, tlv_tag, tlv_len, ptr, ppdu_info); ++ if (ret == -ENOMEM) ++ return ret; ++ ++ ptr += tlv_len; ++ len -= tlv_len; ++ } ++ return 0; ++} ++ + static int ath11k_htt_pull_ppdu_stats(struct ath11k_base *ab, + struct sk_buff *skb) + { + struct ath11k_htt_ppdu_stats_msg *msg; + struct htt_ppdu_stats_info *ppdu_info; ++ struct ath11k_peer *peer = NULL; ++ struct htt_ppdu_user_stats* usr_stats = NULL; ++ u32 peer_id = 0; + struct ath11k *ar; +- int ret; ++ int ret, i; + u8 pdev_id; + u32 ppdu_id, len; + +@@ -1668,6 +1761,47 @@ static int ath11k_htt_pull_ppdu_stats(st + goto out_unlock_data; + } + ++ /* back up data rate tlv for all peers */ ++ if (ppdu_info->frame_type == HTT_STATS_PPDU_FTYPE_DATA && ++ (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON)) && ++ ppdu_info->delay_ba) { ++ ++ for (i = 0; i < ppdu_info->ppdu_stats.common.num_users; i++) { ++ peer_id = ppdu_info->ppdu_stats.user_stats[i].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; ++ } ++ ++ usr_stats = &ppdu_info->ppdu_stats.user_stats[i]; ++ if (usr_stats->delay_ba) ++ ath11k_copy_to_delay_stats(peer, usr_stats); ++ spin_unlock_bh(&ab->base_lock); ++ } ++ } ++ ++ /* restore all peers' data rate tlv to mu-bar tlv */ ++ if (ppdu_info->frame_type == HTT_STATS_PPDU_FTYPE_BAR && ++ (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON))) { ++ ++ for (i = 0; i < ppdu_info->bar_num_users; i++) { ++ peer_id = ppdu_info->ppdu_stats.user_stats[i].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; ++ } ++ ++ usr_stats = &ppdu_info->ppdu_stats.user_stats[i]; ++ if (peer->delayba_flag) ++ ath11k_copy_to_bar(peer, usr_stats); ++ spin_unlock_bh(&ab->base_lock); ++ } ++ } ++ + out_unlock_data: + spin_unlock_bh(&ar->data_lock); + +--- 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 { + } u; + } __packed; + ++#define MAX_USER_POS 8 ++#define MAX_MU_GROUP_ID 64 ++#define MAX_MU_GROUP_SHOW 16 ++#define MAX_MU_GROUP_LENGTH (6 * MAX_MU_GROUP_SHOW) ++ + #define HAL_RX_RU_ALLOC_TYPE_MAX 6 + #define RU_26 1 + #define RU_52 2 +--- a/drivers/net/wireless/ath/ath11k/peer.h ++++ b/drivers/net/wireless/ath/ath11k/peer.h +@@ -7,6 +7,17 @@ + #ifndef ATH11K_PEER_H + #define ATH11K_PEER_H + ++struct ppdu_user_delayba { ++ u8 reserved0; ++ u16 sw_peer_id; ++ u32 info0; ++ u16 ru_end; ++ u16 ru_start; ++ u32 info1; ++ u32 rate_flags; ++ u32 resp_rate_flags; ++}; ++ + struct ath11k_peer { + struct list_head list; + struct ieee80211_sta *sta; +@@ -38,6 +49,8 @@ struct ath11k_peer { + u16 sec_type_grp; + bool is_authorized; + bool dp_setup_done; ++ struct ppdu_user_delayba ppdu_stats_delayba; ++ bool delayba_flag; + }; + + void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id); diff --git a/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-btcoex-config.patch b/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-btcoex-config.patch new file mode 100644 index 00000000000000..18bc4384094eca --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-btcoex-config.patch @@ -0,0 +1,612 @@ +--- a/drivers/net/wireless/ath/ath11k/Makefile ++++ b/drivers/net/wireless/ath/ath11k/Makefile +@@ -17,7 +17,8 @@ ath11k-y += core.o \ + peer.o \ + dbring.o \ + hw.o \ +- pcic.o ++ pcic.o \ ++ vendor.o + + ath11k-$(CPTCFG_ATH11K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o + ath11k-$(CPTCFG_NL80211_TESTMODE) += testmode.o +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -637,6 +637,16 @@ struct ath11k_per_peer_tx_stats { + #define ATH11K_FLUSH_TIMEOUT (5 * HZ) + #define ATH11K_VDEV_DELETE_TIMEOUT_HZ (5 * HZ) + ++struct ath11k_coex_info { ++ bool coex_support; ++ u32 pta_num; ++ u32 coex_mode; ++ u32 bt_active_time_slot; ++ u32 bt_priority_time_slot; ++ u32 coex_algo_type; ++ u32 pta_priority; ++}; ++ + struct ath11k { + struct ath11k_base *ab; + struct ath11k_pdev *pdev; +@@ -759,6 +769,8 @@ struct ath11k { + struct ath11k_per_peer_tx_stats cached_stats; + u32 last_ppdu_id; + u32 cached_ppdu_id; ++ ++ struct ath11k_coex_info coex; + int monitor_vdev_id; + struct completion fw_mode_reset; + u8 ftm_msgref; +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -24,6 +25,7 @@ + #include "debugfs_sta.h" + #include "hif.h" + #include "wow.h" ++#include "vendor.h" + #include "nss.h" + + #define CHAN2G(_channel, _freq, _flags) { \ +@@ -9282,6 +9284,91 @@ err_fallback: + return 0; + } + ++#define ATH11K_WLAN_PRIO_MAX 0x63 ++#define ATH11K_WLAN_PRIO_WEIGHT 0xff ++ ++int ath11k_mac_coex_config(struct ath11k *ar, struct ath11k_vif *arvif, ++ int coex, u32 wlan_prio_mask, u8 wlan_weight) ++{ ++ struct coex_config_arg coex_config; ++ int ret; ++ ++ if (ar->state != ATH11K_STATE_ON && ++ ar->state != ATH11K_STATE_RESTARTED) ++ return -ENETDOWN; ++ ++ if (coex == -1 || !(test_bit(ATH11K_FLAG_BTCOEX, &ar->ab->dev_flags) ^ coex)) ++ goto next; ++ ++ coex_config.vdev_id = arvif->vdev_id; ++ if (coex == 1) { ++ coex_config.config_type = WMI_COEX_CONFIG_PTA_INTERFACE; ++ coex_config.pta_num = ar->coex.pta_num; ++ coex_config.coex_mode = ar->coex.coex_mode; ++ coex_config.bt_txrx_time = ar->coex.bt_active_time_slot; ++ coex_config.bt_priority_time = ar->coex.bt_priority_time_slot; ++ coex_config.pta_algorithm = ar->coex.coex_algo_type; ++ coex_config.pta_priority = ar->coex.pta_priority; ++ ret = ath11k_send_coex_config_cmd(ar, &coex_config); ++ if (ret) { ++ ath11k_warn(ar->ab, ++ "failed to set coex config vdev_id %d ret %d\n", ++ coex_config.vdev_id, ret); ++ goto out; ++ } ++ } ++ ++ memset(&coex_config, 0, sizeof(struct coex_config_arg)); ++ coex_config.vdev_id = arvif->vdev_id; ++ coex_config.config_type = WMI_COEX_CONFIG_BTC_ENABLE; ++ coex_config.coex_enable = coex; ++ ret = ath11k_send_coex_config_cmd(ar, &coex_config); ++ if (ret) { ++ ath11k_warn(ar->ab, ++ "failed to set coex config vdev_id %d ret %d\n", ++ coex_config.vdev_id, ret); ++ goto out; ++ } ++ ++ if (coex) ++ set_bit(ATH11K_FLAG_BTCOEX, &ar->ab->dev_flags); ++ else ++ clear_bit(ATH11K_FLAG_BTCOEX, &ar->ab->dev_flags); ++ ++next: ++ if (!wlan_prio_mask) { ++ ret = 0; ++ goto out; ++ } ++ ++ if (!(test_bit(ATH11K_FLAG_BTCOEX, &ar->ab->dev_flags))) { ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ if (wlan_prio_mask > ATH11K_WLAN_PRIO_MAX || ++ wlan_weight > ATH11K_WLAN_PRIO_WEIGHT) { ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ memset(&coex_config, 0, sizeof(struct coex_config_arg)); ++ coex_config.vdev_id = arvif->vdev_id; ++ coex_config.config_type = WMI_COEX_CONFIG_WLAN_PKT_PRIORITY; ++ coex_config.wlan_pkt_type = wlan_prio_mask; ++ coex_config.wlan_pkt_weight = wlan_weight; ++ ret = ath11k_send_coex_config_cmd(ar, &coex_config); ++ if (ret) { ++ ath11k_warn(ar->ab, ++ "failed to set coex config vdev_id %d ret %d\n", ++ coex_config.vdev_id, ret); ++ goto out; ++ } ++ ++out: ++ return ret; ++} ++ + static const struct ieee80211_ops ath11k_ops = { + .tx = ath11k_mac_op_tx, + .wake_tx_queue = ieee80211_handle_wake_tx_queue, +@@ -9521,6 +9608,56 @@ static int ath11k_mac_setup_iface_combin + return 0; + } + ++static void ath11k_mac_fetch_coex_info(struct ath11k *ar) ++{ ++ struct ath11k_pdev_cap *cap = &ar->pdev->cap; ++ struct ath11k_base *ab = ar->ab; ++ struct device *dev = ab->dev; ++ ++ ar->coex.coex_support = false; ++ ++ if (!(cap->supported_bands & WMI_HOST_WLAN_2G_CAP)) ++ return; ++ ++ if (of_property_read_u32(dev->of_node, "qcom,pta-num", ++ &ar->coex.pta_num)) { ++ ath11k_err(ab, "No qcom,pta_num entry in dev-tree.\n"); ++ } ++ ++ if (of_property_read_u32(dev->of_node, "qcom,coex-mode", ++ &ar->coex.coex_mode)) { ++ ath11k_err(ab, "No qcom,coex_mode entry in dev-tree.\n"); ++ } ++ ++ if (of_property_read_u32(dev->of_node, "qcom,bt-active-time", ++ &ar->coex.bt_active_time_slot)) { ++ ath11k_err(ab, "No qcom,bt-active-time entry in dev-tree.\n"); ++ } ++ ++ if (of_property_read_u32(dev->of_node, "qcom,bt-priority-time", ++ &ar->coex.bt_priority_time_slot)) { ++ ath11k_err(ab, "No qcom,bt-priority-time entry in dev-tree.\n"); ++ } ++ ++ if (of_property_read_u32(dev->of_node, "qcom,coex-algo", ++ &ar->coex.coex_algo_type)) { ++ ath11k_err(ab, "No qcom,coex-algo entry in dev-tree.\n"); ++ } ++ ++ if (of_property_read_u32(dev->of_node, "qcom,pta-priority", ++ &ar->coex.pta_priority)) { ++ ath11k_err(ab, "No qcom,pta-priority entry in dev-tree.\n"); ++ } ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "coex pta_num %u coex_mode %u" ++ " bt_active_time_slot %u bt_priority_time_slot %u" ++ " coex_algorithm %u pta_priority %u\n", ar->coex.pta_num, ++ ar->coex.coex_mode, ar->coex.bt_active_time_slot, ++ ar->coex.bt_priority_time_slot, ar->coex.coex_algo_type, ++ ar->coex.pta_priority); ++ ar->coex.coex_support = true; ++} ++ + static const u8 ath11k_if_types_ext_capa[] = { + [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, + [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT, +@@ -9782,6 +9919,7 @@ static int __ath11k_mac_register(struct + ar->hw->wiphy->ema_max_profile_periodicity = TARGET_EMA_MAX_PROFILE_PERIOD; + + ath11k_reg_init(ar); ++ ath11k_vendor_register(ar); + + if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) { + ar->hw->netdev_features = NETIF_F_HW_CSUM; +@@ -9944,6 +10082,7 @@ int ath11k_mac_allocate(struct ath11k_ba + */ + ath11k_wmi_pdev_attach(ab, i); + ++ ath11k_mac_fetch_coex_info(ar); + ar->cfg_tx_chainmask = pdev->cap.tx_chain_mask; + ar->cfg_rx_chainmask = pdev->cap.rx_chain_mask; + ar->num_tx_chains = get_num_chains(pdev->cap.tx_chain_mask); +--- a/drivers/net/wireless/ath/ath11k/mac.h ++++ b/drivers/net/wireless/ath/ath11k/mac.h +@@ -150,8 +150,9 @@ void __ath11k_mac_scan_finish(struct ath + void ath11k_mac_scan_finish(struct ath11k *ar); + + struct ath11k_vif *ath11k_mac_get_arvif(struct ath11k *ar, u32 vdev_id); +-struct ath11k_vif *ath11k_mac_get_arvif_by_vdev_id(struct ath11k_base *ab, +- u32 vdev_id); ++struct ath11k_vif *ath11k_mac_get_arvif_by_vdev_id(struct ath11k_base *ab, u32 vdev_id); ++int ath11k_mac_coex_config(struct ath11k *ar, struct ath11k_vif *arvif, ++ int coex, u32 wlan_prio_mask, u8 wlan_weight); + u8 ath11k_mac_get_target_pdev_id(struct ath11k *ar); + u8 ath11k_mac_get_target_pdev_id_from_vif(struct ath11k_vif *arvif); + struct ath11k_vif *ath11k_mac_get_vif_up(struct ath11k_base *ab); +--- /dev/null ++++ b/drivers/net/wireless/ath/ath11k/vendor.c +@@ -0,0 +1,121 @@ ++// SPDX-License-Identifier: ISC ++/* ++ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. ++ */ ++ ++#include ++#include ++#include "core.h" ++#include "vendor.h" ++#include "debug.h" ++ ++static const struct nla_policy ++ath11k_vendor_btcoex_config_policy[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_MAX + 1] = { ++ [QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE] = { .type = NLA_U8 }, ++ [QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY] = { .type = NLA_NESTED }, ++}; ++ ++static const struct nla_policy ++ath11k_vendor_wlan_prio_policy[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MAX + 1] = { ++ [QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK] = { .type = NLA_U8 }, ++ [QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT] = { .type = NLA_U8 }, ++}; ++ ++static int ath11k_vendor_btcoex_configure(struct wiphy *wiphy, ++ 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_BTCOEX_CONFIG_MAX + 1]; ++ struct nlattr *tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MAX + 1]; ++ struct nlattr *wlan_prio; ++ enum qca_wlan_priority_type wlan_prio_mask = 0; ++ int ret, coex = -1, rem_conf; ++ u8 wlan_weight = 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_BTCOEX_CONFIG_MAX, data, data_len, ++ ath11k_vendor_btcoex_config_policy, NULL); ++ if (ret) { ++ ath11k_warn(ar->ab, "invalid BTCOEX config policy attribute\n"); ++ goto out; ++ } ++ ++ if (!tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE] && ++ !tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY]) { ++ ath11k_warn(ar->ab, "invalid BTCOEX config attributes\n"); ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ if (tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE]) { ++ coex = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE]); ++ ret = ath11k_mac_coex_config(ar, arvif, coex, wlan_prio_mask, wlan_weight); ++ if (ret) ++ goto out; ++ } ++ if (tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY]) { ++ nla_for_each_nested(wlan_prio, ++ tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY], ++ rem_conf) { ++ ret = ++ nla_parse_nested(tb_wlan_prio, QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MAX, ++ wlan_prio, ath11k_vendor_wlan_prio_policy, ++ NULL); ++ if (ret) ++ goto out; ++ wlan_prio_mask = ++ nla_get_u8(tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK]); ++ if (tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT]) ++ wlan_weight = ++ nla_get_u8(tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT]); ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, ++ "BTCOEX enable %u WLAN Priority %u wlan weight %u\n", ++ coex, wlan_prio_mask, wlan_weight); ++ ++ ret = ath11k_mac_coex_config(ar, arvif, coex, wlan_prio_mask, wlan_weight); ++ if (ret) ++ goto out; ++ } ++ } ++ ++out: ++ mutex_unlock(&ar->conf_mutex); ++ return ret; ++} ++ ++static struct wiphy_vendor_command ath11k_vendor_commands[] = { ++ { ++ .info.vendor_id = QCA_NL80211_VENDOR_ID, ++ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_BTCOEX_CONFIG, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | ++ WIPHY_VENDOR_CMD_NEED_RUNNING, ++ .doit = ath11k_vendor_btcoex_configure, ++ .policy = ath11k_vendor_btcoex_config_policy ++ } ++}; ++ ++int ath11k_vendor_register(struct ath11k *ar) ++{ ++ ar->hw->wiphy->vendor_commands = ath11k_vendor_commands; ++ ar->hw->wiphy->n_vendor_commands = ARRAY_SIZE(ath11k_vendor_commands); ++ ++ return 0; ++} +--- /dev/null ++++ b/drivers/net/wireless/ath/ath11k/vendor.h +@@ -0,0 +1,83 @@ ++/* SPDX-License-Identifier: ISC */ ++/* ++ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. ++ */ ++ ++#ifndef ATH11K_VENDOR_H ++#define ATH11K_VENDOR_H ++ ++#define QCA_NL80211_VENDOR_ID 0x001374 ++ ++enum qca_nl80211_vendor_subcmds { ++ /* 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 ++ * enum qca-vendor_attr_btcoex_config. ++ */ ++ QCA_NL80211_VENDOR_SUBCMD_BTCOEX_CONFIG = 182, ++}; ++ ++/* ++ * enum qca_wlan_priority_type - priority mask ++ * This enum defines priority mask that user can configure ++ * over BT traffic type which can be passed through ++ * QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY attribute. ++ * ++ * @QCA_WLAN_PRIORITY_BE: Bit mask for WLAN Best effort traffic ++ * @QCA_WLAN_PRIORITY_BK: Bit mask for WLAN Background traffic ++ * @QCA_WLAN_PRIORITY_VI: Bit mask for WLAN Video traffic ++ * @QCA_WLAN_PRIORITY_VO: Bit mask for WLAN Voice traffic ++ * @QCA_WLAN_PRIORITY_BEACON: Bit mask for WLAN BEACON frame ++ * @QCA_WLAN_PRIORITY_MGMT: Bit mask for WLAN Management frame ++*/ ++enum qca_wlan_priority_type { ++ QCA_WLAN_PRIORITY_BE = BIT(0), ++ QCA_WLAN_PRIORITY_BK = BIT(1), ++ QCA_WLAN_PRIORITY_VI = BIT(2), ++ QCA_WLAN_PRIORITY_VO = BIT(3), ++ QCA_WLAN_PRIORITY_BEACON = BIT(4), ++ QCA_WLAN_PRIORITY_MGMT = BIT(5), ++}; ++ ++/** ++ * enum qca_wlan_vendor_attr_wlan_prio - Used to configure ++ * WLAN priority mask and its respective weight value. ++ * @QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK - This is u8 attribute ++ * used to pass traffic type mask value see %qca_wlan_priority_type ++ * @QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT - This is u8 attribute ++ * accepts value between 0 and 255 and used to configure weight for ++ * traffic type mentioned in %QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK. ++ */ ++enum qca_wlan_vendor_attr_wlan_prio { ++ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_INVALID = 0, ++ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK = 1, ++ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT = 2, ++ ++ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_LAST, ++ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MAX = ++ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_LAST - 1, ++}; ++ ++ ++ ++/** ++ * enum qca_wlan_vendor_attr_btcoex_config - Used by the vendor command ++ * The use can enable/disable BTCOEX and configure WLAN priority for ++ * different traffic type over BT. ++ * QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE, enable/disable BTCOEX ++ * QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY, This is a nested ++ * attribute pass the attributes in %qca_wlan_vendor_attr_wlan_prio. ++ */ ++enum qca_wlan_vendor_attr_btcoex_config { ++ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_INVALID = 0, ++ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE = 1, ++ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY = 2, ++ ++ /* keep last */ ++ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_LAST, ++ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_MAX = ++ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_LAST - 1 ++}; ++ ++int ath11k_vendor_register(struct ath11k *ar); ++#endif /* QCA_VENDOR_H */ +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -1697,6 +1697,71 @@ int ath11k_wmi_vdev_set_param_cmd(struct + return ret; + } + ++static void ath11k_wmi_copy_coex_config(struct ath11k *ar, struct wmi_coex_config_cmd *cmd, ++ struct coex_config_arg *coex_config) ++{ ++ if (coex_config->config_type == WMI_COEX_CONFIG_BTC_ENABLE) { ++ cmd->coex_enable = coex_config->coex_enable; ++ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, ++ "WMI coex config type %u vdev id %d coex_enable %u\n", ++ coex_config->config_type, coex_config->vdev_id, ++ coex_config->coex_enable); ++ } ++ ++ if (coex_config->config_type == WMI_COEX_CONFIG_WLAN_PKT_PRIORITY) { ++ cmd->wlan_pkt_type = coex_config->wlan_pkt_type; ++ cmd->wlan_pkt_weight = coex_config->wlan_pkt_weight; ++ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, ++ "WMI coex config type %u vdev id %d wlan pkt type 0x%x wlan pkt weight %u\n", ++ coex_config->config_type, coex_config->vdev_id, ++ coex_config->wlan_pkt_type, coex_config->wlan_pkt_weight); ++ } ++ ++ if (coex_config->config_type == WMI_COEX_CONFIG_PTA_INTERFACE) { ++ cmd->pta_num = coex_config->pta_num; ++ cmd->coex_mode = coex_config->coex_mode; ++ cmd->bt_txrx_time = coex_config->bt_txrx_time; ++ cmd->bt_priority_time = coex_config->bt_priority_time; ++ cmd->pta_algorithm = coex_config->pta_algorithm; ++ cmd->pta_priority = coex_config->pta_priority; ++ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, ++ "WMI coex config type %u vdev id %d pta num %u coex mode %u bt_txrx_time %u bt_priority_time %u pta alogrithm %u pta priority %u\n", ++ coex_config->config_type, coex_config->vdev_id, ++ coex_config->pta_num, coex_config->coex_mode, ++ coex_config->bt_txrx_time, coex_config->bt_priority_time, ++ coex_config->pta_algorithm, coex_config->pta_priority); ++ } ++} ++ ++int ath11k_send_coex_config_cmd(struct ath11k *ar, ++ struct coex_config_arg *coex_config) ++{ ++ struct ath11k_pdev_wmi *wmi = ar->wmi; ++ struct wmi_coex_config_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_coex_config_cmd *)skb->data; ++ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_COEX_CONFIG_CMD) | ++ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); ++ ++ cmd->vdev_id = coex_config->vdev_id; ++ cmd->config_type = coex_config->config_type; ++ ath11k_wmi_copy_coex_config(ar, cmd, coex_config); ++ ++ ret = ath11k_wmi_cmd_send(wmi, skb, WMI_COEX_CONFIG_CMDID); ++ if (ret) { ++ ath11k_warn(ar->ab, "failed to send WMI_COEX_CONFIG_CMD cmd\n"); ++ dev_kfree_skb(skb); ++ } ++ ++ return ret; ++} ++ + int ath11k_wmi_send_stats_request_cmd(struct ath11k *ar, + struct stats_request_params *param) + { +--- a/drivers/net/wireless/ath/ath11k/wmi.h ++++ b/drivers/net/wireless/ath/ath11k/wmi.h +@@ -5303,6 +5303,79 @@ struct wmi_wmm_params_arg { + u8 no_ack; + }; + ++enum wmi_coex_config_type { ++ WMI_COEX_CONFIG_PAGE_P2P_TDM = 1, ++ WMI_COEX_CONFIG_PAGE_STA_TDM = 2, ++ WMI_COEX_CONFIG_PAGE_SAP_TDM = 3, ++ WMI_COEX_CONFIG_DURING_WLAN_CONN = 4, ++ WMI_COEX_CONFIG_BTC_ENABLE = 5, ++ WMI_COEX_CONFIG_COEX_DBG = 6, ++ WMI_COEX_CONFIG_PAGE_P2P_STA_TDM = 7, ++ WMI_COEX_CONFIG_INQUIRY_P2P_TDM = 8, ++ WMI_COEX_CONFIG_INQUIRY_STA_TDM = 9, ++ WMI_COEX_CONFIG_INQUIRY_SAP_TDM = 10, ++ WMI_COEX_CONFIG_INQUIRY_P2P_STA_TDM = 11, ++ WMI_COEX_CONFIG_TX_POWER = 12, ++ WMI_COEX_CONFIG_PTA_CONFIG = 13, ++ WMI_COEX_CONFIG_AP_TDM = 14, ++ WMI_COEX_CONFIG_WLAN_SCAN_PRIORITY = 15, ++ WMI_COEX_CONFIG_WLAN_PKT_PRIORITY = 16, ++ WMI_COEX_CONFIG_PTA_INTERFACE = 17, ++}; ++ ++struct coex_config_arg { ++ u32 vdev_id; ++ u32 config_type; ++ union { ++ struct { ++ u32 coex_enable; ++ }; ++ ++ struct { ++ u32 pta_num; ++ u32 coex_mode; ++ u32 bt_txrx_time; ++ u32 bt_priority_time; ++ u32 pta_algorithm; ++ u32 pta_priority; ++ }; ++ ++ struct { ++ u32 wlan_pkt_type; ++ u32 wlan_pkt_type_continued; ++ u32 wlan_pkt_weight; ++ u32 bt_pkt_weight; ++ }; ++ }; ++}; ++ ++struct wmi_coex_config_cmd { ++ u32 tlv_header; ++ u32 vdev_id; ++ u32 config_type; ++ union { ++ struct { ++ u32 coex_enable; ++ } __packed; ++ ++ struct { ++ u32 pta_num; ++ u32 coex_mode; ++ u32 bt_txrx_time; ++ u32 bt_priority_time; ++ u32 pta_algorithm; ++ u32 pta_priority; ++ } __packed; ++ ++ struct { ++ u32 wlan_pkt_type; ++ u32 wlan_pkt_type_continued; ++ u32 wlan_pkt_weight; ++ u32 bt_pkt_weight; ++ } __packed; ++ } __packed; ++} __packed; ++ + struct wmi_vdev_set_wmm_params_cmd { + u32 tlv_header; + u32 vdev_id; +@@ -6520,6 +6593,8 @@ int ath11k_wmi_pdev_non_srg_obss_color_e + u32 *bitmap); + int ath11k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(struct ath11k *ar, + u32 *bitmap); ++int ath11k_send_coex_config_cmd(struct ath11k *ar, ++ struct coex_config_arg *coex_config); + 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/903-002-ath11k-add-support-for-ext-vdev-in-NSS-for-AP_VLAN-vif-handling.patch b/package/kernel/mac80211/patches/ath11k_nss/903-002-ath11k-add-support-for-ext-vdev-in-NSS-for-AP_VLAN-vif-handling.patch new file mode 100644 index 00000000000000..6f5fffe596172b --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/903-002-ath11k-add-support-for-ext-vdev-in-NSS-for-AP_VLAN-vif-handling.patch @@ -0,0 +1,784 @@ +From 83c2a029a5300b2aaeaa9855011668b407d142c2 Mon Sep 17 00:00:00 2001 +From: Sathishkumar Muruganandam +Date: Fri, 20 Nov 2020 11:41:11 +0530 +Subject: [PATCH 2/3] ath11k: add support for ext vdev in NSS for AP_VLAN vif + handling + +- add ext vdev NSS API callbacks required for AP_VLAN vif +- invoke ieee80211_rx_nss_notify_4addr on WDS Rx path for 4addr frames until + ext vdev interface is UP +- do ext vdev down of all AP_VLAN vifs upon vdev down of associated AP vif + +Signed-off-by: Sathishkumar Muruganandam +--- + drivers/net/wireless/ath/ath11k/nss.c | 452 ++++++++++++++++++++++++++++++++-- + drivers/net/wireless/ath/ath11k/nss.h | 57 +++++ + 2 files changed, 495 insertions(+), 14 deletions(-) + +--- 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 + 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; ++ case NSS_WIFILI_PEER_4ADDR_EVENT_MSG: ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, "nss wifili peer 4addr event received %d response %d error %d\n", ++ msg_type, response, error); ++ break; + 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 + return 0; + } + +-static void ath11k_nss_wds_type_rx(struct ath11k *ar, u8* src_mac, u8 is_sa_valid, +- u8 addr4_valid, u16 peer_id) ++static void ath11k_nss_wds_type_rx(struct ath11k *ar, struct net_device *dev, ++ u8* src_mac, u8 is_sa_valid, u8 addr4_valid, ++ u16 peer_id, bool *drop) + { + 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 + if (!is_sa_valid) { + ath11k_peer_add_ast(ar, ta_peer, src_mac, + ATH11K_AST_TYPE_WDS); +- ath11k_nss_add_wds_peer(ar, ta_peer, +- src_mac, ATH11K_AST_TYPE_WDS); ++ if (!ta_peer->nss.ext_vdev_up) ++ ieee80211_rx_nss_notify_4addr(dev, ta_peer->addr); + } else { + if (!ast_entry) { + ath11k_peer_add_ast(ar, ta_peer, src_mac, + ATH11K_AST_TYPE_WDS); +- ath11k_nss_add_wds_peer(ar, ta_peer, src_mac, +- ATH11K_AST_TYPE_WDS); +- } else { ++ if (!ta_peer->nss.ext_vdev_up) ++ ieee80211_rx_nss_notify_4addr(dev, ta_peer->addr); ++ } else if (ast_entry->type == ATH11K_AST_TYPE_WDS) { + ath11k_peer_update_ast(ar, ta_peer, ast_entry); + ath11k_nss_update_wds_peer(ar, ta_peer, src_mac); + } + } ++ ++ if (!ta_peer->nss.ext_vdev_up) ++ *drop = true; + } + + spin_unlock_bh(&ab->base_lock); +@@ -678,7 +686,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, +- struct nss_wifi_vdev_wds_per_packet_metadata *wds_metadata) ++ struct nss_wifi_vdev_wds_per_packet_metadata *wds_metadata, ++ bool *drop) + { + struct ath11k *ar = arvif->ar; + struct ath11k_base *ab = ar->ab; +@@ -699,8 +708,8 @@ static void ath11k_nss_vdev_spl_receive_ + + switch (wds_type) { + case NSS_WIFI_VDEV_WDS_TYPE_RX: +- ath11k_nss_wds_type_rx(ar, src_mac, is_sa_valid, +- addr4_valid, peer_id); ++ ath11k_nss_wds_type_rx(ar, skb->dev, src_mac, is_sa_valid, ++ addr4_valid, peer_id, drop); + 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 + struct ieee80211_vif *vif; + struct ath11k_vif *arvif; + struct ath11k_base *ab; ++ bool drop = false; + bool eth_decap = false; + int data_offs = 0; + int ret = 0; +@@ -822,10 +832,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, +- wds_metadata); ++ wds_metadata, &drop); + } + +- ath11k_nss_deliver_rx(arvif->vif, skb, eth_decap, data_offs, napi); ++ if (!drop) ++ ath11k_nss_deliver_rx(arvif->vif, skb, eth_decap, data_offs, napi); + } + + static void +@@ -888,6 +899,68 @@ ath11k_nss_vdev_data_receive(struct net_ + ath11k_nss_deliver_rx(arvif->vif, skb, eth_decap, data_offs, napi); + } + ++static void ++ath11k_nss_ext_vdev_special_data_receive(struct net_device *dev, ++ struct sk_buff *skb, ++ __attribute__((unused)) struct napi_struct *napi) ++{ ++ dev_kfree_skb_any(skb); ++} ++ ++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) { ++ 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; ++ if (!arvif) { ++ dev_kfree_skb_any(skb); ++ return; ++ } ++ ++ 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); ++} ++ + 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 + ath11k_nss_tx_encap_nwifi(skb); + + send: +- ath11k_dbg_dump(ar->ab, ATH11K_DBG_DP_TX, "", "nss tx msdu: ", +- skb->data, skb->len); +- +- status = nss_wifi_vdev_tx_buf(arvif->ar->nss.ctx, skb, arvif->nss.if_num); ++ 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) ++ 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); + + 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 + struct nss_wifi_vdev_msg *vdev_msg = NULL; + struct nss_wifi_vdev_enable_msg *vdev_en; + struct ath11k *ar = arvif->ar; ++ struct ath11k_vif *ap_vlan_arvif, *tmp; + nss_tx_status_t status; + int ret = 0; + +@@ -1285,6 +1365,12 @@ int ath11k_nss_vdev_up(struct ath11k_vif + } + + ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss vdev up tx msg success\n"); ++ ++ if (arvif->vif->type == NL80211_IFTYPE_AP) ++ list_for_each_entry_safe(ap_vlan_arvif, tmp, &arvif->ap_vlan_arvifs, ++ list) ++ if (ap_vlan_arvif->nss.added) ++ ath11k_nss_ext_vdev_up(ap_vlan_arvif); + free: + kfree(vdev_msg); + return ret; +@@ -1294,6 +1380,7 @@ int ath11k_nss_vdev_down(struct ath11k_v + { + struct nss_wifi_vdev_msg *vdev_msg = NULL; + struct ath11k *ar = arvif->ar; ++ struct ath11k_vif *ap_vlan_arvif, *tmp; + nss_tx_status_t status; + int ret = 0; + +@@ -1321,11 +1408,362 @@ int ath11k_nss_vdev_down(struct ath11k_v + } + + ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss vdev down tx msg success\n"); ++ ++ if (arvif->vif->type == NL80211_IFTYPE_AP) ++ list_for_each_entry_safe(ap_vlan_arvif, tmp, &arvif->ap_vlan_arvifs, ++ list) ++ ath11k_nss_ext_vdev_down(ap_vlan_arvif); + free: + kfree(vdev_msg); + return ret; + } + ++int ath11k_nss_ext_vdev_cfg_wds_peer(struct ath11k_vif *arvif, ++ u8 *wds_addr, u32 wds_peer_id) ++{ ++ struct ath11k *ar = arvif->ar; ++ struct nss_wifi_ext_vdev_msg *ext_vdev_msg = NULL; ++ struct nss_wifi_ext_vdev_wds_msg *cfg_wds_msg = NULL; ++ nss_tx_status_t status; ++ int ret; ++ ++ if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN) ++ return -EINVAL; ++ ++ ext_vdev_msg = kzalloc(sizeof(struct nss_wifi_ext_vdev_msg), GFP_ATOMIC); ++ if (!ext_vdev_msg) ++ return -ENOMEM; ++ ++ 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); ++ ++ nss_wifi_ext_vdev_msg_init(ext_vdev_msg, arvif->nss.if_num, ++ NSS_WIFI_EXT_VDEV_MSG_CONFIGURE_WDS, ++ sizeof(struct nss_wifi_ext_vdev_wds_msg), ++ NULL, arvif); ++ ++ status = nss_wifi_ext_vdev_tx_msg_sync(arvif->nss.ctx, ext_vdev_msg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "failed to configure wds peer nss_err:%d\n", ++ status); ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ ret = 0; ++free: ++ kfree(ext_vdev_msg); ++ ++ return ret; ++} ++ ++int ath11k_nss_ext_vdev_wds_4addr_allow(struct ath11k_vif *arvif, ++ u32 wds_peer_id) ++{ ++ struct ath11k *ar = arvif->ar; ++ struct nss_wifili_peer_wds_4addr_allow_msg *cfg_4addr_msg = NULL; ++ nss_wifili_msg_callback_t msg_cb; ++ struct nss_wifili_msg *wlmsg; ++ nss_tx_status_t status; ++ ++ if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN) ++ return -EINVAL; ++ ++ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); ++ if (!wlmsg) ++ return -ENOMEM; ++ ++ cfg_4addr_msg = &wlmsg->msg.wpswm; ++ cfg_4addr_msg->peer_id = wds_peer_id; ++ cfg_4addr_msg->if_num = arvif->nss.if_num; ++ cfg_4addr_msg->enable = true; ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ar->ab->nss.if_num, ++ NSS_WIFILI_PEER_4ADDR_EVENT_MSG, ++ sizeof(struct nss_wifili_peer_wds_4addr_allow_msg), ++ msg_cb, NULL); ++ ++ status = nss_wifili_tx_msg(ar->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "nss wds 4addr allow if_num %d, peer_id %d cfg fail: %d\n", ++ arvif->nss.if_num, wds_peer_id, status); ++ goto free; ++ } ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS_WDS, "nss wds 4addr allow if_num %d, peer_id %d cfg complete\n", ++ arvif->nss.if_num, wds_peer_id); ++free: ++ kfree(wlmsg); ++ return status; ++} ++ ++int ath11k_nss_ext_vdev_configure(struct ath11k_vif *arvif) ++{ ++ struct ath11k *ar = arvif->ar; ++ struct ath11k_vif *ap_vif = arvif->nss.ap_vif; ++ struct nss_wifi_ext_vdev_msg *ext_vdev_msg = NULL; ++ struct nss_wifi_ext_vdev_configure_if_msg *ext_vdev_cfg = NULL; ++ nss_tx_status_t status; ++ int ret; ++ ++ if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN) ++ return -EINVAL; ++ ++ ext_vdev_msg = kzalloc(sizeof(struct nss_wifi_ext_vdev_msg), GFP_ATOMIC); ++ if (!ext_vdev_msg) ++ return -ENOMEM; ++ ++ ext_vdev_cfg = &ext_vdev_msg->msg.cmsg; ++ ++ ext_vdev_cfg->radio_ifnum = ar->nss.if_num; ++ ext_vdev_cfg->pvap_ifnum = ap_vif->nss.if_num; ++ ++ ether_addr_copy(ext_vdev_cfg->mac_addr, arvif->vif->addr); ++ ++ nss_wifi_ext_vdev_msg_init(ext_vdev_msg, arvif->nss.if_num, ++ NSS_WIFI_EXT_VDEV_MSG_CONFIGURE_IF, ++ sizeof(struct nss_wifi_ext_vdev_configure_if_msg), ++ NULL, arvif); ++ ++ status = nss_wifi_ext_vdev_tx_msg_sync(arvif->ar->nss.ctx, ext_vdev_msg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "failed to configure nss ext vdev nss_err:%d\n", ++ status); ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ ret = 0; ++free: ++ kfree(ext_vdev_msg); ++ ++ return ret; ++} ++ ++void ath11k_nss_ext_vdev_unregister(struct ath11k_vif *arvif) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ ++ if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN) ++ return; ++ ++ nss_wifi_ext_vdev_unregister_if(arvif->nss.if_num); ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, "unregistered nss vdev %d \n", ++ arvif->nss.if_num); ++} ++ ++static int ath11k_nss_ext_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; ++ enum nss_dynamic_interface_type di_type; ++ u32 features = 0; ++ ++ if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN || arvif->nss.ctx) ++ return -EINVAL; ++ ++ di_type = NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_WDS; ++ ++ 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, ++ NULL, netdev, features, ++ arvif); ++ ++ if (!arvif->nss.ctx) { ++ ath11k_warn(ab, "failed to register nss vdev if_num %d nss_err:%d\n", ++ arvif->nss.if_num, status); ++ return -EINVAL; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, "registered nss ext vdev if_num %d\n", ++ arvif->nss.if_num); ++ return 0; ++} ++ ++static void ath11k_nss_ext_vdev_free(struct ath11k_vif *arvif) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ nss_tx_status_t status; ++ ++ if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN) ++ return; ++ ++ status = nss_dynamic_interface_dealloc_node( ++ arvif->nss.if_num, ++ NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_WDS); ++ if (status != NSS_TX_SUCCESS) ++ ath11k_warn(ab, "failed to free nss ext vdev err:%d\n", ++ status); ++ else ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, ++ "nss ext vdev interface deallocated\n"); ++} ++ ++static int ath11k_nss_ext_vdev_alloc(struct ath11k_vif *arvif) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ enum nss_dynamic_interface_type di_type; ++ int if_num; ++ ++ di_type = NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_WDS; ++ ++ if_num = nss_dynamic_interface_alloc_node(di_type); ++ if (if_num < 0) { ++ ath11k_warn(ab, "failed to allocate nss ext vdev\n"); ++ return -EINVAL; ++ } ++ ++ arvif->nss.if_num = if_num; ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, ++ "nss ext vdev interface %pM allocated if_num %d\n", ++ arvif->vif->addr, if_num); ++ ++ return 0; ++} ++ ++int ath11k_nss_ext_vdev_create(struct ath11k_vif *arvif) ++{ ++ struct ath11k *ar = arvif->ar; ++ struct ath11k_base *ab = ar->ab; ++ struct wireless_dev *wdev; ++ int ret; ++ ++ if (!ab->nss.enabled) ++ return 0; ++ ++ if (arvif->nss.created) ++ return 0; ++ ++ wdev = ieee80211_vif_to_wdev_relaxed(arvif->vif); ++ if (!wdev) { ++ ath11k_warn(ab, "ath11k_nss: ext wdev is null\n"); ++ return -EINVAL; ++ } ++ ++ if (!wdev->netdev) { ++ ath11k_warn(ab, "ath11k_nss: ext netdev is null\n"); ++ return -EINVAL; ++ } ++ ++ ret = ath11k_nss_ext_vdev_alloc(arvif); ++ if (ret) ++ return ret; ++ ++ ret = ath11k_nss_ext_vdev_register(arvif, wdev->netdev); ++ if (ret) ++ goto free_ext_vdev; ++ ++ arvif->nss.created = true; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, ++ "nss ext vdev interface created ctx %pK, ifnum %d\n", ++ arvif->nss.ctx, arvif->nss.if_num); ++ ++ return ret; ++ ++free_ext_vdev: ++ ath11k_nss_ext_vdev_free(arvif); ++ ++ return ret; ++} ++ ++void ath11k_nss_ext_vdev_delete(struct ath11k_vif *arvif) ++{ ++ if (!arvif->ar->ab->nss.enabled) ++ return; ++ ++ if (!arvif->nss.created) ++ return; ++ ++ ath11k_dbg(arvif->ar->ab, ATH11K_DBG_NSS_WDS, ++ "nss ext vdev interface delete ctx %pK, ifnum %d\n", ++ arvif->nss.ctx, arvif->nss.if_num); ++ ++ ath11k_nss_ext_vdev_unregister(arvif); ++ ++ ath11k_nss_ext_vdev_free(arvif); ++ ++ arvif->nss.created = false; ++} ++ ++int ath11k_nss_ext_vdev_up(struct ath11k_vif *arvif) ++{ ++ struct nss_wifi_ext_vdev_msg *ext_vdev_msg = NULL; ++ struct ath11k *ar = arvif->ar; ++ nss_tx_status_t status; ++ int ret = 0; ++ ++ if (!ar->ab->nss.enabled) ++ return 0; ++ ++ if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN) ++ return -EINVAL; ++ ++ if (arvif->nss.ext_vdev_up) ++ return 0; ++ ++ ext_vdev_msg = kzalloc(sizeof(struct nss_wifi_vdev_msg), GFP_ATOMIC); ++ if (!ext_vdev_msg) ++ return -ENOMEM; ++ ++ nss_wifi_ext_vdev_msg_init(ext_vdev_msg, arvif->nss.if_num, NSS_IF_OPEN, ++ sizeof(struct nss_if_open), NULL, arvif); ++ ++ status = nss_wifi_ext_vdev_tx_msg_sync(arvif->nss.ctx, ext_vdev_msg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "nss ext vdev up tx msg error %d\n", status); ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS_WDS, "nss ext vdev up tx msg success\n"); ++ arvif->nss.ext_vdev_up = true; ++free: ++ kfree(ext_vdev_msg); ++ return ret; ++} ++ ++int ath11k_nss_ext_vdev_down(struct ath11k_vif *arvif) ++{ ++ struct nss_wifi_ext_vdev_msg *ext_vdev_msg = NULL; ++ struct ath11k *ar = arvif->ar; ++ nss_tx_status_t status; ++ int ret = 0; ++ ++ if (!ar->ab->nss.enabled) ++ return 0; ++ ++ if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN) ++ return -EINVAL; ++ ++ ext_vdev_msg = kzalloc(sizeof(struct nss_wifi_ext_vdev_msg), GFP_ATOMIC); ++ if (!ext_vdev_msg) ++ return -ENOMEM; ++ ++ nss_wifi_ext_vdev_msg_init(ext_vdev_msg, arvif->nss.if_num, NSS_IF_CLOSE, ++ sizeof(struct nss_if_close), NULL, arvif); ++ ++ status = nss_wifi_ext_vdev_tx_msg_sync(arvif->nss.ctx, ext_vdev_msg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "nss ext vdev down tx msg error %d\n", status); ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS_WDS, "nss ext vdev down tx msg success\n"); ++ ++ arvif->nss.ext_vdev_up = false; ++free: ++ kfree(ext_vdev_msg); ++ return ret; ++} ++ + /*----------------------------Peer Setup/Config -----------------------------*/ + + int ath11k_nss_set_peer_sec_type(struct ath11k *ar, +@@ -1419,22 +1857,22 @@ free: + return status; + } + +-void ath11k_nss_update_sta_stats(struct station_info *sinfo, +- struct ieee80211_sta *sta, +- struct ath11k_sta *arsta) ++void ath11k_nss_update_sta_stats(struct ath11k_vif *arvif, ++ struct station_info *sinfo, ++ struct ieee80211_sta *sta) + { + struct sta_info *stainfo; + struct ath11k_peer *peer; +- struct ath11k *ar = arsta->arvif->ar; ++ struct ath11k *ar = arvif->ar; + struct ath11k_base *ab = ar->ab; + +- if (!ab->nss.enabled) ++ if (!ab->nss.stats_enabled) + return; + + spin_lock_bh(&ab->base_lock); +- peer = ath11k_peer_find_by_addr(arsta->arvif->ar->ab, sta->addr); ++ peer = ath11k_peer_find_by_addr(ab, sta->addr); + if (!peer) { +- ath11k_dbg(ab, ATH11K_DBG_NSS, "unable to find peer %pM\n", ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "sta stats: unable to find peer %pM\n", + sta->addr); + goto exit; + } +@@ -1506,13 +1944,13 @@ void ath11k_nss_update_sta_rxrate(struct + struct ath11k_peer *peer, + struct hal_rx_user_status *user_stats) + { +- struct ath11k_sta *arsta = (struct ath11k_sta *)peer->sta->drv_priv; + u16 ath11k_hal_rx_legacy_rates[] = + { 10, 20, 55, 60, 90, 110, 120, 180, 240, 360, 480, 540 }; + u16 rate = 0; + u32 preamble_type; + u8 mcs, nss; +- struct ath11k *ar = arsta->arvif->ar; ++ struct ath11k_vif *arvif = ath11k_vif_to_arvif(peer->vif); ++ struct ath11k *ar = arvif->ar; + struct ath11k_base *ab = ar->ab; + + if (!ab->nss.enabled) +@@ -1816,8 +2254,8 @@ int ath11k_nss_add_wds_peer(struct ath11 + } + + ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, +- "nss add wds peer success peer mac:%pM dest mac:%pM peer_id:%d\n", +- wds_peer_msg->peer_mac, wds_peer_msg->dest_mac, wds_peer_msg->peer_id); ++ "nss add wds peer success pdev:%d peer mac:%pM dest mac:%pM peer_id:%d\n", ++ wds_peer_msg->pdev_id, wds_peer_msg->peer_mac, wds_peer_msg->dest_mac, wds_peer_msg->peer_id); + + msg_free: + kfree(wlmsg); +@@ -1862,8 +2300,8 @@ int ath11k_nss_update_wds_peer(struct at + } + + ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, +- "nss update wds peer success peer mac:%pM dest mac:%pM peer_id:%d\n", +- wds_peer_msg->peer_mac, wds_peer_msg->dest_mac, wds_peer_msg->peer_id); ++ "nss update wds peer success pdev:%d peer mac:%pM dest mac:%pM peer_id:%d\n", ++ wds_peer_msg->pdev_id, wds_peer_msg->peer_mac, wds_peer_msg->dest_mac, wds_peer_msg->peer_id); + + msg_free: + 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 { + struct ath11k_nss_peer { + uint32_t *vaddr; + dma_addr_t paddr; ++ bool ext_vdev_up; + struct peer_stats *nss_stats; + struct completion complete; + }; +@@ -168,6 +169,16 @@ struct arvif_nss { + int encap; + /* Keep the copy of decap type for nss */ + int decap; ++ /* AP_VLAN vif context obtained on ext vdev register */ ++ void* ctx; ++ /* Parent AP vif stored in case of AP_VLAN vif */ ++ struct ath11k_vif *ap_vif; ++ /* Flag to notify if vlan arvif object is added to arvif list*/ ++ bool added; ++ /* Flag to notify if ext vdev is up/down */ ++ bool ext_vdev_up; ++ /* WDS cfg should be done only once for ext vdev */ ++ bool wds_cfg_done; + bool created; + }; + +@@ -223,11 +234,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); ++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, ++ u32 wds_peer_id); ++int ath11k_nss_ext_vdev_create(struct ath11k_vif *arvif); ++int ath11k_nss_ext_vdev_configure(struct ath11k_vif *arvif); ++void ath11k_nss_ext_vdev_unregister(struct ath11k_vif *arvif); ++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); + 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, +- struct ieee80211_sta *sta, +- struct ath11k_sta *arsta); ++void ath11k_nss_update_sta_stats(struct ath11k_vif *arvif, ++ struct station_info *sinfo, ++ struct ieee80211_sta *sta); + 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 + { + } + +-static inline void ath11k_nss_update_sta_stats(struct station_info *sinfo, +- struct ieee80211_sta *sta, +- struct ath11k_sta *arsta) ++static inline void ath11k_nss_update_sta_stats(struct ath11k_vif *arvif, ++ struct station_info *sinfo, ++ struct ieee80211_sta *sta) + { + return; + } +@@ -319,6 +340,43 @@ static inline int ath11k_nss_peer_create + return 0; + } + ++static inline int ath11k_nss_ext_vdev_cfg_wds_peer(struct ath11k_vif *arvif, ++ u8 *wds_addr, u32 wds_peer_id) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_ext_vdev_wds_4addr_allow(struct ath11k_vif *arvif, ++ u32 wds_peer_id) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_ext_vdev_create(struct ath11k_vif *arvif) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_ext_vdev_configure(struct ath11k_vif *arvif) ++{ ++ return 0; ++} ++ ++static inline void ath11k_nss_ext_vdev_unregister(struct ath11k_vif *arvif) ++{ ++ return; ++} ++ ++static inline int ath11k_nss_ext_vdev_up(struct ath11k_vif *arvif) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_ext_vdev_down(struct ath11k_vif *arvif) ++{ ++ return 0; ++} ++ + static inline void ath11k_nss_peer_stats_enable(struct ath11k *ar) + { + return; +@@ -340,6 +398,11 @@ static inline int ath11k_nss_setup(struc + return 0; + } + ++static inline void ath11k_nss_ext_vdev_delete(struct ath11k_vif *arvif) ++{ ++ return; ++} ++ + static inline int ath11k_nss_teardown(struct ath11k_base *ab) + { + 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/ath11k_nss/903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch new file mode 100644 index 00000000000000..86714fea844e81 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch @@ -0,0 +1,575 @@ +From 730f568af3fac2f31467ea0ff374ea442ddc379f Mon Sep 17 00:00:00 2001 +From: Sathishkumar Muruganandam +Date: Fri, 20 Nov 2020 11:57:36 +0530 +Subject: [PATCH 3/3] ath11k: add AP_VLAN vif support for WDS offload in NSS + offload + +- AP_VLAN vif support is required for WDS offload to interop with mac80211 + based 4addr STA and also for multicast-to-unicast conversion of 3addr + multicast to 4addr frames for each associated 4addr STA. + +- For each associated 4addr STA, corresponding AP_VLAN vif having same MAC + address as AP vif is created from hostapd upon 4addr rx_notify from NSS RX. + +- AP_VLAN vif support is added to add/remove interface mac80211 callbacks only + for NSS ext vdev handling and vdev_id, FW vdev operations are not needed. + +- mac80211 advertises AP_VLAN vif for sta_use_4addr drv callback in case of + NSS offload. Extending ath11k_mac_op_sta_use_4addr to invoke ext vdev NSS + APIs required for AP WDS handling. + +- Maintain AP_VLAN vif(s) list on corresponding AP vif and vice versa required + for ext vdev operations (VDEV_DOWN, DELETE, CONFIGURE_IF). + +- NSS require ENABLE_NAWDS and WDS_BACKHAUL to be configured for AP_VLAN + support via ext vdev. + +Signed-off-by: Sathishkumar Muruganandam +--- + drivers/net/wireless/ath/ath11k/core.h | 1 + + drivers/net/wireless/ath/ath11k/mac.c | 156 +++++++++++++++++++++++++++++++-- + drivers/net/wireless/ath/ath11k/wmi.h | 2 + + 3 files changed, 154 insertions(+), 5 deletions(-) + +--- 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 + struct arvif_nss nss; +-#endif ++ struct list_head ap_vlan_arvifs; + }; + + struct ath11k_vif_iter { +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -4739,6 +4739,11 @@ static void ath11k_sta_rc_update_wk(stru + arvif = arsta->arvif; + ar = arvif->ar; + ++ if (ar->ab->nss.enabled && ++ arsta->arvif->vif->type == NL80211_IFTYPE_AP_VLAN && ++ arsta->use_4addr_set) ++ arvif = arvif->nss.ap_vif; ++ + if (WARN_ON(ath11k_mac_vif_chan(arvif->vif, &def))) + return; + +@@ -4910,17 +4915,28 @@ err_rc_bw_changed: + static void ath11k_sta_set_4addr_wk(struct work_struct *wk) + { + struct ath11k *ar; +- struct ath11k_vif *arvif; ++ struct ath11k_vif *arvif, *ap_vlan_arvif = NULL; ++ struct ieee80211_vif *vif; + struct ath11k_sta *arsta; + struct ieee80211_sta *sta; ++ struct ath11k_base *ab; ++ struct ath11k_peer *wds_peer; ++ u8 wds_addr[ETH_ALEN]; ++ u32 wds_peer_id; + int ret = 0; + + arsta = container_of(wk, struct ath11k_sta, set_4addr_wk); + sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv); + arvif = arsta->arvif; + ar = arvif->ar; ++ ab = ar->ab; + +- ath11k_dbg(ar->ab, ATH11K_DBG_MAC, ++ if (ab->nss.enabled && arvif->vif->type == NL80211_IFTYPE_AP_VLAN) { ++ ap_vlan_arvif = arsta->arvif; ++ arvif = ap_vlan_arvif->nss.ap_vif; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_MAC, + "setting USE_4ADDR for peer %pM\n", sta->addr); + + ret = ath11k_wmi_set_peer_param(ar, sta->addr, +@@ -4928,8 +4944,93 @@ static void ath11k_sta_set_4addr_wk(stru + WMI_PEER_USE_4ADDR, 1); + + if (ret) +- ath11k_warn(ar->ab, "failed to set peer %pM 4addr capability: %d\n", ++ ath11k_warn(ab, "failed to set 4addr for STA %pM: %d\n", + sta->addr, ret); ++ ++ if (!ab->nss.enabled || !ap_vlan_arvif) ++ return; ++ ++ vif = ap_vlan_arvif->vif; ++ ++ spin_lock_bh(&ab->base_lock); ++ wds_peer = ath11k_peer_find_by_addr(ab, sta->addr); ++ if (!wds_peer) { ++ spin_unlock_bh(&ab->base_lock); ++ ath11k_warn(ab, "mac sta use 4addr failed to find peer %pM\n", ++ sta->addr); ++ return; ++ } ++ ++ wds_peer_id = wds_peer->peer_id; ++ ether_addr_copy(wds_addr, wds_peer->addr); ++ spin_unlock_bh(&ab->base_lock); ++ ++ /* skip NSS ext vdev registration if already done */ ++ if (ap_vlan_arvif->nss.wds_cfg_done) ++ goto skip_nss_ext; ++ ++ ret = ath11k_nss_ext_vdev_configure(ap_vlan_arvif); ++ if (ret) { ++ ath11k_warn(ab, "failed to nss cfg ext vdev %pM: %d\n", ++ vif->addr, ret); ++ goto ext_vdev_delete; ++ } ++ ++ ap_vlan_arvif->nss.wds_cfg_done = true; ++ ++skip_nss_ext: ++ ++ ret = ath11k_nss_ext_vdev_cfg_wds_peer(ap_vlan_arvif, ++ wds_addr, wds_peer_id); ++ if (ret) { ++ ath11k_warn(ab, "failed to nss cfg_wds_peer %pM on %pM: %d\n", ++ sta->addr, vif->addr, ret); ++ goto ext_vdev_delete; ++ } ++ ++ ret = ath11k_nss_ext_vdev_wds_4addr_allow(ap_vlan_arvif, ++ wds_peer_id); ++ if (ret) { ++ ath11k_warn(ab, "failed to nss 4addr allow %pM: %d\n", ++ vif->addr, ret); ++ goto ext_vdev_delete; ++ } ++ ++ ret = ath11k_nss_ext_vdev_up(ap_vlan_arvif); ++ if (ret) { ++ ath11k_warn(ab, "failed to nss ext vdev up %pM: %d\n", ++ vif->addr, ret); ++ goto ext_vdev_delete; ++ } ++ ++ spin_lock_bh(&ab->base_lock); ++ wds_peer->nss.ext_vdev_up = true; ++ wds_peer->nss.ext_vif = vif; ++ spin_unlock_bh(&ab->base_lock); ++ ++ /* NAWDS and CFG_WDS_BACKHAUL configs should be done on corresponding ++ * AP vif of the AP_VLAN vif ++ */ ++ ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, ++ WMI_VDEV_PARAM_AP_ENABLE_NAWDS, ++ MIN_IDLE_INACTIVE_TIME_SECS); ++ if (ret) { ++ ath11k_warn(ab, "failed to set vdev %i nawds parameters: %d\n", ++ arvif->vdev_id, ret); ++ goto ext_vdev_down; ++ } ++ ++ return; ++ ++ext_vdev_down: ++ ath11k_nss_ext_vdev_down(ap_vlan_arvif); ++ext_vdev_delete: ++ ath11k_nss_ext_vdev_delete(ap_vlan_arvif); ++ ++ spin_lock_bh(&ar->data_lock); ++ list_del(&ap_vlan_arvif->list); ++ spin_unlock_bh(&ar->data_lock); ++ ap_vlan_arvif->nss.added = false; + } + + static int ath11k_mac_inc_num_stations(struct ath11k_vif *arvif, +@@ -5278,9 +5379,32 @@ static void ath11k_mac_op_sta_set_4addr( + struct ieee80211_sta *sta, bool enabled) + { + struct ath11k *ar = hw->priv; ++ struct ath11k_vif *arvif = (void *)vif->drv_priv; + struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); ++ struct ath11k_vif *ap_arvif = NULL; + + if (enabled && !arsta->use_4addr_set) { ++ if (ar->ab->nss.enabled && vif->type == NL80211_IFTYPE_AP_VLAN) { ++ /* 4addr STA is initially associated to AP vif, change ++ * it to AP_VLAN vif and add AP_VLAN vif to AP vifs list ++ */ ++ ap_arvif = arsta->arvif; ++ arvif->nss.ap_vif = ap_arvif; ++ ++ /* Check if the vlan arvif object was already present in the ++ * list. We can receive this path multiple times for the same ++ * vlan vif for different sta objects ++ */ ++ if (!arvif->nss.added) { ++ spin_lock_bh(&ar->data_lock); ++ list_add(&arvif->list, &ap_arvif->ap_vlan_arvifs); ++ spin_unlock_bh(&ar->data_lock); ++ arvif->nss.added = true; ++ } ++ ++ arsta->arvif = arvif; ++ } ++ + 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 + u32 param_id, param_value; + int ret; + ++ if (ab->nss.enabled && vif->type == NL80211_IFTYPE_AP_VLAN) ++ return 0; ++ + 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 + goto err; + } + +- if (ar->num_created_vdevs > (TARGET_NUM_VDEVS(ab) - 1)) { ++ if (vif->type != NL80211_IFTYPE_AP_VLAN && ++ ar->num_created_vdevs > (TARGET_NUM_VDEVS(ab) - 1)) { + 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 + arvif->vif = vif; + + INIT_LIST_HEAD(&arvif->list); ++ ++ if ((vif->type == NL80211_IFTYPE_AP_VLAN || ++ vif->type == NL80211_IFTYPE_STATION) && ab->nss.enabled) { ++ if (ath11k_frame_mode == ATH11K_HW_TXRX_ETHERNET && ++ ieee80211_set_hw_80211_encap(vif, true)) { ++ vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR; ++ arvif->nss.encap = ATH11K_HW_TXRX_ETHERNET; ++ arvif->nss.decap = ATH11K_HW_TXRX_ETHERNET; ++ } ++ ++ if (vif->type == NL80211_IFTYPE_AP_VLAN) { ++ ret = ath11k_nss_ext_vdev_create(arvif); ++ if (ret) { ++ ath11k_warn(ab, "failed to create ext vdev %pM: %d\n", ++ vif->addr, ret); ++ goto err; ++ } ++ mutex_unlock(&ar->conf_mutex); ++ return ret; ++ } ++ } ++ + 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 + fallthrough; + case NL80211_IFTYPE_AP: + arvif->vdev_type = WMI_VDEV_TYPE_AP; ++ INIT_LIST_HEAD(&arvif->ap_vlan_arvifs); + break; + case NL80211_IFTYPE_MONITOR: + arvif->vdev_type = WMI_VDEV_TYPE_MONITOR; +@@ -7164,13 +7315,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; ++ struct ath11k_vif *ap_vlan_arvif, *tmp; + int ret; + int i; + +- cancel_delayed_work_sync(&arvif->connection_loss_work); +- + mutex_lock(&ar->conf_mutex); + ++ if (vif->type == NL80211_IFTYPE_AP_VLAN) { ++ ath11k_nss_ext_vdev_delete(arvif); ++ ++ /* In case the vlan vif never got added into the ap vlan arvifs ++ * list, avoid removal here ++ */ ++ if (!arvif->nss.added) ++ goto unlock; ++ ++ spin_lock_bh(&ar->data_lock); ++ list_del(&arvif->list); ++ spin_unlock_bh(&ar->data_lock); ++ ++ goto unlock; ++ } ++ ++ cancel_delayed_work_sync(&arvif->connection_loss_work); ++ + 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 + if (ret) + ath11k_warn(ab, "failed to submit AP self-peer removal on vdev %d: %d\n", + arvif->vdev_id, ret); ++ ++ list_for_each_entry_safe(ap_vlan_arvif, tmp, &arvif->ap_vlan_arvifs, ++ list) { ++ ath11k_nss_ext_vdev_delete(ap_vlan_arvif); ++ spin_lock_bh(&ar->data_lock); ++ list_del(&ap_vlan_arvif->list); ++ spin_unlock_bh(&ar->data_lock); ++ } + } + + ret = ath11k_mac_vdev_delete(ar, arvif); +@@ -7230,8 +7406,7 @@ err_vdev_del: + + ath11k_debugfs_remove_interface(arvif); + +- /* TODO: recal traffic pause state based on the available vdevs */ +- ++unlock: + mutex_unlock(&ar->conf_mutex); + } + +@@ -7291,16 +7466,17 @@ static int ath11k_mac_op_ampdu_action(st + struct ieee80211_ampdu_params *params) + { + struct ath11k *ar = hw->priv; ++ struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); + int ret = -EINVAL; + + mutex_lock(&ar->conf_mutex); + + switch (params->action) { + case IEEE80211_AMPDU_RX_START: +- ret = ath11k_dp_rx_ampdu_start(ar, params); ++ ret = ath11k_dp_rx_ampdu_start(arvif, params); + break; + case IEEE80211_AMPDU_RX_STOP: +- ret = ath11k_dp_rx_ampdu_stop(ar, params); ++ ret = ath11k_dp_rx_ampdu_stop(arvif, params); + break; + case IEEE80211_AMPDU_TX_START: + case IEEE80211_AMPDU_TX_STOP_CONT: +@@ -8823,6 +8999,7 @@ static void ath11k_mac_op_sta_statistics + { + struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); + struct ath11k *ar = arsta->arvif->ar; ++ struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); + 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 + ATH11K_DEFAULT_NOISE_FLOOR; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); + +- ath11k_nss_update_sta_stats(sinfo, sta, arsta); ++ if (arvif->ar->ab->nss.enabled) ++ ath11k_nss_update_sta_stats(arvif, sinfo, sta); + } + + #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 { + WMI_VDEV_SUBTYPE_MESH_11S, + }; + ++#define MIN_IDLE_INACTIVE_TIME_SECS 256 ++ + enum wmi_sta_powersave_param { + WMI_STA_PS_PARAM_RX_WAKE_POLICY = 0, + 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: + return ret; + } + +-int ath11k_dp_rx_ampdu_start(struct ath11k *ar, ++int ath11k_dp_rx_ampdu_start(struct ath11k_vif *arvif, + struct ieee80211_ampdu_params *params) + { ++ struct ath11k *ar = arvif->ar; + struct ath11k_base *ab = ar->ab; + struct ath11k_sta *arsta = ath11k_sta_to_arsta(params->sta); +- int vdev_id = arsta->arvif->vdev_id; ++ int vdev_id = arvif->vdev_id; + 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 + return ret; + } + +-int ath11k_dp_rx_ampdu_stop(struct ath11k *ar, ++int ath11k_dp_rx_ampdu_stop(struct ath11k_vif *arvif, + struct ieee80211_ampdu_params *params) + { ++ struct ath11k *ar = arvif->ar; + struct ath11k_base *ab = ar->ab; + struct ath11k_peer *peer; +- struct ath11k_sta *arsta = ath11k_sta_to_arsta(params->sta); +- int vdev_id = arsta->arvif->vdev_id; ++ int vdev_id = arvif->vdev_id; + dma_addr_t paddr; + bool active; + 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; + +-int ath11k_dp_rx_ampdu_start(struct ath11k *ar, ++int ath11k_dp_rx_ampdu_start(struct ath11k_vif *arvif, + struct ieee80211_ampdu_params *params); +-int ath11k_dp_rx_ampdu_stop(struct ath11k *ar, ++int ath11k_dp_rx_ampdu_stop(struct ath11k_vif *arvif, + struct ieee80211_ampdu_params *params); + int ath11k_dp_peer_rx_pn_replay_config(struct ath11k_vif *arvif, + 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 + return NULL; + } + ++struct ath11k_ast_entry *ath11k_peer_ast_find_by_pdev_idx(struct ath11k *ar, ++ u8* addr) ++{ ++ struct ath11k_base *ab = ar->ab; ++ struct ath11k_ast_entry *ast_entry; ++ struct ath11k_peer *peer; ++ ++ lockdep_assert_held(&ab->base_lock); ++ ++ list_for_each_entry(peer, &ab->peers, list) ++ list_for_each_entry(ast_entry, &peer->ast_entry_list, ase_list) ++ if (ether_addr_equal(ast_entry->addr, addr) && ++ ast_entry->pdev_idx == ar->pdev_idx) ++ return ast_entry; ++ ++ return NULL; ++} ++ + 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 + } + + if (type != ATH11K_AST_TYPE_STATIC) { +- ast_entry = ath11k_peer_ast_find_by_addr(ab, mac_addr); +- if (ast_entry) { ++ ast_entry = ath11k_peer_ast_find_by_pdev_idx(ar, mac_addr); ++ if (ast_entry && ast_entry->type != ATH11K_AST_TYPE_STATIC) { + 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 + 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); + +- flush_work(&ast_entry->wds_wmi_wk); + 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 * + + peer = ast_entry->peer; + +- ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_del_ast peer %pM ast_entry %pM\n", +- peer->addr, ast_entry->addr); ++ ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_del_ast pdev:%d peer %pM ast_entry %pM\n", ++ ar->pdev->pdev_id, peer->addr, ast_entry->addr); + + if (ast_entry->is_mapped) + list_del(&ast_entry->ase_list); +--- a/drivers/net/wireless/ath/ath11k/peer.h ++++ b/drivers/net/wireless/ath/ath11k/peer.h +@@ -34,6 +34,7 @@ enum ath11k_ast_entry_type { + enum ath11k_wds_wmi_action { + ATH11K_WDS_WMI_ADD = 1, + ATH11K_WDS_WMI_UPDATE, ++ ATH11K_WDS_WMI_REMOVE, + + ATH11K_WDS_WMI_MAX + }; +@@ -126,6 +127,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); ++struct ath11k_ast_entry *ath11k_peer_ast_find_by_pdev_idx(struct ath11k *ar, ++ u8* addr); + 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 + { + return NULL; + } ++ ++static inline struct ath11k_ast_entry *ath11k_peer_ast_find_by_pdev_idx(struct ath11k *ar, ++ u8* addr) ++{ ++ return NULL; ++} + + static inline int ath11k_peer_add_ast(struct ath11k *ar, struct ath11k_peer *peer, + 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 + + peer->nss.nss_stats->tx_failed += tx_dropped; + +- ATH11K_NSS_TXRX_NETDEV_STATS(tx, peer->vif, tx_bytes, tx_packets); ++ if (peer->nss.ext_vdev_up) ++ ATH11K_NSS_TXRX_NETDEV_STATS(tx, peer->nss.ext_vif, tx_bytes, tx_packets); ++ else ++ ATH11K_NSS_TXRX_NETDEV_STATS(tx, peer->vif, tx_bytes, tx_packets); + + 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 + 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); ++ 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 + case ATH11K_NSS_WIFI_VDEV_DECAP_TYPE_CMD: + cmd = NSS_WIFI_VDEV_DECAP_TYPE_CMD; + break; ++ case ATH11K_NSS_WIFI_VDEV_CFG_WDS_BACKHAUL_CMD: ++ cmd = NSS_WIFI_VDEV_CFG_WDS_BACKHAUL_CMD; ++ break; + default: + return -EINVAL; + } +--- 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 { + 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 { + uint32_t *vaddr; + dma_addr_t paddr; + bool ext_vdev_up; ++ struct ieee80211_vif *ext_vif; + struct peer_stats *nss_stats; + struct completion complete; + }; 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/ath11k_nss/904-002-ath11k-extend-ext-vdev-in-NSS-for-dynamic-VLAN-handling.patch new file mode 100644 index 00000000000000..c97edcd605d7f1 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/904-002-ath11k-extend-ext-vdev-in-NSS-for-dynamic-VLAN-handling.patch @@ -0,0 +1,213 @@ +From 6f51430f2614ca2fb2a1e45cc81464c6d7a29f03 Mon Sep 17 00:00:00 2001 +From: Sathishkumar Muruganandam +Date: Fri, 8 Jan 2021 00:34:09 +0530 +Subject: [PATCH 2/3] ath11k: extend ext vdev in NSS for dynamic VLAN handling + +- add ext vdev NSS API callbacks required for dynamic AP_VLAN vif +- existing ext vdev NSS API callbacks are used for both WDS and + dynamic VLAN di_types. + +Signed-off-by: Sathishkumar Muruganandam +--- + drivers/net/wireless/ath/ath11k/nss.c | 101 +++++++++++++++++++++++++++++++--- + drivers/net/wireless/ath/ath11k/nss.h | 17 ++++++ + 2 files changed, 109 insertions(+), 9 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/nss.c ++++ b/drivers/net/wireless/ath/ath11k/nss.c +@@ -1483,14 +1483,11 @@ static int ath11k_nss_ext_vdev_register( + struct ath11k *ar = arvif->ar; + struct ath11k_base *ab = ar->ab; + nss_tx_status_t status; +- enum nss_dynamic_interface_type di_type; + u32 features = 0; + + if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN || arvif->nss.ctx) + return -EINVAL; + +- di_type = NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_WDS; +- + 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, +@@ -1518,7 +1515,8 @@ static void ath11k_nss_ext_vdev_free(str + + status = nss_dynamic_interface_dealloc_node( + arvif->nss.if_num, +- NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_WDS); ++ arvif->nss.di_type); ++ + if (status != NSS_TX_SUCCESS) + ath11k_warn(ab, "failed to free nss ext vdev err:%d\n", + status); +@@ -1527,14 +1525,19 @@ static void ath11k_nss_ext_vdev_free(str + "nss ext vdev interface deallocated\n"); + } + +-static int ath11k_nss_ext_vdev_alloc(struct ath11k_vif *arvif) ++static int ath11k_nss_ext_vdev_alloc(struct ath11k_vif *arvif, ++ struct wireless_dev *wdev) + { + struct ath11k_base *ab = arvif->ar->ab; + enum nss_dynamic_interface_type di_type; + int if_num; + +- di_type = NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_WDS; ++ if (wdev->use_4addr) ++ di_type = NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_WDS; ++ else ++ di_type = NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_VLAN; + ++ arvif->nss.di_type = di_type; + if_num = nss_dynamic_interface_alloc_node(di_type); + if (if_num < 0) { + ath11k_warn(ab, "failed to allocate nss ext vdev\n"); +@@ -1543,8 +1546,8 @@ static int ath11k_nss_ext_vdev_alloc(str + + arvif->nss.if_num = if_num; + ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, +- "nss ext vdev interface %pM allocated if_num %d\n", +- arvif->vif->addr, if_num); ++ "nss ext vdev interface %pM di_type %d allocated if_num %d\n", ++ arvif->vif->addr, di_type, if_num); + + return 0; + } +@@ -1573,7 +1576,7 @@ int ath11k_nss_ext_vdev_create(struct at + return -EINVAL; + } + +- ret = ath11k_nss_ext_vdev_alloc(arvif); ++ ret = ath11k_nss_ext_vdev_alloc(arvif, wdev); + if (ret) + return ret; + +@@ -1684,6 +1687,86 @@ free: + return ret; + } + ++int ath11k_nss_ext_vdev_cfg_dyn_vlan(struct ath11k_vif *arvif, u16 vlan_id) ++{ ++ struct ath11k *ar = arvif->ar; ++ struct nss_wifi_ext_vdev_msg *ext_vdev_msg = NULL; ++ struct nss_wifi_ext_vdev_vlan_msg *cfg_dyn_vlan_msg = NULL; ++ nss_tx_status_t status; ++ int ret; ++ ++ if (!ar->ab->nss.enabled) ++ return 0; ++ ++ if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN) ++ return -EINVAL; ++ ++ ext_vdev_msg = kzalloc(sizeof(struct nss_wifi_ext_vdev_msg), GFP_ATOMIC); ++ if (!ext_vdev_msg) ++ return -ENOMEM; ++ ++ cfg_dyn_vlan_msg = &ext_vdev_msg->msg.vmsg; ++ cfg_dyn_vlan_msg->vlan_id = vlan_id; ++ ++ nss_wifi_ext_vdev_msg_init(ext_vdev_msg, arvif->nss.if_num, ++ NSS_WIFI_EXT_VDEV_MSG_CONFIGURE_VLAN, ++ sizeof(struct nss_wifi_ext_vdev_vlan_msg), ++ NULL, arvif); ++ ++ status = nss_wifi_ext_vdev_tx_msg_sync(arvif->nss.ctx, ext_vdev_msg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "failed to configure dyn vlan nss_err:%d\n", ++ status); ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ ret = 0; ++free: ++ kfree(ext_vdev_msg); ++ ++ return ret; ++} ++ ++int ath11k_nss_dyn_vlan_set_group_key(struct ath11k_vif *arvif, u16 vlan_id, ++ u16 group_key) ++{ ++ struct nss_wifi_vdev_msg *vdev_msg = NULL; ++ struct nss_wifi_vdev_set_vlan_group_key *vlan_group_key; ++ struct ath11k *ar = arvif->ar; ++ nss_tx_status_t status; ++ int ret = 0; ++ ++ if (!ar->ab->nss.enabled) ++ return 0; ++ ++ vdev_msg = kzalloc(sizeof(struct nss_wifi_vdev_msg), GFP_ATOMIC); ++ if (!vdev_msg) ++ return -ENOMEM; ++ ++ vlan_group_key = &vdev_msg->msg.vlan_group_key; ++ vlan_group_key->vlan_id = vlan_id; ++ vlan_group_key->group_key = group_key; ++ ++ nss_wifi_vdev_msg_init(vdev_msg, arvif->nss.if_num, ++ NSS_WIFI_VDEV_SET_GROUP_KEY, ++ sizeof(struct nss_wifi_vdev_set_vlan_group_key), ++ NULL, NULL); ++ ++ status = nss_wifi_vdev_tx_msg(ar->nss.ctx, vdev_msg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "nss vdev set vlan group key error %d\n", status); ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS_WDS, "nss vdev set vlan group key success\n"); ++free: ++ kfree(vdev_msg); ++ return ret; ++ ++} ++ + /*----------------------------Peer Setup/Config -----------------------------*/ + + 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 +@@ -150,6 +150,10 @@ struct arvif_nss { + bool added; + /* Flag to notify if ext vdev is up/down */ + bool ext_vdev_up; ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ /* Keep the copy of di_type for nss */ ++ enum nss_dynamic_interface_type di_type; ++#endif + /* WDS cfg should be done only once for ext vdev */ + bool wds_cfg_done; + bool created; +@@ -215,6 +217,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); ++int ath11k_nss_ext_vdev_cfg_dyn_vlan(struct ath11k_vif *arvif, u16 vlan_id); ++int ath11k_nss_dyn_vlan_set_group_key(struct ath11k_vif *arvif, u16 vlan_id, ++ u16 group_key); + 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, +@@ -343,6 +348,18 @@ static inline int ath11k_nss_ext_vdev_do + { + return 0; + } ++ ++static inline int ath11k_nss_ext_vdev_cfg_dyn_vlan(struct ath11k_vif *arvif, ++ u16 vlan_id) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_dyn_vlan_set_group_key(struct ath11k_vif *arvif, ++ u16 vlan_id, u16 group_key) ++{ ++ return 0; ++} + + static inline void ath11k_nss_peer_stats_enable(struct ath11k *ar) + { 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/ath11k_nss/904-003-ath11k-add-dynamic-VLAN-support-in-NSS-offload.patch new file mode 100644 index 00000000000000..2361523d394ac4 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/904-003-ath11k-add-dynamic-VLAN-support-in-NSS-offload.patch @@ -0,0 +1,557 @@ +From da432fe6dda831c867416d338def3e277c989287 Mon Sep 17 00:00:00 2001 +From: Sathishkumar Muruganandam +Date: Fri, 8 Jan 2021 00:39:47 +0530 +Subject: [PATCH 3/3] ath11k: add dynamic VLAN support in NSS offload + +Driver should advertise NL80211_EXT_FEATURE_VLAN_OFFLOAD to enable +vlan offload in hostapd. + +Group Key for multiple vlan interfaces are configured with the help +of group key index as NSS uses this index to get the corresponding +group key during transmission. + +Each dynamic AP-VLAN interface choose unique group key index which +will be sent to NSS along with VLAN ID for dynamic VLAN ext vdev +configuration. + +ath11k_mac_op_set_key() does the NSS ext vdev config upon receiving +VLAN ID on group key. + +ath11k_mac_op_sta_state() does the STA assignment from AP vif to +AP_VLAN vif in NSS after mac80211. + +Currently, the firmware supports upto 128 group keys for an AP +interface. The multiple group key support can be enabled during +resource config. + +Co-Developed-by: Seevalamuthu Mariappan +Signed-off-by: Seevalamuthu Mariappan +Signed-off-by: Sathishkumar Muruganandam +--- + drivers/net/wireless/ath/ath11k/core.h | 8 ++ + drivers/net/wireless/ath/ath11k/mac.c | 237 ++++++++++++++++++++++++++++++--- + drivers/net/wireless/ath/ath11k/wmi.c | 5 + + drivers/net/wireless/ath/ath11k/wmi.h | 2 + + 4 files changed, 233 insertions(+), 19 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -98,6 +98,11 @@ enum ath11k_crypt_mode { + ATH11K_CRYPT_MODE_SW, + }; + ++#define ATH11K_GROUP_KEYS_NUM_MAX 128 ++#define ATH11K_FREE_GROUP_IDX_MAP_BITS (BITS_PER_BYTE * (sizeof(long))) ++#define ATH11K_FREE_GROUP_IDX_MAP_MAX (ATH11K_GROUP_KEYS_NUM_MAX / \ ++ ATH11K_FREE_GROUP_IDX_MAP_BITS) ++ + 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 { + u32 tx_compl_fail[ATH11K_STATS_MGMT_FRM_TYPE_MAX]; + }; + ++/** ++ *struct ath11k_dyn_vlan_cfg - dynamic vlan config state info container. ++ * will be used during ieee80211_reconfig ++ * nss offload case ++ *@arvif: driver's data for the corresponding AP_VLAN ieee80211_vif ++ *@sta: ieee80211_sta which is getting associated to AP_VLAN ++ *@cfg_list: list to hold all associated sta's state ++ */ ++struct ath11k_dyn_vlan_cfg { ++ struct ath11k_vif *arvif; ++ struct ieee80211_sta *sta; ++ struct list_head cfg_list; ++}; ++ + 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; + struct arvif_nss nss; + struct list_head ap_vlan_arvifs; ++ /* list required by Dynamic VLAN during fw_recovery */ ++ struct list_head dyn_vlan_cfg; ++ /* VLAN keyidx map required for Dynamic VLAN */ ++ u16 *vlan_keyid_map; ++ DECLARE_BITMAP(free_groupidx_map, ATH11K_GROUP_KEYS_NUM_MAX); + }; + + 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 + return ret; + } + ++static int ath11k_mac_cfg_dyn_vlan(struct ath11k_base *ab, ++ struct ath11k_vif *ap_vlan_arvif, ++ struct ieee80211_sta *sta); ++ + u8 ath11k_mac_bw_to_mac80211_bw(u8 bw) + { + u8 ret = 0; +@@ -720,6 +724,33 @@ u8 ath11k_mac_get_target_pdev_id(struct + return ar->ab->target_pdev_ids[0].pdev_id; + } + ++struct ath11k_vif *ath11k_mac_get_ap_arvif_by_addr(struct ath11k_base *ab, ++ const u8 *addr) ++{ ++ int i; ++ struct ath11k_pdev *pdev; ++ struct ath11k_vif *arvif; ++ struct ath11k *ar; ++ ++ for (i = 0; i < ab->num_radios; i++) { ++ pdev = rcu_dereference(ab->pdevs_active[i]); ++ if (pdev && pdev->ar) { ++ ar = pdev->ar; ++ ++ spin_lock_bh(&ar->data_lock); ++ list_for_each_entry(arvif, &ar->arvifs, list) { ++ if (arvif->vif->type == NL80211_IFTYPE_AP && ++ ether_addr_equal(arvif->vif->addr, addr)) { ++ spin_unlock_bh(&ar->data_lock); ++ return arvif; ++ } ++ } ++ spin_unlock_bh(&ar->data_lock); ++ } ++ } ++ return NULL; ++} ++ + 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 + if (test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags)) + return 0; + ++ if (key->vlan_id) ++ arg.group_key_idx = key->hw_key_idx; ++ + 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 + return first_errno; + } + ++static int ath11k_get_vlan_groupkey_index(struct ath11k_vif *arvif, ++ struct ieee80211_key_conf *key) ++{ ++ struct ath11k *ar = arvif->ar; ++ int map_idx = 0; ++ int free_bit; ++ ++ for (map_idx = 0; map_idx < ATH11K_FREE_GROUP_IDX_MAP_MAX; map_idx++) ++ if (arvif->free_groupidx_map[map_idx] != 0) ++ break; ++ ++ if (map_idx == ATH11K_FREE_GROUP_IDX_MAP_MAX) ++ return -ENOSPC; ++ ++ spin_lock_bh(&ar->data_lock); ++ /* select the first free key index */ ++ free_bit = __ffs64(arvif->free_groupidx_map[map_idx]); ++ key->hw_key_idx = (map_idx * ATH11K_FREE_GROUP_IDX_MAP_BITS) + free_bit; ++ /* clear the selected bit from free index map */ ++ clear_bit(key->hw_key_idx, arvif->free_groupidx_map); ++ spin_unlock_bh(&ar->data_lock); ++ ++ return 0; ++} ++ + static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) + { + struct ath11k *ar = hw->priv; + struct ath11k_base *ab = ar->ab; +- struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); ++ struct ath11k_vif *arvif, *ap_vlan_arvif = NULL; + struct ath11k_peer *peer; +- struct ath11k_sta *arsta; ++ struct ath11k_sta *arsta = NULL; + const u8 *peer_addr; + int ret = 0; + u32 flags = 0; +@@ -4288,17 +4347,38 @@ static int ath11k_mac_op_set_key(struct + if (key->keyidx > WMI_MAX_KEY_INDEX) + return -ENOSPC; + +- mutex_lock(&ar->conf_mutex); ++ arvif = ath11k_vif_to_arvif(vif); + +- if (sta) ++ mutex_lock(&ar->conf_mutex); ++ if (sta) { + peer_addr = sta->addr; +- else if (arvif->vdev_type == WMI_VDEV_TYPE_STA) ++ arsta = (struct ath11k_sta *)sta->drv_priv; ++ } else if (arvif->vdev_type == WMI_VDEV_TYPE_STA) { + peer_addr = vif->bss_conf.bssid; +- else ++ } else { + peer_addr = vif->addr; ++ } + + key->hw_key_idx = key->keyidx; + ++ if (ab->nss.enabled && vif->type == NL80211_IFTYPE_AP_VLAN) { ++ ap_vlan_arvif = arvif; ++ if (arsta) { ++ ap_vlan_arvif->nss.ap_vif = arsta->arvif; ++ arvif = arsta->arvif; ++ } else { ++ rcu_read_lock(); ++ arvif = ath11k_mac_get_ap_arvif_by_addr(ab, peer_addr); ++ if (!arvif) { ++ rcu_read_unlock(); ++ ret = -EINVAL; ++ goto exit; ++ } ++ ap_vlan_arvif->nss.ap_vif = arvif; ++ rcu_read_unlock(); ++ } ++ } ++ + /* 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 + goto exit; + } + ++ /* VLAN ID is updated non-zero only for AP_VLAN vif */ ++ if (key->vlan_id && !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE) && ++ ap_vlan_arvif) { ++ if (arvif->vlan_keyid_map) ++ key->hw_key_idx = arvif->vlan_keyid_map[key->vlan_id]; ++ else ++ key->hw_key_idx = 0; ++ switch (cmd) { ++ case SET_KEY: ++ /* If the group key idx is already available, ++ * no need to find the free index again. ++ * This happens during GTK rekey. It uses ++ * the same index after rekey also. ++ */ ++ if (!key->hw_key_idx) ++ ret = ath11k_get_vlan_groupkey_index(arvif, key); ++ break; ++ case DISABLE_KEY: ++ /* If the group key idx is already 0, ++ * no need of freeing the index. ++ */ ++ if (key->hw_key_idx) { ++ spin_lock_bh(&ar->data_lock); ++ /* make the group index as available */ ++ set_bit(key->hw_key_idx, arvif->free_groupidx_map); ++ spin_unlock_bh(&ar->data_lock); ++ } ++ break; ++ default: ++ ret = -EINVAL; ++ } ++ ++ if (ret) { ++ ath11k_warn(ab, "failed to set group key index for vlan %u : %d\n", ++ key->vlan_id, ret); ++ goto exit; ++ } ++ ++ ret = ath11k_nss_ext_vdev_configure(ap_vlan_arvif); ++ if (ret) { ++ ath11k_warn(ab, "failed to nss cfg ext vdev %pM: %d\n", ++ ap_vlan_arvif->vif->addr, ret); ++ goto exit; ++ } ++ ++ ret = ath11k_nss_ext_vdev_cfg_dyn_vlan(ap_vlan_arvif, ++ key->vlan_id); ++ if (ret) { ++ ath11k_warn(ab, "failed to cfg dynamic vlan %d\n", ret); ++ goto exit; ++ } ++ ++ ret = ath11k_nss_dyn_vlan_set_group_key(ap_vlan_arvif->nss.ap_vif, ++ key->vlan_id, ++ key->hw_key_idx); ++ if (ret) { ++ ath11k_warn(ab, "failed to set dynamic vlan group key %d\n", ++ ret); ++ goto exit; ++ } ++ ++ ret = ath11k_nss_ext_vdev_up(ap_vlan_arvif); ++ if (ret) { ++ ath11k_warn(ab, "failed to set dyn vlan UP %d\n", ret); ++ goto exit; ++ } ++ } ++ + 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 + goto unlock; + } + ++ spin_unlock_bh(&ar->ab->base_lock); ++ if (ap_vlan_arvif && ar->state == ATH11K_STATE_RESTARTED) { ++ /* Keys are getting installed during ieee80211_reconfig(). Configuring ++ * dynamic vlan is pending and the state is saved in the ap_vlan ++ * arvif dyn_vlan_cfg list. We will configure it now since nss peer is authorised */ ++ struct ath11k_dyn_vlan_cfg *dyn_vlan_cfg, *tmp; ++ ++ list_for_each_entry_safe(dyn_vlan_cfg, tmp, &ap_vlan_arvif->dyn_vlan_cfg, cfg_list) { ++ struct ieee80211_sta *vlan_sta = dyn_vlan_cfg->sta; ++ ++ ret = ath11k_mac_cfg_dyn_vlan(ar->ab, ap_vlan_arvif, vlan_sta); ++ if (ret) ++ ath11k_warn(ar->ab, "failed to cfg dyn vlan for peer %pM: %d\n", ++ vlan_sta->addr, ret); ++ /* Configuration is used. Free up space */ ++ list_del(&dyn_vlan_cfg->cfg_list); ++ kfree(dyn_vlan_cfg); ++ } ++ } ++ ++ spin_lock_bh(&ar->ab->base_lock); + 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 + peer->mcast_keyidx = key->keyidx; + peer->sec_type_grp = ath11k_dp_tx_get_encrypt_type(key->cipher); + } ++ /* storing group key idx which will be used during rekey */ ++ if (key->vlan_id) ++ arvif->vlan_keyid_map[key->vlan_id] = key->hw_key_idx; + } else if (peer && cmd == DISABLE_KEY) { + peer->keys[key->keyidx] = NULL; + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) + peer->ucast_keyidx = 0; + else + peer->mcast_keyidx = 0; +- } else if (!peer) ++ if (key->vlan_id) ++ arvif->vlan_keyid_map[key->vlan_id] = 0; ++ } else if (!peer) { + /* impossible unless FW goes crazy */ + ath11k_warn(ab, "peer %pM disappeared!\n", peer_addr); ++ } + +- if (sta) { +- arsta = ath11k_sta_to_arsta(sta); ++ if (arsta) { + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_TKIP: +@@ -5186,6 +5360,33 @@ static u32 ath11k_mac_ieee80211_sta_bw_t + return bw; + } + ++static int ath11k_mac_cfg_dyn_vlan(struct ath11k_base *ab, ++ struct ath11k_vif *ap_vlan_arvif, ++ struct ieee80211_sta *sta) ++{ ++ struct ath11k_peer *peer; ++ int peer_id, ret; ++ ++ spin_lock_bh(&ab->base_lock); ++ peer = ath11k_peer_find_by_addr(ab, sta->addr); ++ if (!peer) { ++ ath11k_warn(ab, "failed to find peer for %pM\n", sta->addr); ++ spin_unlock_bh(&ab->base_lock); ++ return -EINVAL; ++ } ++ peer_id = peer->peer_id; ++ spin_unlock_bh(&ab->base_lock); ++ ++ ret = ath11k_nss_ext_vdev_wds_4addr_allow(ap_vlan_arvif, peer_id); ++ if (ret) { ++ ath11k_warn(ab, "failed to set 4addr allow for %pM:%d\n", ++ sta->addr, ret); ++ return ret; ++ } ++ ++ return ret; ++} ++ + 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 + 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) { +@@ -7045,7 +7274,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 && +- ieee80211_set_hw_80211_encap(vif, true)) { ++ (vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)) { + 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 + vif->addr, ret); + goto err; + } ++ INIT_LIST_HEAD(&arvif->dyn_vlan_cfg); + mutex_unlock(&ar->conf_mutex); + return ret; + } +@@ -7082,6 +7312,20 @@ static int ath11k_mac_op_add_interface(s + arvif->vdev_id = bit; + arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE; + ++ spin_lock_bh(&ar->data_lock); ++ /* Configure vlan specific parameters */ ++ for (i = 0; i < ATH11K_FREE_GROUP_IDX_MAP_MAX; i++) ++ arvif->free_groupidx_map[i] = 0xFFFFFFFFL; ++ /* Group idx 0 is not valid for VLAN*/ ++ arvif->free_groupidx_map[0] &= ~(1L); ++ spin_unlock_bh(&ar->data_lock); ++ ++ arvif->vlan_keyid_map = kzalloc(4096, GFP_KERNEL); ++ if (!arvif->vlan_keyid_map) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ + switch (vif->type) { + case NL80211_IFTYPE_UNSPECIFIED: + case NL80211_IFTYPE_STATION: +@@ -7122,7 +7366,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); +- goto err; ++ goto err_keyid; + } + + ar->num_created_vdevs++; +@@ -7281,7 +7525,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); +- goto err; ++ goto err_keyid; + } + } + +@@ -7292,6 +7536,8 @@ err_vdev_del: + list_del(&arvif->list); + spin_unlock_bh(&ar->data_lock); + ++err_keyid: ++ kfree(arvif->vlan_keyid_map); + err: + mutex_unlock(&ar->conf_mutex); + +@@ -7389,6 +7635,7 @@ err_vdev_del: + list_del(&arvif->list); + spin_unlock_bh(&ar->data_lock); + ++ kfree(arvif->vlan_keyid_map); + ath11k_peer_cleanup(ar, arvif->vdev_id); + + idr_for_each(&ar->txmgmt_idr, +@@ -10113,8 +10360,11 @@ static int __ath11k_mac_register(struct + ab->hw_params.bios_sar_capa) + ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa; + +- if (ab->nss.enabled) ++ if (ab->nss.enabled) { + ieee80211_hw_set(ar->hw, SUPPORTS_NSS_OFFLOAD); ++ wiphy_ext_feature_set(ar->hw->wiphy, ++ NL80211_EXT_FEATURE_VLAN_OFFLOAD); ++ } + + ret = ieee80211_register_hw(ar->hw); + 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 + cmd->key_len = arg->key_len; + cmd->key_txmic_len = arg->key_txmic_len; + cmd->key_rxmic_len = arg->key_rxmic_len; ++ cmd->group_key_id = arg->group_key_idx; + + 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 + 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; ++ wmi_cfg->max_num_group_keys = tg_cfg->max_num_group_keys; + } + + static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi, +@@ -4497,6 +4499,9 @@ int ath11k_wmi_cmd_init(struct ath11k_ba + memset(&init_param, 0, sizeof(init_param)); + memset(&config, 0, sizeof(config)); + ++ if (ab->nss.enabled) ++ config.max_num_group_keys = ATH11K_GROUP_KEYS_NUM_MAX; ++ + ab->hw_params.hw_ops->wmi_init_config(ab, &config); + + 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 { + u32 vdev_id; + const u8 *macaddr; + u32 key_idx; ++ u32 group_key_idx; + u32 key_flags; + u32 key_cipher; + u32 key_len; +@@ -5846,6 +5847,7 @@ struct target_resource_config { + u32 bpf_instruction_size; + u32 max_bssid_rx_filters; + u32 use_pdev_id; ++ u32 max_num_group_keys; + u32 peer_map_unmap_v2_support; + u32 sched_params; + u32 twt_ap_pdev_count; diff --git a/target/linux/qualcommax/patches-6.1/9999-add-btcoex-dts.patch b/target/linux/qualcommax/patches-6.1/9999-add-btcoex-dts.patch new file mode 100644 index 00000000000000..83825b782c1b7f --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/9999-add-btcoex-dts.patch @@ -0,0 +1,30 @@ +--- linux-6.1.71/arch/arm64/boot/dts/qcom/ipq8074.dtsi 2024-01-07 01:44:56.908138962 -0500 ++++ linux-6.1.71/arch/arm64/boot/dts/qcom/ipq8074.dtsi 2024-01-07 01:44:58.908138962 -0500 +@@ -1170,7 +1170,14 @@ + wifi: wifi@c0000000 { + compatible = "qcom,ipq8074-wifi"; + reg = <0xc000000 0x2000000>; +- ++ qcom,hw-mode-id = <1>; ++ #ifdef __IPQ_MEM_PROFILE_256_MB__ ++ qcom,tgt-mem-mode = <2>; ++ #elif __IPQ_MEM_PROFILE_512_MB__ ++ qcom,tgt-mem-mode = <1>; ++ #else ++ qcom,tgt-mem-mode = <0>; ++ #endif + interrupts = , + , + , +@@ -1276,6 +1283,12 @@ + "tcl2host-status-ring"; + qcom,rproc = <&q6v5_wcss>; + status = "disabled"; ++ qcom,pta-num = <0>; ++ qcom,coex-mode = <0x2>; ++ qcom,bt-active-time = <0x12>; ++ qcom,bt-priority-time = <0x0c>; ++ qcom,coex-algo = <0x2>; ++ qcom,pta-priority = <0x80800505>; + }; + }; From b53887303d5c951a2d6000bbe22d63fc7aced4d8 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 7 Jan 2024 18:56:04 -0500 Subject: [PATCH 069/225] qualcommax: Silence annoying 'UBI NAND' warnings. --- .../9999-silence-UBI-NAND-warnings.patch | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/9999-silence-UBI-NAND-warnings.patch diff --git a/target/linux/qualcommax/patches-6.1/9999-silence-UBI-NAND-warnings.patch b/target/linux/qualcommax/patches-6.1/9999-silence-UBI-NAND-warnings.patch new file mode 100644 index 00000000000000..2eb85cb7b1700b --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/9999-silence-UBI-NAND-warnings.patch @@ -0,0 +1,13 @@ +--- a/drivers/mtd/mtdblock.c ++++ b/drivers/mtd/mtdblock.c +@@ -261,10 +261,6 @@ static int mtdblock_open(struct mtd_blkt + return 0; + } + +- if (mtd_type_is_nand(mbd->mtd)) +- pr_warn("%s: MTD device '%s' is NAND, please consider using UBI block devices instead.\n", +- mbd->tr->name, mbd->mtd->name); +- + /* OK, it's not open. Create cache info for it */ + mtdblk->count = 1; + mutex_init(&mtdblk->cache_mutex); From 1cc09c867d2cd4a149af21cfc22a2af31e17028e Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 7 Jan 2024 18:56:51 -0500 Subject: [PATCH 070/225] qualcommax: optimize smp_affinity --- .../ipq807x/base-files/etc/init.d/smp_affinity | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/target/linux/qualcommax/ipq807x/base-files/etc/init.d/smp_affinity b/target/linux/qualcommax/ipq807x/base-files/etc/init.d/smp_affinity index 09348eba33a991..b45ba7edddcf4f 100755 --- a/target/linux/qualcommax/ipq807x/base-files/etc/init.d/smp_affinity +++ b/target/linux/qualcommax/ipq807x/base-files/etc/init.d/smp_affinity @@ -18,6 +18,18 @@ enable_affinity_ipq807x(){ set_affinity 'wbm2host-tx-completions-ring1' 2 set_affinity 'wbm2host-tx-completions-ring2' 4 set_affinity 'wbm2host-tx-completions-ring3' 8 + + # assign 3 tcl completions to last 3 CPUs + set_affinity 'ppdu-end-interrupts-mac1' 2 + set_affinity 'ppdu-end-interrupts-mac2' 4 + set_affinity 'ppdu-end-interrupts-mac3' 8 + + set_affinity 'nss_empty_buf_sos' 4 + set_affinity 'nss_empty_buf_queue' 4 + + set_affinity 'xhci-hcd:usb1' 2 + + echo 8 > /proc/irq/50/smp_affinity } boot() { From 568dafc9fe3e13fdc239a9e6ce8896e210acf2d8 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 7 Jan 2024 18:59:36 -0500 Subject: [PATCH 071/225] feeds: update to use personal fork of nss-packages --- feeds.conf.default | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/feeds.conf.default b/feeds.conf.default index 4699f733f878e2..741b14a875d234 100644 --- a/feeds.conf.default +++ b/feeds.conf.default @@ -2,7 +2,8 @@ src-git packages https://git.openwrt.org/feed/packages.git src-git luci https://git.openwrt.org/project/luci.git src-git routing https://git.openwrt.org/feed/routing.git src-git telephony https://git.openwrt.org/feed/telephony.git -src-git nss_packages https://github.com/dimfishr/nss-packages.git +src-git nss_packages https://github.com/qosmio/nss-packages.git;NSS-12.4-K6.1 +src-git sqm_scripts_nss https://github.com/rickkdotnet/sqm-scripts-nss.git #src-git video https://github.com/openwrt/video.git #src-git targets https://github.com/openwrt/targets.git #src-git oldpackages http://git.openwrt.org/packages.git From d105cbcf16e9619fd1f7f9ef507fc87c6d4fd8e0 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 7 Jan 2024 22:41:14 -0500 Subject: [PATCH 072/225] ath11k_nss: handle qca-nss-drv symbol dependancies --- package/kernel/mac80211/ath.mk | 2 ++ .../199-001-mac80211-add-nss-support.patch | 2 +- ...th11k-Add-support-for-beacon-tx-mode.patch | 4 +-- ...ow-fast-rx-by-bypassing-stats-update.patch | 2 +- ...-fix-clear-peer-keys-during-disassoc.patch | 4 +-- ...unused-RX_FLAGS-from-mac80211_rx_fla.patch | 4 +-- .../640-006-mac80211-add-eht-radiotap.patch | 8 ++--- .../patches/ath11k_nss/900-fix-build.patch | 22 ++++++------- ...N-iftype-support-on-NSS-offload-case.patch | 4 +-- ...-dynamic-VLAN-support-on-NSS-offload.patch | 4 +-- ...-support-on-NSS-offload-for-STA-mode.patch | 32 +++++++++---------- ...02-ath11k-add-HE-stats-in-peer-stats.patch | 18 +++++------ .../902-ath11k-add-btcoex-config.patch | 16 +++++----- ...pport-for-WDS-offload-in-NSS-offload.patch | 2 +- ...dev-in-NSS-for-dynamic-VLAN-handling.patch | 18 +++++------ 15 files changed, 72 insertions(+), 70 deletions(-) diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk index a94f24f7df6dca..315746abb1fb7a 100644 --- a/package/kernel/mac80211/ath.mk +++ b/package/kernel/mac80211/ath.mk @@ -332,6 +332,8 @@ define KernelPackage/ath11k/config config ATH11K_NSS_SUPPORT bool "Enable NSS WiFi offload" + select NSS_DRV_WIFI_ENABLE + select NSS_DRV_WIFI_EXT_VDEV_ENABLE default y if TARGET_qualcommax config ATH11K_MEM_PROFILE_512M diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch b/package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch index 0b017ec97ad24d..f25def295537ca 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch @@ -225,7 +225,7 @@ Signed-off-by: Sriram R return -EINVAL; --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c -@@ -2379,6 +2379,9 @@ sta_get_last_rx_stats(struct sta_info *s +@@ -2380,6 +2380,9 @@ sta_get_last_rx_stats(struct sta_info *s struct ieee80211_sta_rx_stats *stats = &sta->deflink.rx_stats; int cpu; 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 index a95308a74ed223..5d5a83911d8519 100644 --- 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 @@ -19,7 +19,7 @@ Signed-off-by: Maharaja Kennadyrajan --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -3483,7 +3483,10 @@ static void ath11k_mac_op_bss_info_chang +@@ -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; @@ -31,7 +31,7 @@ Signed-off-by: Maharaja Kennadyrajan ret = ath11k_wmi_pdev_set_param(ar, param_id, param_value, ar->pdev->pdev_id); if (ret) -@@ -3491,8 +3494,9 @@ static void ath11k_mac_op_bss_info_chang +@@ -3489,8 +3492,9 @@ static void ath11k_mac_op_bss_info_chang arvif->vdev_id); else ath11k_dbg(ar->ab, ATH11K_DBG_MAC, 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/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch index bb46abada6b9e3..b0f6b03f750f9e 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch @@ -395,7 +395,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 -@@ -5197,6 +5197,14 @@ static int ath11k_mac_op_sta_state(struc +@@ -5201,6 +5201,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/357-ath11k-fix-clear-peer-keys-during-disassoc.patch b/package/kernel/mac80211/patches/ath11k_nss/357-ath11k-fix-clear-peer-keys-during-disassoc.patch index 5050192acc64ae..414cb06d87bd4b 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/357-ath11k-fix-clear-peer-keys-during-disassoc.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/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 -@@ -4708,12 +4708,6 @@ static int ath11k_station_disassoc(struc +@@ -4712,12 +4712,6 @@ static int ath11k_station_disassoc(struc return ret; } @@ -30,7 +30,7 @@ Signed-off-by: Karthikeyan Kathirvel return 0; } -@@ -5176,6 +5170,17 @@ static int ath11k_mac_op_sta_state(struc +@@ -5180,6 +5174,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/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch b/package/kernel/mac80211/patches/ath11k_nss/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch index 2d1fbc097df375..14fd82cbeaa853 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/ath11k_nss/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 -@@ -1385,8 +1385,6 @@ ieee80211_tx_info_clear_status(struct ie +@@ -1387,8 +1387,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 -@@ -1458,22 +1456,21 @@ enum mac80211_rx_flags { +@@ -1460,22 +1458,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), 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 index b8d2b614dd4759..79146df5447b8b 100644 --- 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 @@ -321,7 +321,7 @@ Signed-off-by: P Praneesh */ --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -1439,7 +1439,11 @@ ieee80211_tx_info_clear_status(struct ie +@@ -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) @@ -333,7 +333,7 @@ Signed-off-by: P Praneesh enum mac80211_rx_flags { RX_FLAG_MMIC_ERROR = BIT(0), RX_FLAG_DECRYPTED = BIT(1), -@@ -1471,6 +1475,8 @@ enum mac80211_rx_flags { +@@ -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), @@ -342,7 +342,7 @@ Signed-off-by: P Praneesh }; /** -@@ -1538,6 +1544,7 @@ enum mac80211_rx_encoding { +@@ -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_\* @@ -350,7 +350,7 @@ Signed-off-by: P Praneesh * @encoding: &enum mac80211_rx_encoding * @bw: &enum rate_info_bw * @enc_flags: uses bits from &enum mac80211_rx_encoding_flags -@@ -1591,6 +1598,7 @@ struct ieee80211_rx_status { +@@ -1593,6 +1600,7 @@ struct ieee80211_rx_status { u8 ampdu_delimiter_crc; u8 zero_length_psdu_type; u8 link_valid:1, link_id:4; diff --git a/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch b/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch index 67d6e5285bdd94..180fb7feab2e49 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch @@ -56,7 +56,7 @@ if (rxcb->is_mcbc) { --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -9224,7 +9224,7 @@ void cfg80211_bss_flush(struct wiphy *wi +@@ -9228,7 +9228,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 +65,7 @@ enum nl80211_commands cmd, u8 count, u64 color_bitmap); -@@ -9234,9 +9234,9 @@ int cfg80211_bss_color_notify(struct net +@@ -9238,9 +9238,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 +77,7 @@ 0, color_bitmap); } -@@ -9250,7 +9250,7 @@ static inline int cfg80211_obss_color_co +@@ -9254,7 +9254,7 @@ static inline int cfg80211_obss_color_co static inline int cfg80211_color_change_started_notify(struct net_device *dev, u8 count) { @@ -86,7 +86,7 @@ count, 0); } -@@ -9262,7 +9262,7 @@ static inline int cfg80211_color_change_ +@@ -9266,7 +9266,7 @@ static inline int cfg80211_color_change_ */ static inline int cfg80211_color_change_aborted_notify(struct net_device *dev) { @@ -95,7 +95,7 @@ 0, 0); } -@@ -9274,7 +9274,7 @@ static inline int cfg80211_color_change_ +@@ -9278,7 +9278,7 @@ static inline int cfg80211_color_change_ */ static inline int cfg80211_color_change_notify(struct net_device *dev) { @@ -106,7 +106,7 @@ } --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -5239,6 +5239,10 @@ void ieee80211_tx_status_ext(struct ieee +@@ -5241,6 +5241,10 @@ void ieee80211_tx_status_ext(struct ieee * (NULL for multicast packets) * @info: tx status information */ @@ -119,7 +119,7 @@ struct ieee80211_tx_info *info) --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -4775,7 +4775,7 @@ void ieee80211_color_collision_detection +@@ -4777,7 +4777,7 @@ void ieee80211_color_collision_detection struct ieee80211_sub_if_data *sdata = link->sdata; sdata_lock(sdata); @@ -141,7 +141,7 @@ sdata->debugfs.subdir_stations = debugfs_create_dir("stations", --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c -@@ -1406,18 +1406,6 @@ static void __sta_info_destroy_part2(str +@@ -1407,18 +1407,6 @@ static void __sta_info_destroy_part2(str WARN_ON_ONCE(ret); } @@ -195,7 +195,7 @@ struct sta_info *sta = container_of(pubsta, struct sta_info, sta); --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -19406,7 +19406,7 @@ void cfg80211_ch_switch_started_notify(s +@@ -19414,7 +19414,7 @@ void cfg80211_ch_switch_started_notify(s } EXPORT_SYMBOL(cfg80211_ch_switch_started_notify); @@ -204,7 +204,7 @@ enum nl80211_commands cmd, u8 count, u64 color_bitmap) { -@@ -19420,7 +19420,7 @@ int cfg80211_bss_color_notify(struct net +@@ -19428,7 +19428,7 @@ int cfg80211_bss_color_notify(struct net trace_cfg80211_bss_color_notify(dev, cmd, count, color_bitmap); @@ -213,7 +213,7 @@ if (!msg) return -ENOMEM; -@@ -19443,7 +19443,7 @@ int cfg80211_bss_color_notify(struct net +@@ -19451,7 +19451,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/902-000-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch b/package/kernel/mac80211/patches/ath11k_nss/902-000-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch index f0fc8c14ec1efd..7dc88faed71f9f 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/ath11k_nss/902-000-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 -@@ -5100,6 +5100,17 @@ void ieee80211_sta_pspoll(struct ieee802 +@@ -5102,6 +5102,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 -@@ -2176,7 +2176,13 @@ static int ieee80211_change_station(stru +@@ -2177,7 +2177,13 @@ static int ieee80211_change_station(stru rcu_assign_pointer(vlansdata->u.vlan.sta, sta); __ieee80211_check_fast_rx_iface(vlansdata); 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/ath11k_nss/902-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch index 143191f6a9bca9..33eb5d2001db91 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/902-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/902-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 -@@ -2089,6 +2089,8 @@ enum ieee80211_key_flags { +@@ -2091,6 +2091,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) -@@ -2108,6 +2110,7 @@ struct ieee80211_key_conf { +@@ -2110,6 +2112,7 @@ struct ieee80211_key_conf { u8 hw_key_idx; s8 keyidx; u16 flags; 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/ath11k_nss/902-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch index 12d42ddaa9ba9c..0e6c0d92d2abde 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/ath11k_nss/902-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 -@@ -655,6 +655,7 @@ struct ath11k { +@@ -634,6 +634,7 @@ struct ath11k { struct ath11k_pdev_wmi *wmi; #ifdef CPTCFG_ATH11K_NSS_SUPPORT struct ath11k_nss nss; @@ -34,7 +34,7 @@ Signed-off-by: Sathishkumar Muruganandam #endif struct ath11k_pdev_dp dp; u8 mac_addr[ETH_ALEN]; -@@ -1065,6 +1066,8 @@ struct ath11k_base { +@@ -1042,6 +1043,8 @@ struct ath11k_base { u32 rx_hash; bool stats_disable; @@ -45,7 +45,7 @@ Signed-off-by: Sathishkumar Muruganandam }; --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h -@@ -1181,13 +1181,16 @@ struct htt_t2h_peer_map_event { +@@ -1142,13 +1142,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 +66,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 -@@ -1890,6 +1890,8 @@ void ath11k_dp_htt_htc_t2h_msg_handler(s +@@ -1756,6 +1756,8 @@ void ath11k_dp_htt_htc_t2h_msg_handler(s u16 peer_mac_h16; u16 ast_hash; u16 hw_peer_id; @@ -75,7 +75,7 @@ Signed-off-by: Sathishkumar Muruganandam ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "dp_htt rx msg type :0x%0x\n", type); -@@ -1925,15 +1927,29 @@ void ath11k_dp_htt_htc_t2h_msg_handler(s +@@ -1791,15 +1793,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); @@ -630,9 +630,9 @@ Signed-off-by: Sathishkumar Muruganandam if (sta) { --- a/drivers/net/wireless/ath/ath11k/peer.h +++ b/drivers/net/wireless/ath/ath11k/peer.h -@@ -18,6 +18,47 @@ struct ppdu_user_delayba { - u32 resp_rate_flags; - }; +@@ -7,6 +7,47 @@ + #ifndef ATH11K_PEER_H + #define ATH11K_PEER_H +enum ath11k_ast_entry_type { + ATH11K_AST_TYPE_NONE, /* static ast entry for connected peer */ @@ -678,7 +678,7 @@ Signed-off-by: Sathishkumar Muruganandam struct ath11k_peer { struct list_head list; struct ieee80211_sta *sta; -@@ -29,6 +70,10 @@ struct ath11k_peer { +@@ -18,6 +59,10 @@ struct ath11k_peer { u8 pdev_idx; u16 hw_peer_id; struct ath11k_nss_peer nss; @@ -689,7 +689,7 @@ Signed-off-by: Sathishkumar Muruganandam /* protected by ab->data_lock */ struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; -@@ -54,8 +99,13 @@ struct ath11k_peer { +@@ -41,8 +86,13 @@ struct ath11k_peer { }; void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id); @@ -703,7 +703,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, -@@ -72,4 +122,71 @@ struct ath11k_peer *ath11k_peer_find_by_ +@@ -59,4 +109,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); @@ -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) { -@@ -6484,6 +6530,36 @@ static int ath11k_pull_peer_assoc_conf_e +@@ -6419,6 +6465,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) { -@@ -7399,6 +7475,7 @@ static int ath11k_wmi_tlv_rdy_parse(stru +@@ -7334,6 +7410,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: -@@ -8870,6 +8947,22 @@ static void ath11k_wmi_gtk_offload_statu +@@ -8805,6 +8882,22 @@ static void ath11k_wmi_gtk_offload_statu kfree(tb); } @@ -905,7 +905,7 @@ 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; -@@ -9000,6 +9093,9 @@ static void ath11k_wmi_tlv_op_rx(struct +@@ -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); break; @@ -961,7 +961,7 @@ Signed-off-by: Sathishkumar Muruganandam /* * PDEV statistics */ -@@ -6503,6 +6533,9 @@ int ath11k_wmi_set_sta_ps_param(struct a +@@ -6430,6 +6460,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/902-ath11k-add-HE-stats-in-peer-stats.patch b/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-HE-stats-in-peer-stats.patch index edb60ac18bef10..4831424fa40810 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-HE-stats-in-peer-stats.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-HE-stats-in-peer-stats.patch @@ -363,7 +363,7 @@ Signed-off-by: Miles Hu /* HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG Message * * details: -@@ -1312,6 +1351,19 @@ enum htt_ppdu_stats_gi { +@@ -1315,6 +1354,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) -@@ -1339,6 +1391,12 @@ enum htt_ppdu_stats_gi { +@@ -1342,6 +1394,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) -@@ -1442,6 +1500,21 @@ struct htt_ppdu_stats_usr_cmpltn_ack_ba_ +@@ -1445,6 +1503,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; -@@ -1455,14 +1528,16 @@ struct htt_ppdu_stats_usr_cmn_array { +@@ -1458,14 +1531,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 { -@@ -1471,7 +1546,7 @@ struct htt_ppdu_stats { +@@ -1474,7 +1549,7 @@ struct htt_ppdu_stats { }; struct htt_ppdu_stats_info { @@ -748,9 +748,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 -@@ -7,6 +7,17 @@ - #ifndef ATH11K_PEER_H - #define ATH11K_PEER_H +@@ -48,6 +48,17 @@ struct ath11k_ast_entry { + struct list_head ase_list; + }; +struct ppdu_user_delayba { + u8 reserved0; @@ -766,7 +766,7 @@ Signed-off-by: Miles Hu struct ath11k_peer { struct list_head list; struct ieee80211_sta *sta; -@@ -38,6 +49,8 @@ struct ath11k_peer { +@@ -83,6 +94,8 @@ struct ath11k_peer { u16 sec_type_grp; bool is_authorized; bool dp_setup_done; diff --git a/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-btcoex-config.patch b/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-btcoex-config.patch index 18bc4384094eca..495245f9662462 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-btcoex-config.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-btcoex-config.patch @@ -29,7 +29,7 @@ struct ath11k { struct ath11k_base *ab; struct ath11k_pdev *pdev; -@@ -759,6 +769,8 @@ struct ath11k { +@@ -760,6 +770,8 @@ struct ath11k { struct ath11k_per_peer_tx_stats cached_stats; u32 last_ppdu_id; u32 cached_ppdu_id; @@ -56,7 +56,7 @@ #include "nss.h" #define CHAN2G(_channel, _freq, _flags) { \ -@@ -9282,6 +9284,91 @@ err_fallback: +@@ -9286,6 +9288,91 @@ err_fallback: return 0; } @@ -148,7 +148,7 @@ static const struct ieee80211_ops ath11k_ops = { .tx = ath11k_mac_op_tx, .wake_tx_queue = ieee80211_handle_wake_tx_queue, -@@ -9521,6 +9608,56 @@ static int ath11k_mac_setup_iface_combin +@@ -9525,6 +9612,56 @@ static int ath11k_mac_setup_iface_combin return 0; } @@ -205,7 +205,7 @@ static const u8 ath11k_if_types_ext_capa[] = { [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT, -@@ -9782,6 +9919,7 @@ static int __ath11k_mac_register(struct +@@ -9786,6 +9923,7 @@ static int __ath11k_mac_register(struct ar->hw->wiphy->ema_max_profile_periodicity = TARGET_EMA_MAX_PROFILE_PERIOD; ath11k_reg_init(ar); @@ -213,7 +213,7 @@ if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) { ar->hw->netdev_features = NETIF_F_HW_CSUM; -@@ -9944,6 +10082,7 @@ int ath11k_mac_allocate(struct ath11k_ba +@@ -9948,6 +10086,7 @@ int ath11k_mac_allocate(struct ath11k_ba */ ath11k_wmi_pdev_attach(ab, i); @@ -447,7 +447,7 @@ +#endif /* QCA_VENDOR_H */ --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -1697,6 +1697,71 @@ int ath11k_wmi_vdev_set_param_cmd(struct +@@ -1743,6 +1743,71 @@ int ath11k_wmi_vdev_set_param_cmd(struct return ret; } @@ -521,7 +521,7 @@ { --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h -@@ -5303,6 +5303,79 @@ struct wmi_wmm_params_arg { +@@ -5333,6 +5333,79 @@ struct wmi_wmm_params_arg { u8 no_ack; }; @@ -601,7 +601,7 @@ struct wmi_vdev_set_wmm_params_cmd { u32 tlv_header; u32 vdev_id; -@@ -6520,6 +6593,8 @@ int ath11k_wmi_pdev_non_srg_obss_color_e +@@ -6553,6 +6626,8 @@ int ath11k_wmi_pdev_non_srg_obss_color_e u32 *bitmap); int ath11k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(struct ath11k *ar, u32 *bitmap); 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/ath11k_nss/903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch index 86714fea844e81..de7bc77ef53456 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/ath11k_nss/903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch @@ -489,7 +489,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 -@@ -34,6 +34,7 @@ enum ath11k_ast_entry_type { +@@ -23,6 +23,7 @@ enum ath11k_ast_entry_type { enum ath11k_wds_wmi_action { ATH11K_WDS_WMI_ADD = 1, ATH11K_WDS_WMI_UPDATE, 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/ath11k_nss/904-002-ath11k-extend-ext-vdev-in-NSS-for-dynamic-VLAN-handling.patch index c97edcd605d7f1..14274b6a72680a 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/ath11k_nss/904-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 -@@ -1483,14 +1483,11 @@ static int ath11k_nss_ext_vdev_register( +@@ -1570,14 +1570,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, -@@ -1518,7 +1515,8 @@ static void ath11k_nss_ext_vdev_free(str +@@ -1605,7 +1602,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); -@@ -1527,14 +1525,19 @@ static void ath11k_nss_ext_vdev_free(str +@@ -1614,14 +1612,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"); -@@ -1543,8 +1546,8 @@ static int ath11k_nss_ext_vdev_alloc(str +@@ -1630,8 +1633,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; } -@@ -1573,7 +1576,7 @@ int ath11k_nss_ext_vdev_create(struct at +@@ -1660,7 +1663,7 @@ int ath11k_nss_ext_vdev_create(struct at return -EINVAL; } @@ -82,7 +82,7 @@ Signed-off-by: Sathishkumar Muruganandam if (ret) return ret; -@@ -1684,6 +1687,86 @@ free: +@@ -1773,6 +1776,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 -@@ -150,6 +150,10 @@ struct arvif_nss { +@@ -179,6 +179,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; -@@ -215,6 +217,9 @@ void ath11k_nss_ext_vdev_unregister(stru +@@ -246,6 +250,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, -@@ -343,6 +348,18 @@ static inline int ath11k_nss_ext_vdev_do +@@ -378,6 +385,18 @@ static inline int ath11k_nss_ext_vdev_do { return 0; } From 8e2a95f9f421e67360c494d0a3171ea3413d220f Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 8 Jan 2024 03:08:03 -0500 Subject: [PATCH 073/225] ath11k_nss: fix ordering of sysctl values `dev.nss.n2hcfg.n2h_wifi_pool_buf` must be set BEFORE setting `dev.nss.n2hcfg.n2h_high_water_core0`, otherwise it resets the value. --- .../mac80211/files/etc/init.d/qca-nss-pbuf | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf index 40f05c46fb28fb..11604d15dc5c47 100755 --- a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf +++ b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf @@ -18,16 +18,23 @@ START=20 apply_sysctl() { [ $(sysctl -n -e dev.nss.general.redirect) = "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. + extra_pbuf_core0=$(sysctl -n -e dev.nss.n2hcfg.extra_pbuf_core0) - 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 - - 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 > /dev/null 2> /dev/null + if [ "$extra_pbuf_core0" = "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 + else + logger -t ath11k_nss "Sysctl key 'extra_pbuf_core0' already set to '"$extra_pbuf_core0"'. Skipping applying wifi nss configs" + fi 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 > /dev/null 2> /dev/null + 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 + } apply_nss_config() { @@ -51,7 +58,7 @@ apply_nss_config() { qnap,301w | \ xiaomi,ax9000 | \ zyxel,nbg7815) - extra_pbuf_core0=10000000 n2h_high_water_core0=72512 n2h_wifi_pool_buf=36864 apply_sysctl + extra_pbuf_core0=9000000 n2h_high_water_core0=67392 n2h_wifi_pool_buf=40960 apply_sysctl ;; # 512MB profile edimax,cax1800 | \ @@ -79,13 +86,5 @@ start() { exit 1 fi - # 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. - extra_pbuf_core0=$(sysctl -n -e dev.nss.n2hcfg.extra_pbuf_core0) - - if [ "$extra_pbuf_core0" = "0" ]; then - apply_nss_config - else - logger -t ath11k_nss "Sysctl key 'extra_pbuf_core0' already set to '"$extra_pbuf_core0"'. Skipping applying wifi nss configs" - fi + apply_nss_config } From 83d31860f142b59440f6750c0e5c3c7ae0106bf7 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 8 Jan 2024 14:28:17 -0500 Subject: [PATCH 074/225] qualcommax: Set PERFORMANCE as default governor --- target/linux/qualcommax/config-6.1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/target/linux/qualcommax/config-6.1 b/target/linux/qualcommax/config-6.1 index 09b9776d4ac6ef..ba6547e9467913 100644 --- a/target/linux/qualcommax/config-6.1 +++ b/target/linux/qualcommax/config-6.1 @@ -55,6 +55,7 @@ CONFIG_ARM_PSCI_CPUIDLE=y CONFIG_ARM_PSCI_FW=y # CONFIG_ARM_QCOM_CPUFREQ_HW is not set CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y +CONFIG_AT803X_PHY=y CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_SD=y @@ -77,8 +78,8 @@ CONFIG_COREDUMP=y CONFIG_CPUFREQ_DT=y CONFIG_CPUFREQ_DT_PLATDEV=y CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set CONFIG_CPU_FREQ_GOV_ATTR_SET=y CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y CONFIG_CPU_FREQ_GOV_ONDEMAND=y From 05f5c5cf2f297574a6327027d7cf68cb04850cdd Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 8 Jan 2024 01:15:46 -0500 Subject: [PATCH 075/225] qca-ssdk: fix compile warnings + make parallel --- package/kernel/qca-ssdk/Makefile | 10 +++- .../patches/0004-fix-compile-warnings.patch | 56 +++++++++++++++++++ 2 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch diff --git a/package/kernel/qca-ssdk/Makefile b/package/kernel/qca-ssdk/Makefile index c63a22c8e5d620..787bd1e831c8bb 100644 --- a/package/kernel/qca-ssdk/Makefile +++ b/package/kernel/qca-ssdk/Makefile @@ -5,9 +5,9 @@ PKG_RELEASE:=4 PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/qca-ssdk.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2023-10-04 -PKG_SOURCE_VERSION:=23a5aa4a4d5834da7a07efb58baebfbee91786b0 -PKG_MIRROR_HASH:=9d169ce924a46a4e530031061d3183b92f23c7f46b3106f0b9ba3587846a73ee +PKG_SOURCE_DATE:=2023-11-30 +PKG_SOURCE_VERSION:=3153d9068a87198dabf1b8f2c80801fd31a493b3 +PKG_MIRROR_HASH:=05595ba16b22873f5b52609a0ba316ee5264d7fe4ed5b2fb9198da7fe43e4a08 PKG_FLAGS:=nonshared PKG_BUILD_PARALLEL:=1 @@ -53,6 +53,10 @@ ifeq ($(CONFIG_TARGET_SUBTARGET), "ipq807x") MAKE_FLAGS+= CHIP_TYPE=HPPE endif +define Build/Compile + +$(MAKE) $(MAKE_FLAGS) -C $(PKG_BUILD_DIR) $(LNX_CONFIG_OPTS) +endef + define Build/InstallDev $(INSTALL_DIR) $(1)/usr/include/qca-ssdk $(INSTALL_DIR) $(1)/usr/include/qca-ssdk/api diff --git a/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch b/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch new file mode 100644 index 00000000000000..47a7e824c78e8a --- /dev/null +++ b/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch @@ -0,0 +1,56 @@ +--- a/src/adpt/adpt.c ++++ b/src/adpt/adpt.c +@@ -399,11 +399,6 @@ sw_error_t adpt_init(a_uint32_t dev_id, + #endif + #endif + #if defined(HPPE) +-#if defined(FALLTHROUGH) +- fallthrough; +-#else +- /* fall through */ +-#endif + case CHIP_HPPE: + if (g_adpt_api[dev_id] == NULL) { + g_adpt_api[dev_id] = aos_mem_alloc(sizeof(adpt_api_t)); +--- a/src/fal/fal_port_ctrl.c ++++ b/src/fal/fal_port_ctrl.c +@@ -2089,7 +2089,7 @@ fal_port_hibernate_get (a_uint32_t dev_i + */ + sw_error_t + fal_port_cdt (a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, +- a_uint32_t * cable_status, a_uint32_t * cable_len) ++ fal_cable_status_t * cable_status, a_uint32_t * cable_len) + { + sw_error_t rv; + +--- a/src/fal/fal_portvlan.c ++++ b/src/fal/fal_portvlan.c +@@ -2173,7 +2173,7 @@ fal_netisolate_get(a_uint32_t dev_id, a_ + * @return SW_OK or error code + */ + sw_error_t +-fal_eg_trans_filter_bypass_en_set(a_uint32_t dev_id, a_bool_t enable) ++fal_eg_trans_filter_bypass_en_set(a_uint32_t dev_id, a_uint32_t enable) + { + sw_error_t rv; + +@@ -2190,7 +2190,7 @@ fal_eg_trans_filter_bypass_en_set(a_uint + * @return SW_OK or error code + */ + sw_error_t +-fal_eg_trans_filter_bypass_en_get(a_uint32_t dev_id, a_bool_t* enable) ++fal_eg_trans_filter_bypass_en_get(a_uint32_t dev_id, a_uint32_t* enable) + { + sw_error_t rv; + +--- a/Makefile ++++ b/Makefile +@@ -27,7 +27,7 @@ all: $(BIN_DIR) kslib + # LNX Modules-Style Makefile + #################################################################### + modules: $(BIN_DIR) kslib_c +- mkdir -p ./temp/;cp * ./temp -a;cd ./temp;cp ../Makefile.modules ./Makefile; ++ mkdir -p ./temp/;cp app config include ko_Makefile make Makefile.modules src ./temp -a;cd ./temp;cp ../Makefile.modules ./Makefile; + make -C $(SYS_PATH) M=$(PRJ_PATH)/temp $(LNX_MAKEOPTS) modules + cp $(PRJ_PATH)/temp/Module.symvers $(PRJ_PATH)/Module.symvers; + cp temp/*.ko build/bin; From ccae664a3a14bb4729cc90ac29fb73a7799da71f Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 8 Jan 2024 01:15:06 -0500 Subject: [PATCH 076/225] qca-nss-dp: bump version to 12.4.5.r3 --- package/kernel/qca-nss-dp/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package/kernel/qca-nss-dp/Makefile b/package/kernel/qca-nss-dp/Makefile index 708901c782e462..f794d63b6deaf8 100644 --- a/package/kernel/qca-nss-dp/Makefile +++ b/package/kernel/qca-nss-dp/Makefile @@ -1,13 +1,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=qca-nss-dp -PKG_RELEASE:=2 +PKG_RELEASE:=3 PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-dp.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2023-10-04 -PKG_SOURCE_VERSION:=8a21ce862f3129b1d3a7a3f402a0527396da50ab -PKG_MIRROR_HASH:=d2793ebf871b96df2508f628ac9e8ad8b7bd05cd0cf6155fc4f9719ff3d7bf20 +PKG_SOURCE_DATE:=2023-10-16 +PKG_SOURCE_VERSION:=dfeb7d33ca22216a8172d5dd966e4c0db7715b69 +PKG_MIRROR_HASH:=6e0f2d85855acccc791ff041f3b049db4014d561df00bda2f5b102af50496591 PKG_BUILD_PARALLEL:=1 PKG_FLAGS:=nonshared From f1a7d6e6d5a13693ec9d4912186d47a742c7286f Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 8 Jan 2024 18:55:20 -0500 Subject: [PATCH 077/225] qualcommax: add nss-macsec dt support --- .../patches-6.1/9999-add-nss-macsec.patch | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/9999-add-nss-macsec.patch diff --git a/target/linux/qualcommax/patches-6.1/9999-add-nss-macsec.patch b/target/linux/qualcommax/patches-6.1/9999-add-nss-macsec.patch new file mode 100644 index 00000000000000..1be086be21789f --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/9999-add-nss-macsec.patch @@ -0,0 +1,13 @@ +--- a/arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi 2024-01-08 16:04:51.957322224 -0500 ++++ b/arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi 2024-01-08 16:09:29.079630738 -0500 +@@ -268,4 +268,10 @@ + }; + }; + }; ++ nss-macsec1 { ++ compatible = "qcom,nss-macsec"; ++ phy_addr = <0x1c>; ++ phy_access_mode = <0x00>; ++ mdiobus = <&mdio>; ++ }; + }; From 19b633d7b5efb36e5d9d7efb2df2ec4cc515659e Mon Sep 17 00:00:00 2001 From: Qosmio Date: Tue, 9 Jan 2024 01:07:01 -0500 Subject: [PATCH 078/225] ath11k_nss: bugfix overwriting high watermark --- package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf index 11604d15dc5c47..e9b6a7221b2484 100755 --- a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf +++ b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf @@ -17,12 +17,11 @@ START=20 apply_sysctl() { - [ $(sysctl -n -e dev.nss.general.redirect) = "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. - extra_pbuf_core0=$(sysctl -n -e dev.nss.n2hcfg.extra_pbuf_core0) - - if [ "$extra_pbuf_core0" = "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 else @@ -33,7 +32,7 @@ apply_sysctl() { sysctl -w dev.nss.n2hcfg.n2h_wifi_pool_buf=$n2h_wifi_pool_buf > /dev/null 2> /dev/null 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 > /dev/null 2> /dev/null } From d1fb332119ab0080efa6abedc78bb8aaea800886 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Tue, 9 Jan 2024 21:20:26 -0500 Subject: [PATCH 079/225] ath11k_nss: bugfix change start order value 'dev.nss.n2hcfg.n2h_wifi_pool_buf' was not getting set, wait till after qca-nss-drv is loaded. --- package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf index e9b6a7221b2484..6f5e7ba02153f2 100755 --- a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf +++ b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf @@ -14,14 +14,14 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # -START=20 +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 else @@ -29,10 +29,10 @@ apply_sysctl() { fi 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 > /dev/null 2> /dev/null + 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 > /dev/null 2> /dev/null + sysctl -w dev.nss.n2hcfg.n2h_high_water_core0=$n2h_high_water_core0 } From c43e96d28f4177f594367e592fc4cd7cde42fffd Mon Sep 17 00:00:00 2001 From: Qosmio Date: Tue, 9 Jan 2024 21:31:46 -0500 Subject: [PATCH 080/225] ath11k_nss: finally fix n2hcfg values not being set --- package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf index 6f5e7ba02153f2..50f13b33e89429 100755 --- a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf +++ b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf @@ -28,6 +28,8 @@ apply_sysctl() { 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 + 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 From cc56867614f4f125ce322088b3d411eb511227a4 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Wed, 10 Jan 2024 21:01:36 -0500 Subject: [PATCH 081/225] ath11k_nss: Handle 256/512/1G boards automatically --- package/kernel/mac80211/Makefile | 2 +- package/kernel/mac80211/ath.mk | 45 ++++++--- .../mac80211/files/etc/init.d/qca-nss-pbuf | 9 +- ...07-ath11k-Enable-256_512MB-profiles.patch} | 95 +++++++++++++++---- ...11k-Disable-rx_header-tlv-for-2K-SKB.patch | 26 +++-- ...ow-fast-rx-by-bypassing-stats-update.patch | 2 +- 6 files changed, 140 insertions(+), 39 deletions(-) rename package/kernel/mac80211/patches/ath11k_nss/{207-ath11k-Enable-512MB-profile-in-ath11k.patch => 207-ath11k-Enable-256_512MB-profiles.patch} (77%) diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 4886723758f54f..5139e1030d2871 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 PKG_VERSION:=6.5 -PKG_RELEASE:=3 +PKG_RELEASE:=4 # PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.15.58/ PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/ PKG_HASH:=908c22dceba185eab83caa5a1e58ce6b3ebdc58f099c3fd3e11c7352ebfab2d7 diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk index 315746abb1fb7a..c10c326d6a3084 100644 --- a/package/kernel/mac80211/ath.mk +++ b/package/kernel/mac80211/ath.mk @@ -14,9 +14,10 @@ PKG_CONFIG_DEPENDS += \ CONFIG_ATH10K_THERMAL \ CONFIG_ATH11K_THERMAL \ CONFIG_ATH_USER_REGD \ + CONFIG_ATH11K_MEM_PROFILE_1G \ CONFIG_ATH11K_MEM_PROFILE_512M \ - CONFIG_ATH11K_NSS_SUPPORT \ - CONFIG_ATH11K_SMART_ANT_ALG + CONFIG_ATH11K_MEM_PROFILE_256M \ + CONFIG_ATH11K_NSS_SUPPORT ifdef CONFIG_PACKAGE_MAC80211_DEBUGFS config-y += \ @@ -59,9 +60,10 @@ config-$(CONFIG_ATH9K_UBNTHSR) += ATH9K_UBNTHSR config-$(CONFIG_ATH10K_LEDS) += ATH10K_LEDS config-$(CONFIG_ATH10K_THERMAL) += ATH10K_THERMAL config-$(CONFIG_ATH11K_THERMAL) += ATH11K_THERMAL +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_SMART_ANT_ALG) += ATH11K_SMART_ANT_ALG config-$(call config_package,ath9k-htc) += ATH9K_HTC config-$(call config_package,ath10k) += ATH10K ATH10K_PCI @@ -332,20 +334,41 @@ define KernelPackage/ath11k/config config ATH11K_NSS_SUPPORT bool "Enable NSS WiFi offload" + select ATH11K_MEM_PROFILE_512M if (TARGET_qualcommax_ipq807x_DEVICE_edimax_cax1800 || \ + TARGET_qualcommax_ipq807x_DEVICE_compex_wpq873 || \ + TARGET_qualcommax_ipq807x_DEVICE_linksys_mx4200v1 || \ + 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 - config ATH11K_MEM_PROFILE_512M - bool "Use limits for the 512MB memory size" - default n + choice + prompt "ATH11K Memory Profile" + default ATH11K_MEM_PROFILE_1G + help + This option allows you to select the memory profile. + It should correspond to the total RAM of your board. + + config ATH11K_MEM_PROFILE_1G + bool "Use 1G memory profile" + help + This allows configuring ath11k for boards with 1GB+ memory. + + config ATH11K_MEM_PROFILE_512M + bool "Use 512MB memory profile" help - This allows selecting the ath11k memory size profile to be used. + This allows configuring ath11k for boards with 512M memory. + The default is 1GB if not selected - config ATH11K_SMART_ANT_ALG - bool "Enable smart antenna" - depends on PACKAGE_ATH_DEBUG - default n + config ATH11K_MEM_PROFILE_256M + bool "Use 256MB memory profile" + help + This allows configuring ath11k for boards with 256M memory. + The default is 1GB if not selected + endchoice endef define KernelPackage/ath11k-ahb diff --git a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf index 50f13b33e89429..260726fb12d871 100755 --- a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf +++ b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf @@ -47,24 +47,29 @@ apply_nss_config() { case "$board" in # 1GB+ profile + arcadyan,aw1000 | \ buffalo,wxr-5950ax12 | \ dynalink,dl-wrx36 | \ edgecore,eap102 | \ - linksys,mx5300 | \ linksys,mx4200v2 | \ + linksys,mx5300 | \ netgear,rax120v2 | \ netgear,wax620 | \ netgear,wax630 | \ prpl,haze | \ qnap,301w | \ xiaomi,ax9000 | \ + yuncore,ax880 | \ zyxel,nbg7815) extra_pbuf_core0=9000000 n2h_high_water_core0=67392 n2h_wifi_pool_buf=40960 apply_sysctl ;; # 512MB profile edimax,cax1800 | \ + compex,wpq873 | \ linksys,mx4200v1 | \ - xiaomi,ax3600) # 512MB profile + redmi,ax6 | \ + xiaomi,ax3600 | \ + zte,mf269) # 512MB profile extra_pbuf_core0=3100000 n2h_high_water_core0=30624 n2h_wifi_pool_buf=8192 apply_sysctl ;; # 256MB profile diff --git a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-512MB-profile-in-ath11k.patch b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch similarity index 77% rename from package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-512MB-profile-in-ath11k.patch rename to package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch index 0e7ddb8539a207..a4c063ce69ba49 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-512MB-profile-in-ath11k.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch @@ -22,7 +22,7 @@ Signed-off-by: Ramya Gnanasekar --- a/drivers/net/wireless/ath/ath11k/Kconfig +++ b/drivers/net/wireless/ath/ath11k/Kconfig -@@ -23,6 +23,13 @@ config ATH11K_NSS_SUPPORT +@@ -23,6 +23,20 @@ config ATH11K_NSS_SUPPORT If unsure, say Y to enable NSS offload support. @@ -32,36 +32,59 @@ Signed-off-by: Ramya Gnanasekar + default n + ---help--- + Enables 512MB memory profile for ath11k ++ ++config ATH11K_MEM_PROFILE_256M ++ bool "ath11k enable 256MB memory profile" ++ depends on ATH11K ++ default n ++ ---help--- ++ Enables 256MB memory profile for ath11k + config ATH11K_AHB tristate "Atheros ath11k AHB support" depends on m --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h -@@ -11,11 +11,30 @@ +@@ -11,11 +11,43 @@ #include "wmi.h" /* Target configuration defines */ -+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M - ++#if defined(CPTCFG_ATH11K_MEM_PROFILE_256M) ++#define TARGET_NUM_VDEVS 8 ++#define TARGET_NUM_PEERS_PDEV (128 + TARGET_NUM_VDEVS) ++/* Max num of stations (per radio) */ ++#define TARGET_NUM_STATIONS 128 ++#define ATH11K_QMI_TARGET_MEM_MODE ATH11K_QMI_TARGET_MEM_MODE_512M ++#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) +#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) - - #define TARGET_NUM_PEERS_PDEV(ab) (ab->hw_params.num_peers + TARGET_NUM_VDEVS(ab)) +-#define TARGET_NUM_VDEVS(ab) (ab->hw_params.num_vdevs) +- +-#define TARGET_NUM_PEERS_PDEV(ab) (ab->hw_params.num_peers + TARGET_NUM_VDEVS(ab)) ++#define TARGET_NUM_VDEVS(ab) (ab->hw_params.num_vdevs_peers[ab->qmi.target_mem_mode].num_vdevs) ++#define TARGET_NUM_PEERS_PDEV(ab) (ab->hw_params.num_vdevs_peers[ab->qmi.target_mem_mode].num_peers + TARGET_NUM_VDEVS(ab)) +/* Max num of stations (per radio) */ -+#define TARGET_NUM_STATIONS(ab) (ab->hw_params.num_peers) ++#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 @@ -69,7 +92,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 +45,6 @@ +@@ -26,9 +58,6 @@ /* Num of peers for DBS_SBS */ #define TARGET_NUM_PEERS_DBS_SBS(ab) (3 * TARGET_NUM_PEERS_PDEV(ab)) @@ -79,6 +102,14 @@ 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 { + u32 tx_ring_size; + bool smp2p_wow_exit; + bool support_fw_mac_sequence; ++ const struct ath11k_num_vdevs_peers *num_vdevs_peers; + }; + + struct ath11k_hw_ops { --- a/drivers/net/wireless/ath/ath11k/qmi.h +++ b/drivers/net/wireless/ath/ath11k/qmi.h @@ -29,6 +29,12 @@ @@ -107,14 +138,21 @@ Signed-off-by: Ramya Gnanasekar #endif --- a/local-symbols +++ b/local-symbols -@@ -171,6 +171,7 @@ ATH11K= +@@ -171,12 +171,13 @@ ATH11K= ATH11K_AHB= ATH11K_PCI= ATH11K_NSS_SUPPORT= ++ATH11K_MEM_PROFILE_256M= +ATH11K_MEM_PROFILE_512M= ATH11K_DEBUG= ATH11K_DEBUGFS= ATH11K_TRACING= + ATH11K_SPECTRAL= + ATH11K_THERMAL= +-ATH11K_MEM_PROFILE_512M= + ATH12K= + ATH12K_DEBUG= + ATH12K_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 { @@ -226,7 +264,13 @@ Signed-off-by: Ramya Gnanasekar static struct ath11k_hw_params ath11k_hw_params[] = { { .hw_rev = ATH11K_HW_IPQ8074, -@@ -100,6 +104,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -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), @@ -234,7 +278,22 @@ Signed-off-by: Ramya Gnanasekar .supports_regdb = false, .fix_l1ss = true, .credit_flow = false, -@@ -177,7 +182,7 @@ static struct ath11k_hw_params ath11k_hw +- .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,7 +131,9 @@ 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, + .name = "ipq6018 hw1.0", +@@ -177,7 +183,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = true, .coldboot_cal_ftm = true, .cbcal_restart_fw = true, @@ -243,7 +302,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = false, -@@ -259,7 +264,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -259,7 +265,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -252,7 +311,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -426,7 +431,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -426,7 +432,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -261,7 +320,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -509,7 +514,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -509,7 +515,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -270,7 +329,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -593,7 +598,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -593,7 +599,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = true, .coldboot_cal_ftm = true, .cbcal_restart_fw = false, @@ -279,7 +338,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = false, -@@ -672,7 +677,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -672,7 +678,7 @@ static struct ath11k_hw_params ath11k_hw .supports_monitor = false, .supports_sta_ps = false, .supports_shadow_regs = false, @@ -288,7 +347,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_regdb = false, -@@ -710,7 +715,23 @@ static struct ath11k_hw_params ath11k_hw +@@ -710,7 +716,23 @@ static struct ath11k_hw_params ath11k_hw }, }; diff --git a/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch b/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch index 0b9d559a4857ae..87314bc425d3d1 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch @@ -754,10 +754,24 @@ Signed-off-by: Ramya Gnanasekar --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h -@@ -22,6 +22,11 @@ +@@ -22,7 +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 @@ -765,8 +779,8 @@ Signed-off-by: Ramya Gnanasekar +#define ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE 1816 #else /* Num VDEVS per radio */ - #define TARGET_NUM_VDEVS(ab) (ab->hw_params.num_vdevs) -@@ -34,6 +39,8 @@ + #define TARGET_NUM_VDEVS(ab) (ab->hw_params.num_vdevs_peers[ab->qmi.target_mem_mode].num_vdevs) +@@ -47,6 +55,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 @@ -775,7 +789,7 @@ Signed-off-by: Ramya Gnanasekar #endif /* Num of peers for Single Radio mode */ -@@ -129,6 +136,8 @@ enum ath11k_bus { +@@ -142,6 +152,8 @@ enum ath11k_bus { struct hal_rx_desc; struct hal_tcl_data_cmd; @@ -784,7 +798,7 @@ Signed-off-by: Ramya Gnanasekar struct ath11k_hw_ring_mask { u8 tx[ATH11K_EXT_IRQ_GRP_NUM_MAX]; -@@ -218,6 +227,7 @@ struct ath11k_hw_params { +@@ -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; @@ -792,7 +806,7 @@ Signed-off-by: Ramya Gnanasekar bool supports_rssi_stats; bool fw_wmi_diag_event; bool current_cc_support; -@@ -285,6 +295,16 @@ struct ath11k_hw_ops { +@@ -299,6 +312,16 @@ 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); 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/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch index b0f6b03f750f9e..9bc2b50f7cbd45 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch @@ -385,7 +385,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 -@@ -270,6 +270,7 @@ struct ath11k_hw_ops { +@@ -287,6 +287,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); From bec2d457d5045e5e97d9fab9d6ac8e1eb35bd9f9 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Wed, 10 Jan 2024 21:02:52 -0500 Subject: [PATCH 082/225] ath11k_nss: 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 --- .../905-ath11k-add-support-memory-stats.patch | 946 ++++++++++++++++++ 1 file changed, 946 insertions(+) create mode 100644 package/kernel/mac80211/patches/ath11k_nss/905-ath11k-add-support-memory-stats.patch 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 new file mode 100644 index 00000000000000..f4f4389960bd74 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/905-ath11k-add-support-memory-stats.patch @@ -0,0 +1,946 @@ +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, ++ 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); + } + From e0da22d7c91983942c4b813832450e5d931e0ec8 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Wed, 10 Jan 2024 21:08:42 -0500 Subject: [PATCH 083/225] ath11k_nss: add m3 ssr dump. fixes "qmi ignore invalid mem req type" --- .../906-ath11k-m3-ssr-dump-collection.patch | 753 ++++++++++++++++++ 1 file changed, 753 insertions(+) create mode 100644 package/kernel/mac80211/patches/ath11k_nss/906-ath11k-m3-ssr-dump-collection.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/906-ath11k-m3-ssr-dump-collection.patch b/package/kernel/mac80211/patches/ath11k_nss/906-ath11k-m3-ssr-dump-collection.patch new file mode 100644 index 00000000000000..a48875034c96b0 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/906-ath11k-m3-ssr-dump-collection.patch @@ -0,0 +1,753 @@ +--- a/drivers/net/wireless/ath/ath11k/qmi.c ++++ b/drivers/net/wireless/ath/ath11k/qmi.c +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + + #define SLEEP_CLOCK_SELECT_INTERNAL_BIT 0x02 + #define HOST_CSTATE_BIT 0x04 +@@ -292,6 +293,24 @@ static const struct qmi_elem_info qmi_wl + .ei_array = qmi_response_type_v01_ei, + }, + { ++ .data_type = QMI_OPT_FLAG, ++ .elem_len = 1, ++ .elem_size = sizeof(u8), ++ .array_type = NO_ARRAY, ++ .tlv_type = 0x20, ++ .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, ++ m3_dump_upload_req_enable_valid), ++ }, ++ { ++ .data_type = QMI_UNSIGNED_1_BYTE, ++ .elem_len = 1, ++ .elem_size = sizeof(u8), ++ .array_type = NO_ARRAY, ++ .tlv_type = 0x20, ++ .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, ++ m3_dump_upload_req_enable), ++ }, ++ { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, +@@ -517,6 +536,24 @@ static const struct qmi_elem_info qmi_wl + cal_done_enable), + }, + { ++ .data_type = QMI_OPT_FLAG, ++ .elem_len = 1, ++ .elem_size = sizeof(u8), ++ .array_type = NO_ARRAY, ++ .tlv_type = 0x20, ++ .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, ++ m3_dump_upload_req_enable_valid), ++ }, ++ { ++ .data_type = QMI_UNSIGNED_1_BYTE, ++ .elem_len = 1, ++ .elem_size = sizeof(u8), ++ .array_type = NO_ARRAY, ++ .tlv_type = 0x20, ++ .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, ++ m3_dump_upload_req_enable), ++ }, ++ { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, +@@ -1705,6 +1742,87 @@ static const struct qmi_elem_info qmi_wl + }, + }; + ++static struct qmi_elem_info qmi_wlanfw_m3_dump_upload_req_ind_msg_v01_ei[] = { ++ { ++ .data_type = QMI_UNSIGNED_4_BYTE, ++ .elem_len = 1, ++ .elem_size = sizeof(u32), ++ .array_type = NO_ARRAY, ++ .tlv_type = 0x01, ++ .offset = offsetof(struct qmi_wlanfw_m3_dump_upload_req_ind_msg_v01, ++ pdev_id), ++ }, ++ { ++ .data_type = QMI_UNSIGNED_8_BYTE, ++ .elem_len = 1, ++ .elem_size = sizeof(u64), ++ .array_type = NO_ARRAY, ++ .tlv_type = 0x02, ++ .offset = offsetof(struct qmi_wlanfw_m3_dump_upload_req_ind_msg_v01, ++ addr), ++ }, ++ { ++ .data_type = QMI_UNSIGNED_8_BYTE, ++ .elem_len = 1, ++ .elem_size = sizeof(u64), ++ .array_type = NO_ARRAY, ++ .tlv_type = 0x03, ++ .offset = offsetof(struct qmi_wlanfw_m3_dump_upload_req_ind_msg_v01, ++ size), ++ }, ++ { ++ .data_type = QMI_EOTI, ++ .array_type = NO_ARRAY, ++ .tlv_type = QMI_COMMON_TLV_TYPE, ++ }, ++}; ++ ++static struct qmi_elem_info qmi_wlanfw_m3_dump_upload_done_req_msg_v01_ei[] = { ++ { ++ .data_type = QMI_UNSIGNED_4_BYTE, ++ .elem_len = 1, ++ .elem_size = sizeof(u32), ++ .array_type = NO_ARRAY, ++ .tlv_type = 0x01, ++ .offset = offsetof(struct ++ qmi_wlanfw_m3_dump_upload_done_req_msg_v01, ++ pdev_id), ++ }, ++ { ++ .data_type = QMI_UNSIGNED_4_BYTE, ++ .elem_len = 1, ++ .elem_size = sizeof(u32), ++ .array_type = NO_ARRAY, ++ .tlv_type = 0x02, ++ .offset = offsetof(struct ++ qmi_wlanfw_m3_dump_upload_done_req_msg_v01, ++ status), ++ }, ++ { ++ .data_type = QMI_EOTI, ++ .array_type = NO_ARRAY, ++ .tlv_type = QMI_COMMON_TLV_TYPE, ++ }, ++}; ++ ++static struct qmi_elem_info qmi_wlanfw_m3_dump_upload_done_resp_msg_v01_ei[] = { ++ { ++ .data_type = QMI_STRUCT, ++ .elem_len = 1, ++ .elem_size = sizeof(struct qmi_response_type_v01), ++ .array_type = NO_ARRAY, ++ .tlv_type = 0x02, ++ .offset = offsetof(struct qmi_wlanfw_m3_dump_upload_done_resp_msg_v01, ++ resp), ++ .ei_array = qmi_response_type_v01_ei, ++ }, ++ { ++ .data_type = QMI_EOTI, ++ .array_type = NO_ARRAY, ++ .tlv_type = QMI_COMMON_TLV_TYPE, ++ }, ++}; ++ + static int ath11k_qmi_host_cap_send(struct ath11k_base *ab) + { + struct qmi_wlanfw_host_cap_req_msg_v01 req; +@@ -1817,6 +1935,8 @@ static int ath11k_qmi_fw_ind_register_se + + req->pin_connect_result_enable_valid = 0; + req->pin_connect_result_enable = 0; ++ req->m3_dump_upload_req_enable_valid = 1; ++ req->m3_dump_upload_req_enable = 1; + + /* WCN6750 doesn't request for DDR memory via QMI, + * instead it uses a fixed 12MB reserved memory +@@ -2101,6 +2221,33 @@ static int ath11k_qmi_assign_target_mem_ + ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type; + idx++; + break; ++ case M3_DUMP_REGION_TYPE: ++ if (!ab->qmi.target_mem[i].size) { ++ ath11k_info(ab, "qmi mem size is zero\n"); ++ return -EINVAL; ++ } ++ if (ab->qmi.target_mem[i].size > ATH11K_QMI_M3_DUMP_SIZE) { ++ ath11k_warn(ab, "qmi mem size is low to dump m3 ssr\n"); ++ return -EINVAL; ++ } ++ ++ ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size; ++ ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type; ++ if (hremote_node) { ++ ab->qmi.target_mem[idx].paddr = ++ res.start + ATH11K_HOST_DDR_M3_OFFSET; ++ } else if (ath11k_host_ddr_addr) { ++ ab->qmi.target_mem[idx].paddr = ++ ath11k_host_ddr_addr + ATH11K_HOST_DDR_M3_OFFSET; ++ } else { ++ ab->qmi.target_mem[idx].paddr = ab->hw_params.m3_addr; ++ } ++ ++ ab->qmi.target_mem[idx].vaddr = ++ ioremap(ab->qmi.target_mem[idx].paddr, ++ ab->qmi.target_mem[i].size); ++ idx++; ++ break; + default: + ath11k_warn(ab, "qmi ignore invalid mem req type %d\n", + ab->qmi.target_mem[i].type); +@@ -2893,6 +3040,114 @@ static int ath11k_qmi_process_coldboot_c + return 0; + } + ++static int ath11k_qmi_m3_dump_upload_done_ind_send(struct ath11k_base *ab, ++ u32 pdev_id, int status) ++{ ++ struct qmi_wlanfw_m3_dump_upload_done_req_msg_v01 *req; ++ struct qmi_wlanfw_m3_dump_upload_done_resp_msg_v01 *resp; ++ struct qmi_txn txn = {}; ++ int ret = 0; ++ ++ req = kzalloc(sizeof(*req), GFP_KERNEL); ++ if (!req) ++ return -ENOMEM; ++ ++ resp = kzalloc(sizeof(*resp), GFP_KERNEL); ++ if (!resp) { ++ kfree(req); ++ return -ENOMEM; ++ } ++ ++ req->pdev_id = pdev_id; ++ req->status = status; ++ ++ ret = qmi_txn_init(&ab->qmi.handle, &txn, ++ qmi_wlanfw_m3_dump_upload_done_resp_msg_v01_ei, resp); ++ if (ret < 0) ++ goto out; ++ ++ ret = ++ qmi_send_request(&ab->qmi.handle, NULL, &txn, ++ QMI_WLFW_M3_DUMP_UPLOAD_DONE_REQ_V01, ++ QMI_WLANFW_M3_DUMP_UPLOAD_DONE_REQ_MSG_V01_MAX_MSG_LEN, ++ qmi_wlanfw_m3_dump_upload_done_req_msg_v01_ei, req); ++ if (ret < 0) { ++ qmi_txn_cancel(&txn); ++ ath11k_warn(ab, "Failed to send M3 dump upload done request, err %d\n", ++ ret); ++ goto out; ++ } ++ ++ ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS)); ++ if (ret < 0) ++ goto out; ++ ++ if (resp->resp.result != QMI_RESULT_SUCCESS_V01) { ++ ath11k_warn(ab, "qmi M3 upload done req failed, result: %d, err: %d\n", ++ resp->resp.result, resp->resp.error); ++ ret = -EINVAL; ++ goto out; ++ } ++ ath11k_info(ab, "qmi m3 dump uploaded\n"); ++ ++out: ++ kfree(req); ++ kfree(resp); ++ return ret; ++} ++ ++static void ath11k_qmi_event_m3_dump_upload_req(struct ath11k_qmi *qmi, ++ void *data) ++{ ++ struct ath11k_base *ab = qmi->ab; ++ struct target_mem_chunk *target_mem = ab->qmi.target_mem; ++ struct ath11k_qmi_m3_dump_upload_req_data *event_data = data; ++ struct ath11k_qmi_m3_dump_data *m3_dump_data; ++ void *dump; ++ int i, ret = 0; ++ ++ m3_dump_data = kzalloc(sizeof(*m3_dump_data), GFP_KERNEL); ++ if (!m3_dump_data) ++ return; ++ ++ dump = vzalloc(event_data->size); ++ if (!dump) { ++ kfree(m3_dump_data); ++ return; ++ } ++ ++ for (i = 0; i < ab->qmi.mem_seg_count; i++) { ++ if (target_mem[i].paddr == event_data->addr && ++ event_data->size <= target_mem[i].size) ++ break; ++ } ++ ++ if (i == ab->qmi.mem_seg_count) { ++ ath11k_warn(ab, "qmi invalid paddr from firmware for M3 dump\n"); ++ ret = -EINVAL; ++ vfree(dump); ++ goto send_resp; ++ } ++ ++ m3_dump_data->addr = target_mem[i].vaddr; ++ m3_dump_data->size = event_data->size; ++ m3_dump_data->pdev_id = event_data->pdev_id; ++ m3_dump_data->timestamp = ktime_to_ms(ktime_get()); ++ ++ memcpy(dump, m3_dump_data->addr, m3_dump_data->size); ++ ++ dev_coredumpv(ab->dev, dump, le32_to_cpu(m3_dump_data->size), ++ GFP_KERNEL); ++ ++send_resp: ++ ret = ath11k_qmi_m3_dump_upload_done_ind_send(ab, event_data->pdev_id, ret); ++ if (ret < 0) ++ ath11k_warn(ab, "qmi M3 dump upload done failed\n"); ++ ++ kfree(m3_dump_data); ++ return; ++} ++ + static int + ath11k_qmi_driver_event_post(struct ath11k_qmi *qmi, + enum ath11k_qmi_event_type type, +@@ -3093,6 +3348,30 @@ static void ath11k_qmi_msg_fw_init_done_ + ath11k_dbg(ab, ATH11K_DBG_QMI, "firmware init done\n"); + } + ++static void ath11k_qmi_m3_dump_upload_req_ind_cb(struct qmi_handle *qmi_hdl, ++ struct sockaddr_qrtr *sq, ++ struct qmi_txn *txn, ++ const void *data) ++{ ++ struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle); ++ struct ath11k_base *ab = qmi->ab; ++ const struct qmi_wlanfw_m3_dump_upload_req_ind_msg_v01 *msg = data; ++ struct ath11k_qmi_m3_dump_upload_req_data *event_data; ++ ++ ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi m3 dump memory request\n"); ++ ++ event_data = kzalloc(sizeof(*event_data), GFP_KERNEL); ++ if (!event_data) ++ return; ++ ++ event_data->pdev_id = msg->pdev_id; ++ event_data->addr = msg->addr; ++ event_data->size = msg->size; ++ ++ ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_M3_DUMP_UPLOAD_REQ, ++ event_data); ++} ++ + static const struct qmi_msg_handler ath11k_qmi_msg_handlers[] = { + { + .type = QMI_INDICATION, +@@ -3125,13 +3404,20 @@ static const struct qmi_msg_handler ath1 + }, + { + .type = QMI_INDICATION, ++ .msg_id = QMI_WLFW_M3_DUMP_UPLOAD_REQ_IND_V01, ++ .ei = qmi_wlanfw_m3_dump_upload_req_ind_msg_v01_ei, ++ .decoded_size = ++ sizeof(struct qmi_wlanfw_m3_dump_upload_req_ind_msg_v01), ++ .fn = ath11k_qmi_m3_dump_upload_req_ind_cb, ++ }, ++ { ++ .type = QMI_INDICATION, + .msg_id = QMI_WLFW_FW_INIT_DONE_IND_V01, + .ei = qmi_wlfw_fw_init_done_ind_msg_v01_ei, + .decoded_size = + sizeof(struct qmi_wlfw_fw_init_done_ind_msg_v01), + .fn = ath11k_qmi_msg_fw_init_done_cb, + }, +- + /* end of list */ + {}, + }; +@@ -3271,6 +3557,9 @@ static void ath11k_qmi_driver_event_work + break; + case ATH11K_QMI_EVENT_COLD_BOOT_CAL_DONE: + break; ++ case ATH11K_QMI_EVENT_M3_DUMP_UPLOAD_REQ: ++ ath11k_qmi_event_m3_dump_upload_req(qmi, event->data); ++ break; + default: + ath11k_warn(ab, "invalid qmi event type: %d", event->type); + break; +--- a/drivers/net/wireless/ath/ath11k/qmi.h ++++ b/drivers/net/wireless/ath/ath11k/qmi.h +@@ -31,15 +31,21 @@ + + #ifdef CPTCFG_ATH11K_MEM_PROFILE_512M + #define ATH11K_QMI_IPQ8074_M3_DUMP_ADDRESS 0x4E800000 ++#define ATH11K_QMI_IPQ8074_M3_DUMP_OFFSET 0x3800000 + #else + #define ATH11K_QMI_IPQ8074_M3_DUMP_ADDRESS 0x51000000 ++#define ATH11K_QMI_IPQ8074_M3_DUMP_OFFSET 0x6000000 + #endif + ++#define ATH11K_QMI_M3_DUMP_SIZE 0x100000 ++ + #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 + #define QMI_WLFW_FW_READY_IND_V01 0x0021 + #define QMI_WLFW_FW_INIT_DONE_IND_V01 0x0038 ++#define QMI_WLFW_M3_DUMP_UPLOAD_DONE_REQ_V01 0x004E ++#define QMI_WLFW_M3_DUMP_UPLOAD_REQ_IND_V01 0x004D + + #define QMI_WLANFW_MAX_DATA_SIZE_V01 6144 + #define ATH11K_FIRMWARE_MODE_OFF 4 +@@ -47,7 +53,16 @@ + + #define ATH11K_QMI_DEVICE_BAR_SIZE 0x200000 + ++#define ATH11K_HOST_DDR_M3_OFFSET 0x2300000 ++ + struct ath11k_base; ++extern unsigned int ath11k_host_ddr_addr; ++ ++enum ath11k_target_mem_mode { ++ ATH11K_QMI_TARGET_MEM_MODE_DEFAULT = 0, ++ ATH11K_QMI_TARGET_MEM_MODE_512M, ++ ATH11K_QMI_TARGET_MEM_MODE_256M, ++}; + + enum ath11k_qmi_file_type { + ATH11K_QMI_FILE_TYPE_BDF_GOLDEN, +@@ -76,6 +91,7 @@ enum ath11k_qmi_event_type { + ATH11K_QMI_EVENT_FORCE_FW_ASSERT, + ATH11K_QMI_EVENT_POWER_UP, + ATH11K_QMI_EVENT_POWER_DOWN, ++ ATH11K_QMI_EVENT_M3_DUMP_UPLOAD_REQ, + ATH11K_QMI_EVENT_FW_INIT_DONE, + ATH11K_QMI_EVENT_MAX, + }; +@@ -86,6 +102,13 @@ struct ath11k_qmi_driver_event { + void *data; + }; + ++struct ath11k_qmi_m3_dump_data { ++ u32 pdev_id; ++ u32 size; ++ u64 timestamp; ++ u32 *addr; ++}; ++ + struct ath11k_qmi_ce_cfg { + const struct ce_pipe_config *tgt_ce; + int tgt_ce_len; +@@ -150,7 +173,22 @@ struct ath11k_qmi { + wait_queue_head_t cold_boot_waitq; + }; + +-#define QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN 261 ++struct ath11k_qmi_m3_dump_upload_req_data { ++ u32 pdev_id; ++ u64 addr; ++ u64 size; ++}; ++ ++struct qmi_wlanfw_m3_dump_upload_done_req_msg_v01 { ++ u32 pdev_id; ++ u32 status; ++}; ++ ++struct qmi_wlanfw_m3_dump_upload_done_resp_msg_v01 { ++ struct qmi_response_type_v01 resp; ++}; ++ ++#define QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN 194 + #define QMI_WLANFW_HOST_CAP_REQ_V01 0x0034 + #define QMI_WLANFW_HOST_CAP_RESP_MSG_V01_MAX_LEN 7 + #define QMI_WLFW_HOST_CAP_RESP_V01 0x0034 +@@ -226,6 +264,10 @@ struct qmi_wlanfw_ind_register_req_msg_v + u8 xo_cal_enable; + u8 cal_done_enable_valid; + u8 cal_done_enable; ++ u8 respond_get_info_enable_valid; ++ u8 respond_get_info_enable; ++ u8 m3_dump_upload_req_enable_valid; ++ u8 m3_dump_upload_req_enable; + }; + + struct qmi_wlanfw_ind_register_resp_msg_v01 { +@@ -303,6 +345,12 @@ struct qmi_wlfw_fw_init_done_ind_msg_v01 + char placeholder; + }; + ++struct qmi_wlanfw_m3_dump_upload_req_ind_msg_v01 { ++ u32 pdev_id; ++ u64 addr; ++ u64 size; ++}; ++ + #define QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN 0 + #define QMI_WLANFW_CAP_RESP_MSG_V01_MAX_LEN 235 + #define QMI_WLANFW_CAP_REQ_V01 0x0024 +@@ -447,6 +495,8 @@ struct qmi_wlanfw_bdf_download_resp_msg_ + #define QMI_WLANFW_M3_INFO_RESP_V01 0x003C + #define QMI_WLANFW_M3_INFO_REQ_V01 0x003C + ++#define QMI_WLANFW_M3_DUMP_UPLOAD_DONE_REQ_MSG_V01_MAX_MSG_LEN 14 ++ + struct qmi_wlanfw_m3_info_req_msg_v01 { + u64 addr; + u32 size; +@@ -525,10 +575,4 @@ 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); + +-enum ath11k_target_mem_mode { +- ATH11K_QMI_TARGET_MEM_MODE_DEFAULT = 0, +- ATH11K_QMI_TARGET_MEM_MODE_512M, +- ATH11K_QMI_TARGET_MEM_MODE_256M, +-}; +- + #endif +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -638,6 +638,7 @@ struct ath11k_debug { + u32 mem_offset; + u32 module_id_bitmap[MAX_MODULE_ID_BITMAP_WORDS]; + struct ath11k_debug_dbr *dbr_debug[WMI_DIRECT_BUF_MAX]; ++ bool enable_m3_dump; + }; + + struct ath11k_per_peer_tx_stats { +--- a/drivers/net/wireless/ath/ath11k/debugfs.c ++++ b/drivers/net/wireless/ath/ath11k/debugfs.c +@@ -2226,6 +2226,68 @@ static const struct file_operations fops + .llseek = default_llseek, + }; + ++static ssize_t ath11k_write_enable_m3_dump(struct file *file, ++ const char __user *ubuf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath11k *ar = file->private_data; ++ bool enable; ++ int ret; ++ ++ if (kstrtobool_from_user(ubuf, count, &enable)) ++ return -EINVAL; ++ ++ mutex_lock(&ar->conf_mutex); ++ ++ if (ar->state != ATH11K_STATE_ON) { ++ ret = -ENETDOWN; ++ goto exit; ++ } ++ ++ if (enable == ar->debug.enable_m3_dump) { ++ ret = count; ++ goto exit; ++ } ++ ++ ret = ath11k_wmi_pdev_m3_dump_enable(ar, enable); ++ if (ret) { ++ ath11k_warn(ar->ab, ++ "failed to enable m3 ssr dump %d\n", ++ ret); ++ goto exit; ++ } ++ ++ ar->debug.enable_m3_dump = enable; ++ ret = count; ++ ++exit: ++ mutex_unlock(&ar->conf_mutex); ++ return ret; ++} ++ ++static ssize_t ath11k_read_enable_m3_dump(struct file *file, ++ char __user *ubuf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath11k *ar = file->private_data; ++ char buf[32]; ++ size_t len = 0; ++ ++ mutex_lock(&ar->conf_mutex); ++ len = scnprintf(buf, sizeof(buf) - len, "%d\n", ++ ar->debug.enable_m3_dump); ++ mutex_unlock(&ar->conf_mutex); ++ ++ return simple_read_from_buffer(ubuf, count, ppos, buf, len); ++ ++} ++ ++static const struct file_operations fops_enable_m3_dump = { ++ .read = ath11k_read_enable_m3_dump, ++ .write = ath11k_write_enable_m3_dump, ++ .open = simple_open ++}; ++ + int ath11k_debugfs_register(struct ath11k *ar) + { + struct ath11k_base *ab = ar->ab; +@@ -2293,6 +2355,10 @@ int ath11k_debugfs_register(struct ath11 + debugfs_create_file("nss_peer_stats_config", 0644, + ar->debug.debugfs_pdev, ar, &fops_nss_stats); + ++ debugfs_create_file("enable_m3_dump", 0644, ++ ar->debug.debugfs_pdev, ar, ++ &fops_enable_m3_dump); ++ + return 0; + } + void ath11k_debugfs_add_interface(struct ath11k_vif *arvif) +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -9301,6 +9301,36 @@ int ath11k_wmi_fw_dbglog_cfg(struct ath1 + return ret; + } + ++int ath11k_wmi_pdev_m3_dump_enable(struct ath11k *ar, u32 enable) { ++ struct ath11k_vif *arvif; ++ u32 m3_args[WMI_M3_MAX_TEST_ARGS]; ++ struct wmi_unit_test_cmd wmi_ut; ++ bool arvif_found = false; ++ ++ list_for_each_entry(arvif, &ar->arvifs, list) { ++ if (arvif->is_started) { ++ arvif_found = true; ++ break; ++ } ++ } ++ ++ if (!arvif_found) ++ return -EINVAL; ++ ++ m3_args[WMI_M3_TEST_CMDID] = WMI_DBG_ENABLE_M3_SSR; ++ m3_args[WMI_M3_TEST_ENABLE] = enable; ++ ++ wmi_ut.vdev_id = arvif->vdev_id; ++ wmi_ut.module_id = WMI_M3_UNIT_TEST_MODULE; ++ wmi_ut.num_args = WMI_M3_MAX_TEST_ARGS; ++ wmi_ut.diag_token = WMI_M3_UNIT_TEST_TOKEN; ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "%s M3 SSR dump\n", ++ enable ? "Enabling" : "Disabling"); ++ ++ return ath11k_wmi_send_unit_test_cmd(ar, wmi_ut, m3_args); ++} ++ + int ath11k_wmi_connect(struct ath11k_base *ab) + { + u32 i; +--- a/drivers/net/wireless/ath/ath11k/wmi.h ++++ b/drivers/net/wireless/ath/ath11k/wmi.h +@@ -2136,6 +2136,11 @@ enum wmi_tlv_service { + WMI_MAX_EXT2_SERVICE = 384 + }; + ++enum wmi_unit_test_cmdid { ++ /* TODO: Add the remaining cmd ids if needed */ ++ WMI_DBG_ENABLE_M3_SSR = 36, ++}; ++ + enum { + WMI_SMPS_FORCED_MODE_NONE = 0, + WMI_SMPS_FORCED_MODE_DISABLED, +@@ -4116,6 +4121,15 @@ struct wmi_dfs_unit_test_arg { + u32 radar_param; + }; + ++#define WMI_M3_UNIT_TEST_MODULE 0x22 ++#define WMI_M3_UNIT_TEST_TOKEN 0 ++ ++enum wmi_m3_test_args_idx { ++ WMI_M3_TEST_CMDID, ++ WMI_M3_TEST_ENABLE, ++ WMI_M3_MAX_TEST_ARGS, ++}; ++ + struct wmi_unit_test_cmd { + u32 tlv_header; + u32 vdev_id; +@@ -6654,6 +6668,7 @@ int ath11k_wmi_set_hw_mode(struct ath11k + enum wmi_host_hw_mode_config_type mode); + int ath11k_wmi_wow_host_wakeup_ind(struct ath11k *ar); + int ath11k_wmi_wow_enable(struct ath11k *ar); ++int ath11k_wmi_pdev_m3_dump_enable(struct ath11k *ar, u32 enable); + int ath11k_wmi_scan_prob_req_oui(struct ath11k *ar, + const u8 mac_addr[ETH_ALEN]); + int ath11k_wmi_fw_dbglog_cfg(struct ath11k *ar, u32 *module_id_bitmap, +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -44,6 +44,25 @@ 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"); + ++#ifdef CONFIG_QCOM_QMI_HELPERS ++wait_queue_head_t ath11k_ssr_dump_wq; ++EXPORT_SYMBOL(ath11k_ssr_dump_wq); ++ ++bool ath11k_collect_dump = false; ++EXPORT_SYMBOL(ath11k_collect_dump); ++#endif ++ ++unsigned int ath11k_host_ddr_addr; ++EXPORT_SYMBOL(ath11k_host_ddr_addr); ++module_param_named(host_ddr_addr, ath11k_host_ddr_addr, uint, 0644); ++MODULE_PARM_DESC(host_ddr_addr, "host ddr addr for FW"); ++ ++bool dev_init_progress = false; ++EXPORT_SYMBOL(dev_init_progress); ++ ++struct mutex dev_init_lock; ++EXPORT_SYMBOL(dev_init_lock); ++ + static const struct ath11k_num_vdevs_peers ath11k_vdevs_peers[]; + + static struct ath11k_hw_params ath11k_hw_params[] = { +@@ -58,6 +77,7 @@ static struct ath11k_hw_params ath11k_hw + .max_radios = 3, + .bdf_addr = 0x4B0C0000, + .hw_ops = &ipq8074_ops, ++ .m3_addr = ATH11K_QMI_IPQ8074_M3_DUMP_ADDRESS, + .ring_mask = &ath11k_hw_ring_mask_ipq8074, + .internal_sleep_clock = false, + .regs = &ipq8074_regs, +@@ -134,6 +154,8 @@ static struct ath11k_hw_params ath11k_hw + /* 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, ++ .m3_offset = ATH11K_QMI_IPQ8074_M3_DUMP_OFFSET, ++ }, + { + .hw_rev = ATH11K_HW_IPQ6018_HW10, + .name = "ipq6018 hw1.0", +@@ -191,7 +213,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 = false, + .alloc_cacheable_memory = true, +@@ -347,10 +368,10 @@ static struct ath11k_hw_params ath11k_hw + .supports_shadow_regs = false, + .idle_ps = false, + .supports_sta_ps = false, +- .coldboot_cal_mm = false, ++ .coldboot_cal_mm = true, + .coldboot_cal_ftm = true, + .cbcal_restart_fw = true, +- .fw_mem_mode = 2, ++ .fw_mem_mode = ATH11K_QMI_TARGET_MEM_MODE, + .num_vdevs = 8, + .num_peers = 128, + .supports_suspend = false, +--- a/drivers/net/wireless/ath/ath11k/hw.h ++++ b/drivers/net/wireless/ath/ath11k/hw.h +@@ -243,6 +243,7 @@ struct ath11k_hw_params { + const struct ath11k_hw_hal_params *hal_params; + bool supports_dynamic_smps_6ghz; + bool alloc_cacheable_memory; ++ u32 m3_addr; + u8 reo_dest_ring_map_shift; + bool supports_rssi_stats; + bool fw_wmi_diag_event; +@@ -269,6 +270,7 @@ struct ath11k_hw_params { + bool smp2p_wow_exit; + bool support_fw_mac_sequence; + const struct ath11k_num_vdevs_peers *num_vdevs_peers; ++ u32 m3_offset; + }; + + struct ath11k_hw_ops { From 0f6e7aabd442a0772e4d641e7def383cba086504 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Wed, 10 Jan 2024 22:19:51 -0500 Subject: [PATCH 084/225] ath11k_nss: allow specifying pbuf 'memory_profile' In case you want to specify the memory profile to use rather than letting it autodetect. The following new uci option is introduced. pbuf. config general opt option memory_profile '' choices are 1gb, 512mb, 256mb. Delete option to let it autodetect. NOTE: You must reboot after changing these settings, for it to autoapply. --- package/kernel/mac80211/Makefile | 3 +- .../mac80211/files/etc/init.d/qca-nss-pbuf | 29 +++++++++++++++---- package/kernel/mac80211/files/pbuf.uci | 5 ++++ 3 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 package/kernel/mac80211/files/pbuf.uci diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 5139e1030d2871..df4f8be5be20fc 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -424,8 +424,9 @@ endef ifdef CONFIG_ATH11K_NSS_SUPPORT define KernelPackage/ath11k/install - $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_DIR) $(1)/etc/init.d $(1)/etc/config $(INSTALL_BIN) ./files/etc/init.d/qca-nss-pbuf $(1)/etc/init.d + $(INSTALL_BIN) ./files/pbuf.uci $(1)/etc/config/pbuf endef endif diff --git a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf index 260726fb12d871..be89de061ce8b1 100755 --- a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf +++ b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf @@ -43,7 +43,23 @@ apply_nss_config() { 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 - board=$(board_name) + local memory_profile + if memory_profile=$(uci_get pbuf.opt.memory_profile); then + case "$memory_profile" in + 1g*|512m*|256m*) + board=$memory_profile + logger -t ath11k_nss "Using custom memory profile - $board" + ;; + *) + logger -s -t ath11k_nss -p user.error "Unknown profile $memory_profile. Choose 1gb, 512mb, or 256mb" + board=$(board_name) + logger -s -t ath11k_nss -p user.warn "Falling back to: $board" + ;; + esac + else + board=$(board_name) + logger -t ath11k_nss "Setting n2hcfg values for board: $board" + fi case "$board" in # 1GB+ profile @@ -60,7 +76,8 @@ apply_nss_config() { qnap,301w | \ xiaomi,ax9000 | \ yuncore,ax880 | \ - zyxel,nbg7815) + zyxel,nbg7815 | \ + 1g*) extra_pbuf_core0=9000000 n2h_high_water_core0=67392 n2h_wifi_pool_buf=40960 apply_sysctl ;; # 512MB profile @@ -69,11 +86,13 @@ apply_nss_config() { linksys,mx4200v1 | \ redmi,ax6 | \ xiaomi,ax3600 | \ - zte,mf269) # 512MB profile + zte,mf269 | \ + 512m*) extra_pbuf_core0=3100000 n2h_high_water_core0=30624 n2h_wifi_pool_buf=8192 apply_sysctl ;; # 256MB profile - netgear,wax218) + netgear,wax218 | \ + 256m*) extra_pbuf_core0=3100000 n2h_high_water_core0=30258 n2h_wifi_pool_buf=4096 apply_sysctl ;; esac @@ -88,7 +107,7 @@ start() { enable_nss_offload=$(cat /sys/module/ath11k/parameters/nss_offload) if [ "$enable_nss_offload" = "0" ]; then - logger -t ath11k_nss "Module parameter 'nss_offload=0'. Skipping applying wifi nss configs" + logger -t ath11k_nss -s user.warn "Module parameter 'nss_offload=0'. Skipping applying wifi nss configs" exit 1 fi diff --git a/package/kernel/mac80211/files/pbuf.uci b/package/kernel/mac80211/files/pbuf.uci new file mode 100644 index 00000000000000..ac4fadbc4f5e63 --- /dev/null +++ b/package/kernel/mac80211/files/pbuf.uci @@ -0,0 +1,5 @@ +config general opt + # to bypass board autodetection, uncomment ONE of the options below + # option memory_profile '1gb' + # option memory_profile '512mb' + # option memory_profile '256mb' From 1b682285a64d88714329530dd4e6d1b6c50d4f66 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 13 Jan 2024 08:16:22 -0500 Subject: [PATCH 085/225] ath11k_nss: fix compilation and rename some patches --- package/kernel/mac80211/Makefile | 2 +- .../ath11k_nss/199-003-ath11k-add-nss-support.patch | 2 +- ...h => 207-mac80211-Add-support-for-dynamic-vlan.patch} | 0 ...211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch | 9 +++++++++ ...nfig.patch => 902-020-ath11k-add-btcoex-config.patch} | 0 ...h => 902-069-ath11k-add-HE-stats-in-peer-stats.patch} | 0 .../ath11k_nss/905-ath11k-add-support-memory-stats.patch | 2 +- 7 files changed, 12 insertions(+), 3 deletions(-) rename package/kernel/mac80211/patches/ath11k_nss/{207-ath11k-Add-support-for-dynamic-vlan.patch => 207-mac80211-Add-support-for-dynamic-vlan.patch} (100%) rename package/kernel/mac80211/patches/ath11k_nss/{902-ath11k-add-btcoex-config.patch => 902-020-ath11k-add-btcoex-config.patch} (100%) rename package/kernel/mac80211/patches/ath11k_nss/{902-ath11k-add-HE-stats-in-peer-stats.patch => 902-069-ath11k-add-HE-stats-in-peer-stats.patch} (100%) diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index df4f8be5be20fc..713e6d57122a43 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 PKG_VERSION:=6.5 -PKG_RELEASE:=4 +PKG_RELEASE:=5 # PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.15.58/ PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/ PKG_HASH:=908c22dceba185eab83caa5a1e58ce6b3ebdc58f099c3fd3e11c7352ebfab2d7 diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch b/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch index cfe11083939837..ffae0a9448ef8b 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch @@ -1069,7 +1069,7 @@ Signed-off-by: Sriram R /* create list containing all the subframes */ ieee80211_amsdu_to_8023s(skb, &subframe_list, NULL, - vif->type, 0, NULL, NULL); -+ vif->type, 0, NULL, NULL, false); ++ vif->type, 0, NULL, NULL, 0); /* This shouldn't happen, indicating error during defragmentation */ if (skb_queue_empty(&subframe_list)) diff --git a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch b/package/kernel/mac80211/patches/ath11k_nss/207-mac80211-Add-support-for-dynamic-vlan.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch rename to package/kernel/mac80211/patches/ath11k_nss/207-mac80211-Add-support-for-dynamic-vlan.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch b/package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch index b64643140a14b1..70e2603c8cc02b 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch @@ -66,6 +66,15 @@ Signed-off-by: Aaradhana Sahu rcu_read_unlock(); return; } +@@ -4374,7 +4378,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); + ieee80211_xmit(sdata, sta, skb); @@ -4657,19 +4663,29 @@ static bool ieee80211_tx_8023(struct iee static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, diff --git a/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-btcoex-config.patch b/package/kernel/mac80211/patches/ath11k_nss/902-020-ath11k-add-btcoex-config.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-btcoex-config.patch rename to package/kernel/mac80211/patches/ath11k_nss/902-020-ath11k-add-btcoex-config.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-HE-stats-in-peer-stats.patch b/package/kernel/mac80211/patches/ath11k_nss/902-069-ath11k-add-HE-stats-in-peer-stats.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-HE-stats-in-peer-stats.patch rename to package/kernel/mac80211/patches/ath11k_nss/902-069-ath11k-add-HE-stats-in-peer-stats.patch 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 index f4f4389960bd74..734b6fb8c4b160 100644 --- 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 @@ -251,7 +251,7 @@ Signed-off-by: Maharaja Kennadyrajan + +static ssize_t +ath11k_debug_write_enable_memory_stats(struct file *file, -+ char __user *ubuf, ++ const char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct ath11k_base *ab = file->private_data; From 5b6b999491577cb56a7a3357d28d6c342e429290 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 13 Jan 2024 08:19:32 -0500 Subject: [PATCH 086/225] ath11k_nss: ath11k support dynamic vlan also support offload for the following: mac80211: * vlan * mesh (partial) ath11k: * vlan --- ...-ath11k-Add-support-for-dynamic-vlan.patch | 381 ++++ ...00-mac80211-nss-mesh-offload-support.patch | 1241 +++++++++++++ ...TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch | 80 + ...TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch | 45 + .../336-mac80211-Mesh-Fast-rx-support.patch | 208 +++ ...rning-with-monitor-interface-restart.patch | 33 + ...interface-combination-advertisement-.patch | 1594 +++++++++++++++++ .../829-mac80211-fix-mesh-ping-issue.patch | 113 ++ .../902-022-ath11k-add-ap-ps-support.patch | 324 ++++ ...x-memory-corruption-during-mesh-beac.patch | 68 + ...04-300-ath11k-nss_get_arvif_from_dev.patch | 113 ++ ...07-068-ath11k-add-rx-histogram-stats.patch | 608 +++++++ ...ul-ofdma-ru-allocation-in-peer-stats.patch | 452 +++++ ...11k-remove-error-on-soc-debugfs-fail.patch | 146 ++ .../908-301-ath11k-nss-mcbc-exception.patch | 253 +++ ...30-ath11k-sync-wds_ast_entry-updates.patch | 522 ++++++ ...ct-ast-index-assignment-for-wds-peer.patch | 96 + 17 files changed, 6277 insertions(+) create mode 100644 package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/335-0003-ath11k-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/335-0003-mac80211-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/336-mac80211-Mesh-Fast-rx-support.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/353-mac80211-fix-dynamic-vlan-warning-with-monitor-interface-restart.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/675-01-cfg80211-Extend-interface-combination-advertisement-.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/829-mac80211-fix-mesh-ping-issue.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/902-022-ath11k-add-ap-ps-support.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/902-wifi-mac80211-Fix-memory-corruption-during-mesh-beac.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/904-300-ath11k-nss_get_arvif_from_dev.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/907-068-ath11k-add-rx-histogram-stats.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/907-ath11k-remove-error-on-soc-debugfs-fail.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/908-330-ath11k-sync-wds_ast_entry-updates.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/908-362-ath11k-fix-incorrect-ast-index-assignment-for-wds-peer.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch new file mode 100644 index 00000000000000..b17b9fb419745d --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch @@ -0,0 +1,381 @@ +From 71add81f4a3f1ea505f498d789e7a1721c4d7a6e Mon Sep 17 00:00:00 2001 +From: Seevalamuthu Mariappan +Date: Mon, 4 Sep 2023 12:48:19 +0530 +Subject: [PATCH] ath11k: Add support for dynamic vlan + +This patch adds support for dynamic vlan. VLAN group traffics +are encrypted in software. vlan unicast packets shall be taking +8023 xmit path if encap offload is enabled and mcast/bcast will +be using 80211 xmit path. + +Metadata info in dp_tx added to notify firmware that the +multicast/broadcast packets are encrypted in sw. + +Signed-off-by: Seevalamuthu Mariappan +--- + drivers/net/wireless/ath/ath11k/core.h | 1 + + drivers/net/wireless/ath/ath11k/dp_tx.c | 80 +++++++++- + drivers/net/wireless/ath/ath11k/dp_tx.h | 198 ++++++++++++++++++++++++ + drivers/net/wireless/ath/ath11k/mac.c | 3 + + 4 files changed, 279 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -116,6 +116,7 @@ struct ath11k_skb_cb { + u32 cipher; + struct ath11k *ar; + struct ieee80211_vif *vif; ++ u32 pkt_offset; + } __packed; + + struct ath11k_skb_rxcb { +--- a/drivers/net/wireless/ath/ath11k/dp_tx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_tx.c +@@ -79,6 +79,43 @@ enum hal_encrypt_type ath11k_dp_tx_get_e + } + } + ++#define HTT_META_DATA_ALIGNMENT 0x8 ++ ++static int ath11k_dp_metadata_align_skb(struct sk_buff *skb, u8 align_len) ++{ ++ if (unlikely(skb_cow_head(skb, align_len))) ++ return -ENOMEM; ++ ++ skb_push(skb, align_len); ++ memset(skb->data, 0, align_len); ++ return 0; ++} ++ ++static int ath11k_dp_prepare_htt_metadata(struct sk_buff *skb, ++ u8 *htt_metadata_size) ++{ ++ u8 htt_desc_size; ++ /* Size rounded of multiple of 8 bytes */ ++ u8 htt_desc_size_aligned; ++ int ret; ++ struct htt_tx_msdu_desc_ext *desc_ext; ++ ++ htt_desc_size = sizeof(struct htt_tx_msdu_desc_ext); ++ htt_desc_size_aligned = ALIGN(htt_desc_size, HTT_META_DATA_ALIGNMENT); ++ ++ ret = ath11k_dp_metadata_align_skb(skb, htt_desc_size_aligned); ++ if (unlikely(ret)) ++ return ret; ++ ++ desc_ext = (struct htt_tx_msdu_desc_ext *)skb->data; ++ desc_ext->valid_encrypt_type = 1; ++ desc_ext->encrypt_type = 0; ++ desc_ext->host_tx_desc_pool = 1; ++ *htt_metadata_size = htt_desc_size_aligned; ++ ++ return 0; ++} ++ + int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif, + struct ath11k_sta *arsta, struct sk_buff *skb) + { +@@ -96,7 +133,8 @@ int ath11k_dp_tx(struct ath11k *ar, stru + int ret; + u32 ring_selector = 0; + u8 ring_map = 0; +- bool tcl_ring_retry; ++ bool tcl_ring_retry, is_diff_encap = false; ++ u8 align_pad, htt_meta_size = 0; + + if (unlikely(test_bit(ATH11K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags))) + return -ESHUTDOWN; +@@ -189,7 +227,10 @@ tcl_ring_sel: + + switch (ti.encap_type) { + case HAL_TCL_ENCAP_TYPE_NATIVE_WIFI: +- ath11k_dp_tx_encap_nwifi(skb); ++ if (arvif->vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) ++ is_diff_encap = true; ++ else ++ ath11k_dp_tx_encap_nwifi(skb); + break; + case HAL_TCL_ENCAP_TYPE_RAW: + if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) { +@@ -208,6 +249,33 @@ tcl_ring_sel: + goto fail_remove_idr; + } + ++ /* Add metadata for sw encrypted vlan group traffic */ ++ if ((!test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) && ++ !(info->control.flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && ++ !info->control.hw_key && ieee80211_has_protected(hdr->frame_control)) || ++ (skb->protocol == cpu_to_be16(ETH_P_PAE) && is_diff_encap)) { ++ /* HW requirement is that metadata should always point to a ++ * 8-byte aligned address. So we add alignment pad to start of ++ * buffer. HTT Metadata should be ensured to be multiple of 8-bytes ++ * to get 8-byte aligned start address along with align_pad added ++ */ ++ align_pad = ((unsigned long)skb->data) & (HTT_META_DATA_ALIGNMENT - 1); ++ ret = ath11k_dp_metadata_align_skb(skb, align_pad); ++ if (unlikely(ret)) ++ goto fail_remove_idr; ++ ++ ti.pkt_offset += align_pad; ++ ret = ath11k_dp_prepare_htt_metadata(skb, &htt_meta_size); ++ if (unlikely(ret)) ++ goto fail_remove_idr; ++ ++ ti.pkt_offset += htt_meta_size; ++ ti.meta_data_flags |= HTT_TCL_META_DATA_VALID_HTT; ++ ti.flags0 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_TO_FW, 1); ++ ti.encap_type = HAL_TCL_ENCAP_TYPE_RAW; ++ ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN; ++ } ++ + 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); +@@ -216,7 +284,8 @@ tcl_ring_sel: + goto fail_remove_idr; + } + +- ti.data_len = skb->len; ++ ti.data_len = skb->len - ti.pkt_offset; ++ skb_cb->pkt_offset = ti.pkt_offset; + skb_cb->paddr = ti.paddr; + skb_cb->vif = arvif->vif; + skb_cb->ar = ar; +@@ -272,6 +341,8 @@ fail_unmap_dma: + dma_unmap_single(ab->dev, ti.paddr, ti.data_len, DMA_TO_DEVICE); + + fail_remove_idr: ++ if (ti.pkt_offset) ++ skb_pull(skb, ti.pkt_offset); + spin_lock_bh(&tx_ring->tx_idr_lock); + idr_remove(&tx_ring->txbuf_idr, + FIELD_GET(DP_TX_DESC_ID_MSDU_ID, ti.desc_id)); +@@ -358,6 +429,9 @@ ath11k_dp_tx_htt_tx_complete_buf(struct + flags = skb_cb->flags; + vif = skb_cb->vif; + ++ if (skb_cb->pkt_offset) ++ skb_pull(msdu, skb_cb->pkt_offset); /* removing the alignment and htt meta data */ ++ + memset(&info->status, 0, sizeof(info->status)); + + if (ts->acked) { +--- a/drivers/net/wireless/ath/ath11k/dp_tx.h ++++ b/drivers/net/wireless/ath/ath11k/dp_tx.h +@@ -16,6 +16,204 @@ struct ath11k_dp_htt_wbm_tx_status { + u16 peer_id; + }; + ++/* htt_tx_msdu_desc_ext ++ * ++ * valid_pwr ++ * if set, tx pwr spec is valid ++ * ++ * valid_mcs_mask ++ * if set, tx MCS mask is valid ++ * ++ * valid_nss_mask ++ * if set, tx Nss mask is valid ++ * ++ * valid_preamble_type ++ * if set, tx preamble spec is valid ++ * ++ * valid_retries ++ * if set, tx retries spec is valid ++ * ++ * valid_bw_info ++ * if set, tx dyn_bw and bw_mask are valid ++ * ++ * valid_guard_interval ++ * if set, tx guard intv spec is valid ++ * ++ * valid_chainmask ++ * if set, tx chainmask is valid ++ * ++ * valid_encrypt_type ++ * if set, encrypt type is valid ++ * ++ * valid_key_flags ++ * if set, key flags is valid ++ * ++ * valid_expire_tsf ++ * if set, tx expire TSF spec is valid ++ * ++ * valid_chanfreq ++ * if set, chanfreq is valid ++ * ++ * is_dsrc ++ * if set, MSDU is a DSRC frame ++ * ++ * guard_interval ++ * 0.4us, 0.8us, 1.6us, 3.2us ++ * ++ * encrypt_type ++ * 0 = NO_ENCRYPT, ++ * 1 = ENCRYPT, ++ * 2 ~ 3 - Reserved ++ * ++ * retry_limit ++ * Specify the maximum number of transmissions, including the ++ * initial transmission, to attempt before giving up if no ack ++ * is received. ++ * If the tx rate is specified, then all retries shall use the ++ * same rate as the initial transmission. ++ * If no tx rate is specified, the target can choose whether to ++ * retain the original rate during the retransmissions, or to ++ * fall back to a more robust rate. ++ * ++ * use_dcm_11ax ++ * If set, Use Dual subcarrier modulation. ++ * Valid only for 11ax preamble types HE_SU ++ * and HE_EXT_SU ++ * ++ * ltf_subtype_11ax ++ * Takes enum values of htt_11ax_ltf_subtype_t ++ * Valid only for 11ax preamble types HE_SU ++ * and HE_EXT_SU ++ * ++ * dyn_bw ++ * 0 = static bw, 1 = dynamic bw ++ * ++ * bw_mask ++ * Valid only if dyn_bw == 0 (static bw). ++ * ++ * host_tx_desc_pool ++ * If set, Firmware allocates tx_descriptors ++ * in WAL_BUFFERID_TX_HOST_DATA_EXP,instead ++ * of WAL_BUFFERID_TX_TCL_DATA_EXP. ++ * Use cases: ++ * Any time firmware uses TQM-BYPASS for Data ++ * TID, firmware expect host to set this bit. ++ * ++ * power ++ * unit of the power field is 0.5 dbm ++ * signed value ranging from -64dbm to 63.5 dbm ++ * ++ * mcs_mask ++ * mcs bit mask of 0 ~ 11 ++ * Setting more than one MCS isn't currently ++ * supported by the target (but is supported ++ * in the interface in case in the future ++ * the target supports specifications of ++ * a limited set of MCS values. ++ * ++ * nss_mask ++ * Nss bit mask 0 ~ 7 ++ * Setting more than one Nss isn't currently ++ * supported by the target (but is supported ++ * in the interface in case in the future ++ * the target supports specifications of ++ * a limited set of Nss values. ++ * ++ * pream_type ++ * Preamble types ++ * ++ * update_peer_cache ++ * When set these custom values will be ++ * used for all packets, until the next ++ * update via this ext header. ++ * This is to make sure not all packets ++ * need to include this header. ++ * ++ * chain_mask ++ * specify which chains to transmit from ++ * ++ * key_flags ++ * Key Index and related flags - used in mesh mode ++ * ++ * chanfreq ++ * Channel frequency: This identifies the desired channel ++ * frequency (in MHz) for tx frames. This is used by FW to help ++ * determine when it is safe to transmit or drop frames for ++ * off-channel operation. ++ * The default value of zero indicates to FW that the corresponding ++ * VDEV's home channel (if there is one) is the desired channel ++ * frequency. ++ * ++ * expire_tsf_lo ++ * tx expiry time (TSF) LSBs ++ * ++ * expire_tsf_hi ++ * tx expiry time (TSF) MSBs ++ * ++ * learning_frame ++ * When this flag is set, this frame will be dropped by FW ++ * rather than being enqueued to the Transmit Queue Manager (TQM) HW. ++ * ++ * send_as_standalone ++ * This will indicate if the msdu needs to be sent as a singleton PPDU, ++ * i.e. with no A-MSDU or A-MPDU aggregation. ++ * The scope is extended to other use-cases. ++ * ++ * is_host_opaque_valid ++ * set this bit to 1 if the host_opaque_cookie is populated ++ * with valid information. ++ * ++ * host_opaque_cookie ++ * Host opaque cookie for special frames ++ */ ++ ++struct htt_tx_msdu_desc_ext { ++ u32 ++ valid_pwr : 1, ++ valid_mcs_mask : 1, ++ valid_nss_mask : 1, ++ valid_preamble_type : 1, ++ valid_retries : 1, ++ valid_bw_info : 1, ++ valid_guard_interval : 1, ++ valid_chainmask : 1, ++ valid_encrypt_type : 1, ++ valid_key_flags : 1, ++ valid_expire_tsf : 1, ++ valid_chanfreq : 1, ++ is_dsrc : 1, ++ guard_interval : 2, ++ encrypt_type : 2, ++ retry_limit : 4, ++ use_dcm_11ax : 1, ++ ltf_subtype_11ax : 2, ++ dyn_bw : 1, ++ bw_mask : 6, ++ host_tx_desc_pool : 1; ++ u32 ++ power : 8, ++ mcs_mask : 12, ++ nss_mask : 8, ++ pream_type : 3, ++ update_peer_cache : 1; ++ u32 ++ chain_mask : 8, ++ key_flags : 8, ++ chanfreq : 16; ++ ++ u32 expire_tsf_lo; ++ u32 expire_tsf_hi; ++ ++ u32 ++ learning_frame : 1, ++ send_as_standalone : 1, ++ is_host_opaque_valid : 1, ++ rsvd0 : 29; ++ u32 ++ host_opaque_cookie : 16, ++ rsvd1 : 16; ++} __packed; ++ + void ath11k_dp_tx_update_txcompl(struct ath11k *ar, struct hal_tx_status *ts); + int ath11k_dp_tx_htt_h2t_ver_req_msg(struct ath11k_base *ab); + 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 + */ + ar->hw->wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MONITOR); + ++ ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); ++ ar->hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_AP_VLAN); ++ + /* Apply the regd received during initialization */ + ret = ath11k_regd_update(ar); + if (ret) { diff --git a/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch b/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch new file mode 100644 index 00000000000000..7233913ee6f0f7 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch @@ -0,0 +1,1241 @@ +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 +Signed-off-by: Gautham Kumar Senthilkumaran +--- + include/net/mac80211.h | 106 ++ + net/mac80211/cfg.c | 19 +- + net/mac80211/debug.h | 10 + + net/mac80211/debugfs.c | 1 + + net/mac80211/driver-ops.c | 20 + + net/mac80211/driver-ops.h | 7 + + net/mac80211/mesh.h | 5 + + net/mac80211/mesh_hwmp.c | 273 +++++ + net/mac80211/mesh_pathtbl.c | 167 ++- + net/mac80211/rx.c | 8 +- + 10 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/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -145,6 +145,9 @@ + */ + struct device; + ++struct ieee80211_mesh_path_offld; ++enum ieee80211_mesh_path_offld_cmd; ++ + /** + * enum ieee80211_max_queues - maximum number of queues + * +@@ -387,11 +390,17 @@ enum ieee80211_bss_change { + * to indicate which NSS BSS parameter changed. + * + * @BSS_CHANGED_NSS_AP_ISOLATE: AP Isolate feature in NSS mode ++ * @BSS_CHANGED_NSS_MESH_TTL: TTL update in NSS mesh mode ++ * @BSS_CHANGED_NSS_MESH_REFRESH_TIME: Mesh refresh time in NSS mesh mode ++ * @BSS_CHANGED_NSS_MESH_FWD_ENABLED: NSS offload mesh forward enabled + * + */ + + enum ieee80211_nss_bss_change { + BSS_CHANGED_NSS_AP_ISOLATE = BIT(0), ++ BSS_CHANGED_NSS_MESH_TTL = BIT(1), ++ BSS_CHANGED_NSS_MESH_REFRESH_TIME = BIT(2), ++ BSS_CHANGED_NSS_MESH_FWD_ENABLED = BIT(3), + }; + + /* +@@ -794,6 +803,11 @@ struct ieee80211_bss_conf { + bool eht_mu_beamformer; + bool nss_ap_isolate; + enum nl80211_beacon_tx_mode beacon_tx_mode; ++ ++ /* Mesh configuration for nss offload */ ++ u8 nss_offld_ttl; ++ bool nss_offld_mesh_forward_enabled; ++ u32 nss_offld_mpath_refresh_time; + }; + + /** +@@ -1273,6 +1287,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. ++ * @mpdu_succ: Number of mpdus successfully transmitted ++ * @mpdu_fail: Number of mpdus failed + */ + struct ieee80211_tx_status { + struct ieee80211_sta *sta; +@@ -1283,6 +1299,8 @@ struct ieee80211_tx_status { + u8 n_rates; + + struct list_head *free_list; ++ u32 mpdu_succ; ++ u32 mpdu_fail; + }; + + /** +@@ -1775,6 +1793,7 @@ struct ieee80211_channel_switch { + * this is not pure P2P vif. + * @IEEE80211_VIF_DISABLE_SMPS_OVERRIDE: disable user configuration of + * SMPS mode via debugfs. ++ * @IEEE80211_HW_NSS_OFFLOAD_DEBUG_MODE: It enables the debug mode of nss offload. + */ + enum ieee80211_vif_flags { + IEEE80211_VIF_BEACON_FILTER = BIT(0), +@@ -1782,6 +1801,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), ++ IEEE80211_VIF_NSS_OFFLOAD_DEBUG_MODE = BIT(5), + }; + + +@@ -2765,6 +2785,7 @@ enum ieee80211_hw_flags { + IEEE80211_HW_DETECTS_COLOR_COLLISION, + IEEE80211_HW_MLO_MCAST_MULTI_LINK_TX, + IEEE80211_HW_SUPPORTS_NSS_OFFLOAD, ++ IEEE80211_HW_SUPPORTS_MESH_NSS_OFFLOAD, + + /* keep last, obviously */ + NUM_IEEE80211_HW_FLAGS +@@ -4265,6 +4286,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 ++ * @config_mesh_offload_path: Configure mesh path table when driver supports mesh offload. ++ * This calback must be atomic. + * @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 { + void (*sta_set_decap_offload)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, bool enabled); ++#ifdef CPTCFG_MAC80211_MESH ++ void (*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); ++#endif + 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 + void ieee80211_set_active_links_async(struct ieee80211_vif *vif, + u16 active_links); + ++/* Defines for Mesh NSS offload */ ++ ++enum ieee80211_mesh_path_offld_cmd { ++ IEEE80211_MESH_PATH_OFFLD_CMD_ADD_MPATH, ++ IEEE80211_MESH_PATH_OFFLD_CMD_UPDATE_MPATH, ++ IEEE80211_MESH_PATH_OFFLD_CMD_DELETE_MPATH, ++ IEEE80211_MESH_PATH_OFFLD_CMD_ADD_MPP, ++ IEEE80211_MESH_PATH_OFFLD_CMD_UPDATE_MPP, ++ IEEE80211_MESH_PATH_OFFLD_CMD_DELETE_MPP, ++}; ++ ++enum ieee80211_mesh_path_offld_action { ++ IEEE80211_MESH_PATH_OFFLD_ACTION_MPATH_REFRESH = BIT(0), ++ IEEE80211_MESH_PATH_OFFLD_ACTION_MPATH_DEL = BIT(1), ++ IEEE80211_MESH_PATH_OFFLD_ACTION_MPATH_EXP = BIT(2), ++ IEEE80211_MESH_PATH_OFFLD_ACTION_MPP_LEARN = BIT(3), ++ IEEE80211_MESH_PATH_OFFLD_ACTION_MPP_ADD = BIT(4), ++ IEEE80211_MESH_PATH_OFFLD_ACTION_MPP_UPDATE = BIT(5), ++ IEEE80211_MESH_PATH_OFFLD_ACTION_PATH_NOT_FOUND = BIT(6), ++}; ++ ++/* Duplicate defines to make it available to driver */ ++enum ieee80211_mesh_path_flags { ++ IEEE80211_MESH_PATH_ACTIVE = BIT(0), ++ IEEE80211_MESH_PATH_RESOLVING = BIT(1), ++ IEEE80211_MESH_PATH_SN_VALID = BIT(2), ++ IEEE80211_MESH_PATH_FIXED = BIT(3), ++ IEEE80211_MESH_PATH_RESOLVED = BIT(4), ++ IEEE80211_MESH_PATH_REQ_QUEUED = BIT(5), ++ IEEE80211_MESH_PATH_DELETED = BIT(6), ++}; ++ ++struct ieee80211_mesh_path_offld { ++ u8 mesh_da[ETH_ALEN]; ++ u8 da[ETH_ALEN]; ++ u8 next_hop[ETH_ALEN]; ++ u8 old_next_hop[ETH_ALEN]; ++ u8 ta[ETH_ALEN]; ++ u32 metric; ++ unsigned long exp_time; ++ u8 hop_count; ++ u16 flags; /* See &enum ieee80211_mesh_path_flags */ ++ u8 mesh_gate; ++ u8 block_mesh_fwd; ++ u8 metadata_type; ++}; ++ ++#ifdef CPTCFG_MAC80211_MESH ++/** ieee80211_mesh_path_offld_change_notify - Notify mesh path change event. ++ * @vif: Mesh interface on which the event is being reported. ++ * @path: Mesh path which got changed. Please note not all the entries in the ++ * path will have valid information. Based on the action code, it will be ++ * processed. ++ * @action: Type of the event. ++ */ ++int ieee80211_mesh_path_offld_change_notify(struct ieee80211_vif *vif, ++ struct ieee80211_mesh_path_offld *path, ++ enum ieee80211_mesh_path_offld_action action); ++ ++/** ieee80211s_update_metric_ppdu - Upate tx PPDU stats for 11s metric computation ++ * ++ * @hw: the hardware the frame was transmitted by ++ * @st: tx status information ++*/ ++void ieee80211s_update_metric_ppdu(struct ieee80211_hw *hw, ++ struct ieee80211_tx_status *st); ++ ++/** mesh_nss_offld_proxy_path_exp_update - update the expiry time from nss ++ * @vif Mesh interface on which the event is being reported. ++ * @mac: dest_mac_addr of the mesh proxy path ++ * @time_diff: This is the time diff since the mesh peer is active ++ */ ++void mesh_nss_offld_proxy_path_exp_update(struct ieee80211_vif *vif, u8* da, ++ u8* mesh_da, u32 time_diff); ++#else ++static inline int ++ieee80211_mesh_path_offld_change_notify(struct ieee80211_vif *vif, ++ struct ieee80211_mesh_path_offld *path, ++ enum ieee80211_mesh_path_offld_action action) ++{ ++ return 0; ++} ++ ++static inline void ++ieee80211s_update_metric_ppdu(struct ieee80211_hw *hw, ++ struct ieee80211_tx_status *st) ++{ ++} ++ ++static inline void ++mesh_nss_offld_proxy_path_exp_update(struct ieee80211_vif *vif, u8* da, ++ u8* mesh_da, u32 time_diff) ++{ ++} ++#endif ++ + #endif /* MAC80211_H */ +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -2514,6 +2514,7 @@ static int ieee80211_update_mesh_config( + struct mesh_config *conf; + struct ieee80211_sub_if_data *sdata; + struct ieee80211_if_mesh *ifmsh; ++ u32 nss_changed = 0; + + sdata = IEEE80211_DEV_TO_SUB_IF(dev); + ifmsh = &sdata->u.mesh; +@@ -2530,8 +2531,11 @@ static int ieee80211_update_mesh_config( + conf->dot11MeshMaxPeerLinks = nconf->dot11MeshMaxPeerLinks; + if (_chg_mesh_attr(NL80211_MESHCONF_MAX_RETRIES, mask)) + conf->dot11MeshMaxRetries = nconf->dot11MeshMaxRetries; +- if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask)) ++ if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask)) { + conf->dot11MeshTTL = nconf->dot11MeshTTL; ++ sdata->vif.bss_conf.nss_offld_ttl = nconf->dot11MeshTTL; ++ nss_changed |= BSS_CHANGED_NSS_MESH_TTL; ++ } + 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( + if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, mask)) + conf->dot11MeshHWMPmaxPREQretries = + nconf->dot11MeshHWMPmaxPREQretries; +- if (_chg_mesh_attr(NL80211_MESHCONF_PATH_REFRESH_TIME, mask)) ++ if (_chg_mesh_attr(NL80211_MESHCONF_PATH_REFRESH_TIME, mask)) { + conf->path_refresh_time = nconf->path_refresh_time; ++ sdata->vif.bss_conf.nss_offld_mpath_refresh_time = ++ nconf->path_refresh_time; ++ nss_changed |= BSS_CHANGED_NSS_MESH_REFRESH_TIME; ++ } + 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( + if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask)) + conf->dot11MeshHWMPRannInterval = + nconf->dot11MeshHWMPRannInterval; +- if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask)) ++ if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask)) { + conf->dot11MeshForwarding = nconf->dot11MeshForwarding; ++ sdata->vif.bss_conf.nss_offld_mesh_forward_enabled = ++ nconf->dot11MeshForwarding; ++ nss_changed |= BSS_CHANGED_NSS_MESH_FWD_ENABLED; ++ } + 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( + conf->dot11MeshConnectedToAuthServer = + nconf->dot11MeshConnectedToAuthServer; + ieee80211_mbss_info_change_notify(sdata, BSS_CHANGED_BEACON); ++ ieee80211_nss_bss_info_change_notify(sdata, nss_changed); + return 0; + } + +--- a/net/mac80211/debug.h ++++ b/net/mac80211/debug.h +@@ -67,6 +67,12 @@ + #define MAC80211_MESH_PS_DEBUG 0 + #endif + ++#ifdef CPTCFG_MAC80211_MESH_OFFLOAD_DEBUG ++#define MAC80211_MESH_OFFLOAD_DEBUG 1 ++#else ++#define MAC80211_MESH_OFFLOAD_DEBUG 0 ++#endif ++ + #ifdef CPTCFG_MAC80211_TDLS_DEBUG + #define MAC80211_TDLS_DEBUG 1 + #else +@@ -215,6 +221,10 @@ do { \ + _sdata_dbg(MAC80211_MESH_PS_DEBUG, \ + sdata, fmt, ##__VA_ARGS__) + ++#define moffld_dbg(sdata, fmt, ...) \ ++ _sdata_dbg(MAC80211_MESH_OFFLOAD_DEBUG, \ ++ sdata, fmt, ##__VA_ARGS__) ++ + #define tdls_dbg(sdata, fmt, ...) \ + _sdata_dbg(MAC80211_TDLS_DEBUG, \ + sdata, fmt, ##__VA_ARGS__) +--- a/net/mac80211/debugfs.c ++++ b/net/mac80211/debugfs.c +@@ -497,6 +497,7 @@ static const char *hw_flag_names[] = { + FLAG(DETECTS_COLOR_COLLISION), + FLAG(MLO_MCAST_MULTI_LINK_TX), + FLAG(SUPPORTS_NSS_OFFLOAD), ++ FLAG(SUPPORTS_MESH_NSS_OFFLOAD), + #undef FLAG + }; + +--- a/net/mac80211/driver-ops.c ++++ b/net/mac80211/driver-ops.c +@@ -569,3 +569,23 @@ int drv_change_sta_links(struct ieee8021 + + return 0; + } ++ ++#ifdef CPTCFG_MAC80211_MESH ++void drv_config_mesh_offload_path(struct ieee80211_local *local, ++ struct ieee80211_sub_if_data *sdata, ++ enum ieee80211_mesh_path_offld_cmd cmd, ++ struct ieee80211_mesh_path_offld *path) ++{ ++ if (!check_sdata_in_driver(sdata)) ++ return; ++ ++ if (!ieee80211_hw_check(&local->hw, SUPPORTS_MESH_NSS_OFFLOAD)) ++ return; ++ ++ if (local->ops->config_mesh_offload_path) ++ local->ops->config_mesh_offload_path(&local->hw, ++ &sdata->vif, cmd, path); ++ ++ /* TODO: trace event */ ++} ++#endif +--- a/net/mac80211/driver-ops.h ++++ b/net/mac80211/driver-ops.h +@@ -1567,4 +1567,10 @@ int drv_change_sta_links(struct ieee8021 + struct ieee80211_sta *sta, + u16 old_links, u16 new_links); + ++#ifdef CPTCFG_MAC80211_MESH ++void drv_config_mesh_offload_path(struct ieee80211_local *local, ++ struct ieee80211_sub_if_data *sdata, ++ enum ieee80211_mesh_path_offld_cmd cmd, ++ struct ieee80211_mesh_path_offld *path); ++#endif /* CPTCFG_MAC80211_MESH */ + #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 + struct ieee80211_mgmt *mgmt, size_t len); + struct mesh_path * + mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst); ++struct mesh_path *__mesh_path_add(struct ieee80211_sub_if_data *sdata, ++ const u8 *dst); ++int __mpp_path_add(struct ieee80211_sub_if_data *sdata, ++ const u8 *dst, const u8 *mpp); + + 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 + void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata); + + bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt); ++void mesh_nss_offld_path_update(struct mesh_path *mpath, bool is_mpath, u8 *old_next_hop_addr); + struct ieee80211_mesh_fast_tx * + mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, + struct ieee80211_mesh_fast_tx_key *key); +--- a/net/mac80211/mesh_hwmp.c ++++ b/net/mac80211/mesh_hwmp.c +@@ -365,6 +365,13 @@ u32 airtime_link_metric_get(struct ieee8 + return (u32)result; + } + ++static inline struct sta_info * ++next_hop_deref_protected(struct mesh_path *mpath) ++{ ++ return rcu_dereference_protected(mpath->next_hop, ++ lockdep_is_held(&mpath->state_lock)); ++} ++ + /** + * hwmp_route_info_get - Update routing info to originator and transmitter + * +@@ -388,9 +395,10 @@ static u32 hwmp_route_info_get(struct ie + { + struct ieee80211_local *local = sdata->local; + struct mesh_path *mpath; +- struct sta_info *sta; ++ struct sta_info *sta, *next_hop; + bool fresh_info; + const u8 *orig_addr, *ta; ++ u8 old_next_hop_addr[ETH_ALEN] = {0}; + u32 orig_sn, orig_metric; + unsigned long orig_lifetime, exp_time; + u32 last_hop_metric, new_metric; +@@ -492,7 +500,10 @@ static u32 hwmp_route_info_get(struct ie + } + + if (fresh_info) { +- if (rcu_access_pointer(mpath->next_hop) != sta) { ++ next_hop = rcu_dereference(mpath->next_hop); ++ if (next_hop) ++ ether_addr_copy(old_next_hop_addr, next_hop->sta.addr); ++ if (next_hop != sta) { + mpath->path_change_count++; + flush_mpath = true; + } +@@ -514,6 +525,8 @@ static u32 hwmp_route_info_get(struct ie + /* draft says preq_id should be saved to, but there does + * not seem to be any use for it, skipping by now + */ ++ ++ mesh_nss_offld_path_update(mpath, true, old_next_hop_addr); + } else + spin_unlock_bh(&mpath->state_lock); + } +@@ -544,7 +557,14 @@ static u32 hwmp_route_info_get(struct ie + } + + if (fresh_info) { +- if (rcu_access_pointer(mpath->next_hop) != sta) { ++ /* Reset the old_next_hop_addr since this may have filled ++ * if orig_addr and ta are different ++ */ ++ memset(old_next_hop_addr, 0, ETH_ALEN); ++ next_hop = rcu_dereference(mpath->next_hop); ++ if (next_hop) ++ ether_addr_copy(old_next_hop_addr, next_hop->sta.addr); ++ if (next_hop != sta) { + mpath->path_change_count++; + flush_mpath = true; + } +@@ -561,6 +581,8 @@ static u32 hwmp_route_info_get(struct ie + /* init it at a low value - 0 start is tricky */ + ewma_mesh_fail_avg_add(&sta->mesh->fail_avg, 1); + mesh_path_tx_pending(mpath); ++ ++ mesh_nss_offld_path_update(mpath, true, old_next_hop_addr); + } else + spin_unlock_bh(&mpath->state_lock); + } +@@ -697,15 +719,6 @@ static void hwmp_preq_frame_process(stru + } + } + +- +-static inline struct sta_info * +-next_hop_deref_protected(struct mesh_path *mpath) +-{ +- return rcu_dereference_protected(mpath->next_hop, +- lockdep_is_held(&mpath->state_lock)); +-} +- +- + static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata, + struct ieee80211_mgmt *mgmt, + const u8 *prep_elem, u32 metric) +@@ -1349,3 +1362,274 @@ void mesh_path_tx_root_frame(struct ieee + return; + } + } ++ ++static int mesh_path_offld_mpath_refresh(struct ieee80211_sub_if_data *sdata, ++ u8 *mda) ++{ ++ struct mesh_path *mpath; ++ ++ rcu_read_lock(); ++ ++ mpath = mesh_path_lookup(sdata, mda); ++ if (!mpath || !(mpath->flags & MESH_PATH_ACTIVE)) { ++ moffld_dbg(sdata, ++ "mpath lookup failed during path refresh for %pM, is_mpath %d\n", ++ mda, mpath != NULL); ++ rcu_read_unlock(); ++ return -ENOENT; ++ } ++ ++ if (!(mpath->flags & MESH_PATH_RESOLVING) && !(mpath->flags & MESH_PATH_FIXED)) ++ mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); ++ ++ rcu_read_unlock(); ++ ++ return 0; ++} ++ ++static int mesh_path_offld_mpath_del(struct ieee80211_sub_if_data *sdata, u8 *da) ++{ ++ struct mesh_path *mpath, *mppath; ++ ++ rcu_read_lock(); ++ ++ mpath = mesh_path_lookup(sdata, da); ++ if (!mpath) { ++ moffld_dbg(sdata, "mpath lookup failed for %pM during duplicate mpath removal\n", ++ da); ++ rcu_read_unlock(); ++ return -ENOENT; ++ } ++ ++ mppath = mpp_path_lookup(sdata, da); ++ if (!mppath) { ++ moffld_dbg(sdata, "proxy path lookup failed for %pM during duplicate mpath removal\n", ++ da); ++ rcu_read_unlock(); ++ return -EINVAL; ++ } ++ ++ mesh_path_del(sdata, mpath->dst); ++ ++ rcu_read_unlock(); ++ ++ return 0; ++} ++ ++static int mesh_path_offld_mpath_exp(struct ieee80211_sub_if_data *sdata, u8 *mda) ++{ ++ struct mesh_path *mpath; ++ ++ rcu_read_lock(); ++ ++ mpath = mesh_path_lookup(sdata, mda); ++ if (!mpath) { ++ mpath = mesh_path_add(sdata, mda); ++ if (IS_ERR(mpath)) { ++ rcu_read_unlock(); ++ moffld_dbg(sdata, ++ "failed to add mpath for %pM during mpath exp\n", mda); ++ return PTR_ERR(mpath); ++ } ++ } ++ ++ spin_lock_bh(&mpath->state_lock); ++ mpath->flags &= ~MESH_PATH_ACTIVE; ++ spin_unlock_bh(&mpath->state_lock); ++ ++ if (!(mpath->flags & MESH_PATH_RESOLVING) && ++ mesh_path_sel_is_hwmp(sdata)) ++ mesh_queue_preq(mpath, PREQ_Q_F_START); ++ ++ rcu_read_unlock(); ++ ++ return 0; ++} ++ ++static int mesh_path_offld_mpp_learn(struct ieee80211_sub_if_data *sdata, ++ u8 *da, u8 *mda) ++{ ++ struct mesh_path *mppath; ++ int ret; ++ ++ rcu_read_lock(); ++ mppath = mpp_path_lookup(sdata, da); ++ if (mppath) { ++ moffld_dbg(sdata, "proxy path for da %pM mesh_da %pM already exists\n", ++ da, mda); ++ rcu_read_unlock(); ++ return -EEXIST; ++ } ++ ++ ret = mpp_path_add(sdata, da, mda); ++ if (ret) ++ moffld_dbg(sdata, "failed to add proxy path entry (%d): da %pM mesh_da %pM\n", ++ ret, da, mda); ++ ++ rcu_read_unlock(); ++ ++ return ret; ++} ++ ++static int mesh_path_offld_mpp_add(struct ieee80211_sub_if_data *sdata, ++ u8 *da, u8 *mda) ++{ ++ struct mesh_path *mppath; ++ int ret; ++ ++ rcu_read_lock(); ++ mppath = mpp_path_lookup(sdata, da); ++ if (mppath) { ++ moffld_dbg(sdata, "proxy path for da %pM mesh_da %pM already exists\n", ++ da, mda); ++ rcu_read_unlock(); ++ return -EEXIST; ++ } ++ ++ ret = __mpp_path_add(sdata, da, mda); ++ if (ret) ++ moffld_dbg(sdata, "failed to add proxy path entry (%d): da %pM mesh_da %pM\n", ++ ret, da, mda); ++ ++ rcu_read_unlock(); ++ ++ return ret; ++} ++ ++static int mesh_path_offld_mpp_update(struct ieee80211_sub_if_data *sdata, ++ u8 *da, u8 *mda) ++{ ++ struct mesh_path *mppath; ++ ++ rcu_read_lock(); ++ mppath = mpp_path_lookup(sdata, da); ++ if (!mppath) { ++ moffld_dbg(sdata, ++ "proxy path lookup for da %pM failed during MPP update with mesh_da %pM\n", ++ da, mda); ++ rcu_read_unlock(); ++ return -ENOENT; ++ } else { ++ spin_lock_bh(&mppath->state_lock); ++ if (!ether_addr_equal(mppath->mpp, mda)) ++ memcpy(mppath->mpp, mda, ETH_ALEN); ++ mppath->exp_time = jiffies; ++ spin_unlock_bh(&mppath->state_lock); ++ } ++ rcu_read_unlock(); ++ ++ return 0; ++} ++ ++static int mesh_path_offld_mpath_not_found(struct ieee80211_sub_if_data *sdata, ++ u8 *mda, u8 *ta) ++{ ++ struct mesh_path *mpath; ++ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; ++ ++ rcu_read_lock(); ++ ++ mpath = mesh_path_lookup(sdata, mda); ++ if (!mpath) { ++ mpath = mesh_path_add(sdata, mda); ++ if (IS_ERR(mpath)) { ++ moffld_dbg(sdata, "mpath add failed for mesh_da %pM (%lu)\n", ++ mda, PTR_ERR(mpath)); ++ rcu_read_unlock(); ++ return PTR_ERR(mpath); ++ } ++ } ++ ++ if (!(mpath->flags & MESH_PATH_RESOLVING) && ++ mesh_path_sel_is_hwmp(sdata)) ++ mesh_queue_preq(mpath, PREQ_Q_F_START); ++ ++ rcu_read_unlock(); ++ ++ if (!is_zero_ether_addr(ta)) ++ mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl, ++ mda, 0, WLAN_REASON_MESH_PATH_NOFORWARD, ta); ++ ++ return 0; ++} ++ ++void ieee80211s_update_metric_ppdu(struct ieee80211_hw *hw, ++ struct ieee80211_tx_status *st) ++{ ++ struct sta_info *sta; ++ int i, num_mpdu; ++ bool failed; ++ struct rate_info rinfo; ++ ++ if (!st->sta) ++ return; ++ ++ if (st->mpdu_succ) { ++ num_mpdu = st->mpdu_succ; ++ failed = false; ++ } else if (st->mpdu_fail) { ++ num_mpdu = st->mpdu_fail; ++ failed = true; ++ } else ++ return; ++ ++ sta = container_of(st->sta, struct sta_info, sta); ++ if (!ieee80211_vif_is_mesh(&sta->sdata->vif)) ++ return; ++ ++ for (i = 0; i < num_mpdu; i++) { ++ ewma_mesh_fail_avg_add(&sta->mesh->fail_avg, failed * 100); ++ if (ewma_mesh_fail_avg_read(&sta->mesh->fail_avg) > ++ LINK_FAIL_THRESH) ++ mesh_plink_broken(sta); ++ ++ if (!st->rates) ++ continue; ++ ++ rinfo = st->rates->rate_idx; ++ ewma_mesh_tx_rate_avg_add(&sta->mesh->tx_rate_avg, ++ cfg80211_calculate_bitrate(&rinfo)); ++ } ++} ++EXPORT_SYMBOL(ieee80211s_update_metric_ppdu); ++ ++int ieee80211_mesh_path_offld_change_notify(struct ieee80211_vif *vif, ++ struct ieee80211_mesh_path_offld *path, ++ enum ieee80211_mesh_path_offld_action action) ++{ ++ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); ++ int ret = -ENOTSUPP; ++ ++ moffld_dbg(sdata, "received mesh offload event %d\n", action); ++ ++ switch (action) { ++ case IEEE80211_MESH_PATH_OFFLD_ACTION_MPATH_REFRESH: ++ ret = mesh_path_offld_mpath_refresh(sdata, path->mesh_da); ++ break; ++ case IEEE80211_MESH_PATH_OFFLD_ACTION_MPATH_DEL: ++ ret = mesh_path_offld_mpath_del(sdata, path->mesh_da); ++ break; ++ case IEEE80211_MESH_PATH_OFFLD_ACTION_MPATH_EXP: ++ ret = mesh_path_offld_mpath_exp(sdata, path->mesh_da); ++ break; ++ case IEEE80211_MESH_PATH_OFFLD_ACTION_MPP_LEARN: ++ ret = mesh_path_offld_mpp_learn(sdata, path->da, path->mesh_da); ++ break; ++ case IEEE80211_MESH_PATH_OFFLD_ACTION_MPP_ADD: ++ ret = mesh_path_offld_mpp_add(sdata, path->da, path->mesh_da); ++ break; ++ case IEEE80211_MESH_PATH_OFFLD_ACTION_MPP_UPDATE: ++ ret = mesh_path_offld_mpp_update(sdata, path->da, ++ path->mesh_da); ++ break; ++ case IEEE80211_MESH_PATH_OFFLD_ACTION_PATH_NOT_FOUND: ++ ret = mesh_path_offld_mpath_not_found(sdata, path->da, ++ path->ta); ++ break; ++ default: ++ break; ++ } ++ ++ return ret; ++} ++EXPORT_SYMBOL(ieee80211_mesh_path_offld_change_notify); +--- a/net/mac80211/mesh_pathtbl.c ++++ b/net/mac80211/mesh_pathtbl.c +@@ -15,6 +15,7 @@ + #include "ieee80211_i.h" + #include "mesh.h" + #include ++#include "driver-ops.h" + + static void mesh_path_free_rcu(struct mesh_table *tbl, struct mesh_path *mpath); + +@@ -103,6 +104,63 @@ static void mesh_table_free(struct mesh_ + mesh_path_rht_free, tbl); + } + ++void mesh_nss_offld_proxy_path_exp_update(struct ieee80211_vif *vif, u8* da, u8* mesh_da, u32 inactive_time) ++{ ++ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); ++ struct mesh_table *tbl = &sdata->u.mesh.mpp_paths; ++ struct mesh_path *mppath; ++ struct hlist_node *n; ++ unsigned long expiry; ++ ++ spin_lock_bh(&tbl->walk_lock); ++ hlist_for_each_entry_safe(mppath, n, &tbl->walk_head, walk_list) { ++ if(!ether_addr_equal(da, mppath->dst) || !ether_addr_equal(mesh_da, mppath->mpp)) ++ continue; ++ if ((!(mppath->flags & MESH_PATH_RESOLVING)) && ++ (!(mppath->flags & MESH_PATH_FIXED))) { ++ expiry = jiffies - msecs_to_jiffies(inactive_time); ++ mppath->exp_time = time_after(mppath->exp_time, expiry) ? ++ mppath->exp_time : expiry; ++ } ++ } ++ spin_unlock_bh(&tbl->walk_lock); ++} ++EXPORT_SYMBOL(mesh_nss_offld_proxy_path_exp_update); ++ ++void mesh_nss_offld_path_update(struct mesh_path *mpath, bool is_mpath, u8 *old_next_hop_addr) ++{ ++ struct ieee80211_mesh_path_offld path = {0}; ++ struct sta_info *next_hop; ++ struct ieee80211_sub_if_data *sdata = mpath->sdata; ++ ++ ++ path.metric = mpath->metric; ++ if (time_before(jiffies, mpath->exp_time)) ++ path.exp_time = jiffies_to_msecs(mpath->exp_time - jiffies); ++ ++ path.hop_count = mpath->hop_count; ++ path.flags = mpath->flags; ++ path.mesh_gate = mpath->is_gate; ++ if (is_mpath) { ++ ether_addr_copy(path.mesh_da, mpath->dst); ++ } else { ++ ether_addr_copy(path.mesh_da, mpath->mpp); ++ ether_addr_copy(path.da, mpath->dst); ++ } ++ ++ next_hop = rcu_dereference(mpath->next_hop); ++ if (next_hop) ++ ether_addr_copy(path.next_hop, next_hop->addr); ++ ++ if (old_next_hop_addr) ++ ether_addr_copy(path.old_next_hop, old_next_hop_addr); ++ ++ drv_config_mesh_offload_path(sdata->local, sdata, ++ is_mpath ? IEEE80211_MESH_PATH_OFFLD_CMD_UPDATE_MPATH : ++ IEEE80211_MESH_PATH_OFFLD_CMD_UPDATE_MPP, ++ &path); ++} ++ + /** + * mesh_path_assign_nexthop - update mesh path next hop + * +@@ -240,16 +298,23 @@ static void mesh_path_move_to_queue(stru + + + static struct mesh_path *mpath_lookup(struct mesh_table *tbl, const u8 *dst, +- struct ieee80211_sub_if_data *sdata) ++ struct ieee80211_sub_if_data *sdata, ++ bool is_mpath) + { + struct mesh_path *mpath; ++ bool update; ++ struct sta_info *next_hop; + + mpath = rhashtable_lookup(&tbl->rhead, dst, mesh_rht_params); + + if (mpath && mpath_expired(mpath)) { + spin_lock_bh(&mpath->state_lock); ++ next_hop = rcu_dereference(mpath->next_hop); ++ update = !!(mpath->flags & MESH_PATH_ACTIVE); + mpath->flags &= ~MESH_PATH_ACTIVE; + spin_unlock_bh(&mpath->state_lock); ++ if (update && is_mpath) ++ mesh_nss_offld_path_update(mpath, true, next_hop ? next_hop->addr : NULL); + } + return mpath; + } +@@ -266,13 +331,13 @@ static struct mesh_path *mpath_lookup(st + struct mesh_path * + mesh_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst) + { +- return mpath_lookup(&sdata->u.mesh.mesh_paths, dst, sdata); ++ return mpath_lookup(&sdata->u.mesh.mesh_paths, dst, sdata, true); + } + + struct mesh_path * + mpp_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst) + { +- return mpath_lookup(&sdata->u.mesh.mpp_paths, dst, sdata); ++ return mpath_lookup(&sdata->u.mesh.mpp_paths, dst, sdata, false); + } + + static struct mesh_path * +@@ -334,6 +399,7 @@ mpp_path_lookup_by_idx(struct ieee80211_ + int mesh_path_add_gate(struct mesh_path *mpath) + { + struct mesh_table *tbl; ++ struct sta_info *next_hop; + int err; + + rcu_read_lock(); +@@ -346,6 +412,7 @@ int mesh_path_add_gate(struct mesh_path + goto err_rcu; + } + mpath->is_gate = true; ++ next_hop = rcu_dereference(mpath->next_hop); + mpath->sdata->u.mesh.num_gates++; + + spin_lock(&tbl->gates_lock); +@@ -354,6 +421,8 @@ int mesh_path_add_gate(struct mesh_path + + spin_unlock_bh(&mpath->state_lock); + ++ mesh_nss_offld_path_update(mpath, true, next_hop ? next_hop->addr : NULL); ++ + mpath_dbg(mpath->sdata, + "Mesh path: Recorded new gate: %pM. %d known gates\n", + mpath->dst, mpath->sdata->u.mesh.num_gates); +@@ -370,16 +439,21 @@ err_rcu: + */ + static void mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath) + { ++ struct sta_info *next_hop; ++ + lockdep_assert_held(&mpath->state_lock); + if (!mpath->is_gate) + return; + ++ next_hop = rcu_dereference(mpath->next_hop); + mpath->is_gate = false; + spin_lock_bh(&tbl->gates_lock); + hlist_del_rcu(&mpath->gate_list); + mpath->sdata->u.mesh.num_gates--; + spin_unlock_bh(&tbl->gates_lock); + ++ mesh_nss_offld_path_update(mpath, true, next_hop ? next_hop->addr : NULL); ++ + mpath_dbg(mpath->sdata, + "Mesh path: Deleted gate: %pM. %d known gates\n", + mpath->dst, mpath->sdata->u.mesh.num_gates); +@@ -667,17 +741,8 @@ void mesh_fast_tx_flush_addr(struct ieee + spin_unlock_bh(&cache->walk_lock); + } + +-/** +- * mesh_path_add - allocate and add a new path to the mesh path table +- * @dst: destination address of the path (ETH_ALEN length) +- * @sdata: local subif +- * +- * Returns: 0 on success +- * +- * State: the initial state of the new path is set to 0 +- */ +-struct mesh_path *mesh_path_add(struct ieee80211_sub_if_data *sdata, +- const u8 *dst) ++struct mesh_path *__mesh_path_add(struct ieee80211_sub_if_data *sdata, ++ const u8 *dst) + { + struct mesh_table *tbl; + struct mesh_path *mpath, *new_mpath; +@@ -718,8 +783,36 @@ struct mesh_path *mesh_path_add(struct i + return new_mpath; + } + +-int mpp_path_add(struct ieee80211_sub_if_data *sdata, +- const u8 *dst, const u8 *mpp) ++/** ++ * mesh_path_add - allocate and add a new path to the mesh path table ++ * @dst: destination address of the path (ETH_ALEN length) ++ * @sdata: local subif ++ * ++ * Returns: 0 on success ++ * ++ * State: the initial state of the new path is set to 0 ++ */ ++struct mesh_path *mesh_path_add(struct ieee80211_sub_if_data *sdata, ++ const u8 *dst) ++{ ++ struct mesh_path *new_path; ++ struct ieee80211_mesh_path_offld path = {0}; ++ ++ new_path = __mesh_path_add(sdata, dst); ++ if (IS_ERR(new_path)) ++ return new_path; ++ ++ ether_addr_copy(path.mesh_da, dst); ++ ++ drv_config_mesh_offload_path(sdata->local, sdata, ++ IEEE80211_MESH_PATH_OFFLD_CMD_ADD_MPATH, ++ &path); ++ ++ return new_path; ++} ++ ++int __mpp_path_add(struct ieee80211_sub_if_data *sdata, ++ const u8 *dst, const u8 *mpp) + { + struct mesh_table *tbl; + struct mesh_path *new_mpath; +@@ -757,6 +850,25 @@ int mpp_path_add(struct ieee80211_sub_if + return ret; + } + ++int mpp_path_add(struct ieee80211_sub_if_data *sdata, ++ const u8 *dst, const u8 *mpp) ++{ ++ struct ieee80211_mesh_path_offld path = {0}; ++ int ret; ++ ++ ret = __mpp_path_add(sdata, dst, mpp); ++ if (ret) ++ return ret; ++ ++ ether_addr_copy(path.mesh_da, mpp); ++ ether_addr_copy(path.da, dst); ++ ++ drv_config_mesh_offload_path(sdata->local, sdata, ++ IEEE80211_MESH_PATH_OFFLD_CMD_ADD_MPP, ++ &path); ++ ++ return 0; ++} + + /** + * mesh_plink_broken - deactivates paths and sends perr when a link breaks +@@ -807,8 +919,29 @@ static void mesh_path_free_rcu(struct me + kfree_rcu(mpath, rcu); + } + +-static void __mesh_path_del(struct mesh_table *tbl, struct mesh_path *mpath) ++static void __mesh_path_del(struct mesh_table *tbl, struct mesh_path *mpath, ++ bool is_mpath_tbl) + { ++ struct ieee80211_mesh_path_offld path = {0}; ++ struct sta_info *next_hop; ++ struct ieee80211_sub_if_data *sdata = mpath->sdata; ++ ++ ++ path.metric = mpath->metric; ++ path.exp_time = mpath->exp_time; ++ path.hop_count = mpath->hop_count; ++ path.flags = mpath->flags; ++ if (is_mpath_tbl) { ++ ether_addr_copy(path.mesh_da, mpath->dst); ++ } else { ++ ether_addr_copy(path.mesh_da, mpath->mpp); ++ ether_addr_copy(path.da, mpath->dst); ++ } ++ ++ next_hop = rcu_dereference(mpath->next_hop); ++ if (next_hop) ++ ether_addr_copy(path.next_hop, next_hop->addr); ++ + hlist_del_rcu(&mpath->walk_list); + rhashtable_remove_fast(&tbl->rhead, &mpath->rhash, mesh_rht_params); + if (tbl == &mpath->sdata->u.mesh.mpp_paths) +@@ -816,6 +949,11 @@ static void __mesh_path_del(struct mesh_ + else + mesh_fast_tx_flush_mpath(mpath); + mesh_path_free_rcu(tbl, mpath); ++ ++ drv_config_mesh_offload_path(sdata->local, sdata, ++ is_mpath_tbl ? IEEE80211_MESH_PATH_OFFLD_CMD_DELETE_MPATH : ++ IEEE80211_MESH_PATH_OFFLD_CMD_DELETE_MPP, ++ &path); + } + + /** +@@ -839,7 +977,7 @@ void mesh_path_flush_by_nexthop(struct s + spin_lock_bh(&tbl->walk_lock); + hlist_for_each_entry_safe(mpath, n, &tbl->walk_head, walk_list) { + if (rcu_access_pointer(mpath->next_hop) == sta) +- __mesh_path_del(tbl, mpath); ++ __mesh_path_del(tbl, mpath, true); + } + spin_unlock_bh(&tbl->walk_lock); + } +@@ -854,19 +992,19 @@ static void mpp_flush_by_proxy(struct ie + spin_lock_bh(&tbl->walk_lock); + hlist_for_each_entry_safe(mpath, n, &tbl->walk_head, walk_list) { + if (ether_addr_equal(mpath->mpp, proxy)) +- __mesh_path_del(tbl, mpath); ++ __mesh_path_del(tbl, mpath, false); + } + spin_unlock_bh(&tbl->walk_lock); + } + +-static void table_flush_by_iface(struct mesh_table *tbl) ++static void table_flush_by_iface(struct mesh_table *tbl, bool is_mpath_tbl) + { + struct mesh_path *mpath; + struct hlist_node *n; + + spin_lock_bh(&tbl->walk_lock); + hlist_for_each_entry_safe(mpath, n, &tbl->walk_head, walk_list) { +- __mesh_path_del(tbl, mpath); ++ __mesh_path_del(tbl, mpath, is_mpath_tbl); + } + spin_unlock_bh(&tbl->walk_lock); + } +@@ -881,8 +1019,8 @@ static void table_flush_by_iface(struct + */ + void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata) + { +- table_flush_by_iface(&sdata->u.mesh.mesh_paths); +- table_flush_by_iface(&sdata->u.mesh.mpp_paths); ++ table_flush_by_iface(&sdata->u.mesh.mesh_paths, true); ++ table_flush_by_iface(&sdata->u.mesh.mpp_paths, false); + } + + /** +@@ -896,7 +1034,7 @@ void mesh_path_flush_by_iface(struct iee + */ + static int table_path_del(struct mesh_table *tbl, + struct ieee80211_sub_if_data *sdata, +- const u8 *addr) ++ const u8 *addr, bool is_mpath_tbl) + { + struct mesh_path *mpath; + +@@ -907,7 +1045,7 @@ static int table_path_del(struct mesh_ta + return -ENXIO; + } + +- __mesh_path_del(tbl, mpath); ++ __mesh_path_del(tbl, mpath, is_mpath_tbl); + spin_unlock_bh(&tbl->walk_lock); + return 0; + } +@@ -928,7 +1066,7 @@ int mesh_path_del(struct ieee80211_sub_i + /* flush relevant mpp entries first */ + mpp_flush_by_proxy(sdata, addr); + +- err = table_path_del(&sdata->u.mesh.mesh_paths, sdata, addr); ++ err = table_path_del(&sdata->u.mesh.mesh_paths, sdata, addr, true); + sdata->u.mesh.mesh_paths_generation++; + return err; + } +@@ -1031,7 +1169,10 @@ void mesh_path_flush_pending(struct mesh + */ + void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop) + { ++ struct sta_info *old_next_hop; ++ + spin_lock_bh(&mpath->state_lock); ++ old_next_hop = rcu_dereference(mpath->next_hop); + mesh_path_assign_nexthop(mpath, next_hop); + mpath->sn = 0xffff; + mpath->metric = 0; +@@ -1045,6 +1186,8 @@ void mesh_path_fix_nexthop(struct mesh_p + /* init it at a low value - 0 start is tricky */ + ewma_mesh_fail_avg_add(&next_hop->mesh->fail_avg, 1); + mesh_path_tx_pending(mpath); ++ ++ mesh_nss_offld_path_update(mpath, true, old_next_hop ? old_next_hop->addr : NULL); + } + + void mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata) +@@ -1056,7 +1199,7 @@ void mesh_pathtbl_init(struct ieee80211_ + + static + void mesh_path_tbl_expire(struct ieee80211_sub_if_data *sdata, +- struct mesh_table *tbl) ++ struct mesh_table *tbl, bool is_mpath_tbl) + { + struct mesh_path *mpath; + struct hlist_node *n; +@@ -1066,15 +1209,15 @@ void mesh_path_tbl_expire(struct ieee802 + if ((!(mpath->flags & MESH_PATH_RESOLVING)) && + (!(mpath->flags & MESH_PATH_FIXED)) && + time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE)) +- __mesh_path_del(tbl, mpath); ++ __mesh_path_del(tbl, mpath, is_mpath_tbl); + } + spin_unlock_bh(&tbl->walk_lock); + } + + void mesh_path_expire(struct ieee80211_sub_if_data *sdata) + { +- mesh_path_tbl_expire(sdata, &sdata->u.mesh.mesh_paths); +- mesh_path_tbl_expire(sdata, &sdata->u.mesh.mpp_paths); ++ mesh_path_tbl_expire(sdata, &sdata->u.mesh.mesh_paths, true); ++ mesh_path_tbl_expire(sdata, &sdata->u.mesh.mpp_paths, false); + } + + 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 + info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; + #endif + ++ info = IEEE80211_SKB_CB(skb); ++ memset(info, 0, sizeof(*info)); ++ + /* 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 + break; + #ifdef CPTCFG_MAC80211_MESH + case NL80211_IFTYPE_MESH_POINT: ++ if (ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD) && ++ (sdata->vif.driver_flags & IEEE80211_VIF_NSS_OFFLOAD_DEBUG_MODE) && ++ !(is_multicast_ether_addr(skb->data))) { ++ info->flags = IEEE80211_TX_CTL_HW_80211_ENCAP; ++ goto nss_mesh; ++ } ++ + 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 + + skb_reset_mac_header(skb); + +- info = IEEE80211_SKB_CB(skb); +- memset(info, 0, sizeof(*info)); +- +- info->flags = info_flags; ++#ifdef CPTCFG_MAC80211_MESH ++nss_mesh: ++#endif ++ info->flags |= info_flags; + info->ack_frame_id = info_id; + info->band = band; + +@@ -4284,6 +4294,7 @@ void __ieee80211_subif_start_xmit(struct + struct sk_buff *next; + int len = skb->len; + struct ieee80211_key *key = NULL; ++ struct ieee80211_tx_info *info; + 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 + goto out; + } + +- ieee80211_tx_stats(dev, skb->len); +- +- ieee80211_xmit(sdata, sta, skb); ++ info = IEEE80211_SKB_CB(skb); ++ 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); ++ } else { ++ ieee80211_tx_stats(dev, skb->len); ++ ieee80211_xmit(sdata, sta, skb); ++ } + } + goto out; + out_free: 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/ath11k_nss/335-0003-ath11k-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch new file mode 100644 index 00000000000000..1bfbd0ebdbb27e --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/335-0003-ath11k-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch @@ -0,0 +1,80 @@ +From 6a9662d48c4f277380283050370ab3f1f940b6a6 Mon Sep 17 00:00:00 2001 +From: Venkateswara Naralasetty +Date: Mon, 4 Sep 2023 13:44:47 +0530 +Subject: [PATCH] ath11k: skip HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE config + +Don't set HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE flag to TCL, +HW only take care of tid classification if this flag is not set. + +Signed-off-by: Venkateswara Naralasetty +--- + drivers/net/wireless/ath/ath11k/dp_tx.c | 19 +------------------ + drivers/net/wireless/ath/ath11k/hal_tx.c | 1 - + drivers/net/wireless/ath/ath11k/mac.c | 2 ++ + 3 files changed, 3 insertions(+), 19 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/dp_tx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_tx.c +@@ -44,19 +44,6 @@ static void ath11k_dp_tx_encap_nwifi(str + hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA); + } + +-static u8 ath11k_dp_tx_get_tid(struct sk_buff *skb) +-{ +- struct ieee80211_hdr *hdr = (void *)skb->data; +- struct ath11k_skb_cb *cb = ATH11K_SKB_CB(skb); +- +- if (cb->flags & ATH11K_SKB_HW_80211_ENCAP) +- return skb->priority & IEEE80211_QOS_CTL_TID_MASK; +- else if (!ieee80211_is_data_qos(hdr->frame_control)) +- return HAL_DESC_REO_NON_QOS_TID; +- else +- return skb->priority & IEEE80211_QOS_CTL_TID_MASK; +-} +- + 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: + if (ieee80211_vif_is_mesh(arvif->vif)) + ti.enable_mesh = true; + +- ti.flags1 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE, 1); +- +- ti.tid = ath11k_dp_tx_get_tid(skb); +- + switch (ti.encap_type) { + case HAL_TCL_ENCAP_TYPE_NATIVE_WIFI: + if (arvif->vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) +--- a/drivers/net/wireless/ath/ath11k/hal_tx.c ++++ b/drivers/net/wireless/ath/ath11k/hal_tx.c +@@ -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 | +- 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, +--- 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 + ieee80211_hw_set(ar->hw, USES_RSS); + } + ++ ieee80211_hw_set(ar->hw, SUPPORTS_TID_CLASS_OFFLOAD); ++ + ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; + ar->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; + 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/ath11k_nss/335-0003-mac80211-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch new file mode 100644 index 00000000000000..6a37ba0e1aa730 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/335-0003-mac80211-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch @@ -0,0 +1,45 @@ +From c7bd857a315fb299e4c984be2f3720428477ae6e Mon Sep 17 00:00:00 2001 +From: Venkateswara Naralasetty +Date: Thu, 11 Nov 2021 11:14:08 +0530 +Subject: [PATCH] ath11k: skip HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE config + +Don't set HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE flag to TCL, +HW only take care of tid classification if this flag is not set. + +Signed-off-by: Venkateswara Naralasetty +Signed-off-by: Gautham Kumar Senthilkumaran +--- + include/net/mac80211.h | 3 +++ + net/mac80211/debugfs.c | 1 + + net/mac80211/wme.c | 3 +++ + 3 files changed, 7 insertions(+) + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -2727,6 +2727,8 @@ struct ieee80211_txq { + * + * @IEEE80211_HW_SUPPORTS_NSS_OFFLOAD: Hardware/driver supports NSS offload + * ++ * @IEEE80211_HW_SUPPORTS_TID_CLASS_OFFLOAD: Hardware suports tid calssification offload. ++ * + * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays + */ + enum ieee80211_hw_flags { +@@ -2786,6 +2788,7 @@ enum ieee80211_hw_flags { + IEEE80211_HW_MLO_MCAST_MULTI_LINK_TX, + IEEE80211_HW_SUPPORTS_NSS_OFFLOAD, + IEEE80211_HW_SUPPORTS_MESH_NSS_OFFLOAD, ++ IEEE80211_HW_SUPPORTS_TID_CLASS_OFFLOAD, + + /* keep last, obviously */ + NUM_IEEE80211_HW_FLAGS +--- a/net/mac80211/debugfs.c ++++ b/net/mac80211/debugfs.c +@@ -498,6 +498,7 @@ static const char *hw_flag_names[] = { + FLAG(MLO_MCAST_MULTI_LINK_TX), + FLAG(SUPPORTS_NSS_OFFLOAD), + FLAG(SUPPORTS_MESH_NSS_OFFLOAD), ++ FLAG(SUPPORTS_TID_CLASS_OFFLOAD), + #undef FLAG + }; + diff --git a/package/kernel/mac80211/patches/ath11k_nss/336-mac80211-Mesh-Fast-rx-support.patch b/package/kernel/mac80211/patches/ath11k_nss/336-mac80211-Mesh-Fast-rx-support.patch new file mode 100644 index 00000000000000..d29a05f13943bf --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/336-mac80211-Mesh-Fast-rx-support.patch @@ -0,0 +1,208 @@ +From 0f024902a8a54c70204f5b2f824c5dc74888c536 Mon Sep 17 00:00:00 2001 +From: Sriram R +Date: Wed, 29 Sep 2021 09:30:21 +0530 +Subject: [PATCH] mac80211: Add support for mesh fast Rx path + +Add support to process rx frames for the mesh destination +when driver supports fast Rx by offloading PN, Duplicate, +reordering to the HW. + +Fast Rx from a peer is enabled once the PLINK is established. +Fast Rx is not supported for the forwarding path currently. + +Signed-off-by: Sriram R +--- + net/mac80211/cfg.c | 5 + + net/mac80211/ieee80211_i.h | 1 + + net/mac80211/mesh_plink.c | 5 + + net/mac80211/rx.c | 262 ++++++++++++++++++++++++++++++++++++++++++++- + 4 files changed, 269 insertions(+), 4 deletions(-) + +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -1747,6 +1747,8 @@ static void sta_apply_mesh_params(struct + /* init at low value */ + ewma_mesh_tx_rate_avg_add(&sta->mesh->tx_rate_avg, 10); + ++ ieee80211_check_fast_rx(sta); ++ + break; + case NL80211_PLINK_LISTEN: + case NL80211_PLINK_BLOCKED: +@@ -1761,6 +1763,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); ++ ieee80211_check_fast_rx(sta); + break; + default: + /* nothing */ +--- a/net/mac80211/mesh_plink.c ++++ b/net/mac80211/mesh_plink.c +@@ -381,6 +381,8 @@ static u64 __mesh_plink_deactivate(struc + changed |= ieee80211_mps_set_sta_local_pm(sta, + NL80211_MESH_POWER_UNKNOWN); + ++ ieee80211_check_fast_rx(sta); ++ + return changed; + } + +@@ -846,6 +848,7 @@ static u64 mesh_plink_establish(struct i + mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", sta->sta.addr); + ieee80211_mps_sta_status_update(sta); + changed |= ieee80211_mps_set_sta_local_pm(sta, mshcfg->power_mode); ++ ieee80211_check_fast_rx(sta); + return changed; + } + +@@ -864,7 +867,7 @@ static u64 mesh_plink_fsm(struct ieee802 + struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg; + enum ieee80211_self_protected_actioncode action = 0; + u64 changed = 0; +- bool flush = false; ++ bool flush = false, check_fast_rx = false; + + mpl_dbg(sdata, "peer %pM in state %s got event %s\n", sta->sta.addr, + mplstates[sta->mesh->plink_state], mplevents[event]); +@@ -924,6 +927,7 @@ static u64 mesh_plink_fsm(struct ieee802 + break; + case CNF_ACPT: + changed |= mesh_plink_establish(sdata, sta); ++ check_fast_rx = true; + break; + default: + break; +@@ -939,6 +943,7 @@ static u64 mesh_plink_fsm(struct ieee802 + break; + case OPN_ACPT: + changed |= mesh_plink_establish(sdata, sta); ++ check_fast_rx = true; + action = WLAN_SP_MESH_PEERING_CONFIRM; + break; + default: +@@ -985,6 +990,10 @@ static u64 mesh_plink_fsm(struct ieee802 + break; + } + spin_unlock_bh(&sta->mesh->plink_lock); ++ ++ if (check_fast_rx) ++ ieee80211_check_fast_rx(sta); ++ + if (flush) + mesh_path_flush_by_nexthop(sta); + if (action) { +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -4663,10 +4663,15 @@ void ieee80211_check_fast_rx(struct sta_ + + break; + case NL80211_IFTYPE_MESH_POINT: ++ /* Not required for NSS mode */ ++ if (ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) ++ goto clear; ++ /* Note: da and sa offs are not static, determine in fast rx path */ ++ + fastrx.expected_ds_bits = cpu_to_le16(IEEE80211_FCTL_FROMDS | + IEEE80211_FCTL_TODS); +- fastrx.da_offs = offsetof(struct ieee80211_hdr, addr3); +- fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr4); ++ ++ fastrx.internal_forward = 0; + break; + default: + goto clear; +@@ -4707,7 +4712,7 @@ void ieee80211_check_fast_rx(struct sta_ + __release(check_fast_rx); + + if (assign) +- new = kmemdup(&fastrx, sizeof(fastrx), GFP_KERNEL); ++ new = kmemdup(&fastrx, sizeof(fastrx), GFP_ATOMIC); + + 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 + u8 sa[ETH_ALEN]; + } addrs __aligned(2); + struct ieee80211_sta_rx_stats *stats; ++ struct ieee80211s_hdr *mesh_hdr; ++ struct mesh_path *mppath; ++ u8 da_offs = fast_rx->da_offs, sa_offs = fast_rx->sa_offs; ++ struct ieee80211_sub_if_data *sdata = rx->sdata; + + /* 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 + snap_offs += IEEE80211_CCMP_HDR_LEN; + } + ++ /* Find corresponding offsets for mesh hdr */ ++ if (ieee80211_vif_is_mesh(&sdata->vif)) { ++ if (status->rx_flags & IEEE80211_RX_AMSDU) ++ return false; ++ ++ /* All mesh data frames needs to be QoS Data */ ++ if (unlikely(!ieee80211_is_data_qos(hdr->frame_control))) ++ return false; ++ ++ /* TODO forwarding not handled yet in fast rx */ ++ if (!ether_addr_equal(fast_rx->vif_addr, hdr->addr3)) ++ return false; ++ ++ /* Check if Min Mesh hdr is present */ ++ if (!pskb_may_pull(skb, hdrlen + 6)) ++ goto drop; ++ ++ /* Goto mesh hdr, located at snap offs compared to AP/STA */ ++ mesh_hdr = (struct ieee80211s_hdr *) (skb->data + snap_offs); ++ ++ /* Only Ext Mesh hdr supported in this path now */ ++ if ((mesh_hdr->flags & MESH_FLAGS_AE) != MESH_FLAGS_AE_A5_A6) ++ return false; ++ ++ /* Point to eaddr1 and eaddr2 */ ++ da_offs = snap_offs + ETH_ALEN; ++ sa_offs = da_offs + ETH_ALEN; ++ ++ snap_offs += sizeof(struct ieee80211s_hdr); ++ } ++ + 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 + return true; + } + ++ /* Update MPP table for the received packet */ ++ if (ieee80211_vif_is_mesh(&sdata->vif)) { ++ char *proxied_addr, *mpp_addr; ++ ++ mpp_addr = hdr->addr4; ++ proxied_addr = mesh_hdr->eaddr2; ++ ++ /* Update mpp for the SA */ ++ rcu_read_lock(); ++ mppath = mpp_path_lookup(sdata, proxied_addr); ++ if (!mppath) { ++ mpp_path_add(sdata, proxied_addr, mpp_addr); ++ } else { ++ spin_lock_bh(&mppath->state_lock); ++ ++ if (!ether_addr_equal(mppath->mpp, mpp_addr)) ++ ether_addr_copy(mppath->mpp, mpp_addr); ++ ++ mppath->exp_time = jiffies; ++ spin_unlock_bh(&mppath->state_lock); ++ } ++ rcu_read_unlock(); ++ } ++ + /* do the header conversion - first grab the addresses */ +- ether_addr_copy(addrs.da, skb->data + fast_rx->da_offs); +- ether_addr_copy(addrs.sa, skb->data + fast_rx->sa_offs); ++ ether_addr_copy(addrs.da, skb->data + da_offs); ++ ether_addr_copy(addrs.sa, skb->data + sa_offs); + if (ieee80211_vif_is_mesh(&rx->sdata->vif)) { + skb_pull(skb, snap_offs - 2); + put_unaligned_be16(skb->len - 2, skb->data); 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/ath11k_nss/353-mac80211-fix-dynamic-vlan-warning-with-monitor-interface-restart.patch new file mode 100644 index 00000000000000..d128824140ecb6 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/353-mac80211-fix-dynamic-vlan-warning-with-monitor-interface-restart.patch @@ -0,0 +1,33 @@ +From 0628e831520aa2e57aed02aee4a1772b40ce4f9d Mon Sep 17 00:00:00 2001 +From: Nagarajan Maran +Date: Thu, 30 Jun 2022 17:20:29 +0530 +Subject: [PATCH] mac80211: fix dynamic vlan warning with monitor interface restart + +When monitor interface restarts, in nss offload disabled +case, the encap and decap offload flags are removed +from all the interfaces in that phy#. + +However when dynamic VLAN and monitor interfaces are +created in the same phy#, these flags are not updated +correctly, due to which warning calltrace is observed. + +Add condition check to update the correct flags in +dynamic VLAN case. + +Signed-off-by: Nagarajan Maran +--- + net/mac80211/iface.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -994,7 +994,8 @@ static bool ieee80211_set_sdata_offload_ + flags |= IEEE80211_OFFLOAD_DECAP_ENABLED; + + if (local->monitors && +- !ieee80211_hw_check(&local->hw, SUPPORTS_CONC_MON_RX_DECAP)) ++ (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD) || ++ !ieee80211_hw_check(&local->hw, SUPPORTS_CONC_MON_RX_DECAP))) + flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED; + } else { + flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED; 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 new file mode 100644 index 00000000000000..4a8328f4e3ca83 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/675-01-cfg80211-Extend-interface-combination-advertisement-.patch @@ -0,0 +1,1594 @@ +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/829-mac80211-fix-mesh-ping-issue.patch b/package/kernel/mac80211/patches/ath11k_nss/829-mac80211-fix-mesh-ping-issue.patch new file mode 100644 index 00000000000000..7043ecb079061a --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/829-mac80211-fix-mesh-ping-issue.patch @@ -0,0 +1,113 @@ +From a76238143218ea348cec4b5d26fe9411338ae09e Mon Sep 17 00:00:00 2001 +From: Aaradhana Sahu +Date: Fri, 6 Oct 2023 18:19:53 +0530 +Subject: [PATCH] mac80211: fix mesh ping issue + +Signed-off-by: Aaradhana Sahu +--- + net/mac80211/rx.c | 68 +++-------------------------------------------- + 1 file changed, 4 insertions(+), 64 deletions(-) + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -4748,16 +4748,14 @@ void ieee80211_check_fast_rx(struct sta_ + + break; + case NL80211_IFTYPE_MESH_POINT: +- /* Not required for NSS mode */ +- if (ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) +- goto clear; + /* Note: da and sa offs are not static, determine in fast rx path */ + + fastrx.expected_ds_bits = cpu_to_le16(IEEE80211_FCTL_FROMDS | + IEEE80211_FCTL_TODS); +- +- fastrx.internal_forward = 0; +- break; ++ fastrx.da_offs = offsetof(struct ieee80211_hdr, addr3); ++ fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr4); ++ break; ++ + default: + goto clear; + } +@@ -4980,10 +4978,7 @@ static bool ieee80211_invoke_fast_rx(str + u8 sa[ETH_ALEN]; + } addrs __aligned(2); + struct ieee80211_sta_rx_stats *stats; +- struct ieee80211s_hdr *mesh_hdr; +- struct mesh_path *mppath; + u8 da_offs = fast_rx->da_offs, sa_offs = fast_rx->sa_offs; +- struct ieee80211_sub_if_data *sdata = rx->sdata; + + /* 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 + snap_offs += IEEE80211_CCMP_HDR_LEN; + } + +- /* Find corresponding offsets for mesh hdr */ +- if (ieee80211_vif_is_mesh(&sdata->vif)) { +- if (status->rx_flags & IEEE80211_RX_AMSDU) +- return false; +- +- /* All mesh data frames needs to be QoS Data */ +- if (unlikely(!ieee80211_is_data_qos(hdr->frame_control))) +- return false; +- +- /* TODO forwarding not handled yet in fast rx */ +- if (!ether_addr_equal(fast_rx->vif_addr, hdr->addr3)) +- return false; +- +- /* Check if Min Mesh hdr is present */ +- if (!pskb_may_pull(skb, hdrlen + 6)) +- goto drop; +- +- /* Goto mesh hdr, located at snap offs compared to AP/STA */ +- mesh_hdr = (struct ieee80211s_hdr *) (skb->data + snap_offs); +- +- /* Only Ext Mesh hdr supported in this path now */ +- if ((mesh_hdr->flags & MESH_FLAGS_AE) != MESH_FLAGS_AE_A5_A6) +- return false; +- +- /* Point to eaddr1 and eaddr2 */ +- da_offs = snap_offs + ETH_ALEN; +- sa_offs = da_offs + ETH_ALEN; +- +- snap_offs += sizeof(struct ieee80211s_hdr); +- } +- + 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 + return true; + } + +- /* Update MPP table for the received packet */ +- if (ieee80211_vif_is_mesh(&sdata->vif)) { +- char *proxied_addr, *mpp_addr; +- +- mpp_addr = hdr->addr4; +- proxied_addr = mesh_hdr->eaddr2; +- +- /* Update mpp for the SA */ +- rcu_read_lock(); +- mppath = mpp_path_lookup(sdata, proxied_addr); +- if (!mppath) { +- mpp_path_add(sdata, proxied_addr, mpp_addr); +- } else { +- spin_lock_bh(&mppath->state_lock); +- +- if (!ether_addr_equal(mppath->mpp, mpp_addr)) +- ether_addr_copy(mppath->mpp, mpp_addr); +- +- mppath->exp_time = jiffies; +- spin_unlock_bh(&mppath->state_lock); +- } +- rcu_read_unlock(); +- } +- + /* do the header conversion - first grab the addresses */ + ether_addr_copy(addrs.da, skb->data + da_offs); + ether_addr_copy(addrs.sa, skb->data + sa_offs); 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 new file mode 100644 index 00000000000000..52037816a113b1 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/902-022-ath11k-add-ap-ps-support.patch @@ -0,0 +1,324 @@ +--- 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/902-wifi-mac80211-Fix-memory-corruption-during-mesh-beac.patch b/package/kernel/mac80211/patches/ath11k_nss/902-wifi-mac80211-Fix-memory-corruption-during-mesh-beac.patch new file mode 100644 index 00000000000000..ea76cd96327e46 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/902-wifi-mac80211-Fix-memory-corruption-during-mesh-beac.patch @@ -0,0 +1,68 @@ +From 0ff455d1d446e34ae6c2596d4d8491f66fc61913 Mon Sep 17 00:00:00 2001 +From: Manish Dharanenthiran +Date: Sat, 2 Dec 2023 03:38:31 +0530 +Subject: [PATCH] wifi: mac80211: Fix memory corruption during mesh beacon + update + +During mesh beacon update, u64 flag is used to check for +bit set/unset for validation purpose. But, in +'ieee80211_mbss_info_change_notify' API, unsigned long flag +is modified using sizeof(u64). This leads to following issue: + + > 'mbss_changed' flag in 'ieee80211_if_mesh' is declared as + unsigned_long which creates an architecture dependency + (32bit vs 64bit) while modifying it with u64 flag which + leads to memory corruption. + +Fix above mentioned issue by replacing unsigned long with u64 +for changed flag. + +Signed-off-by: Manish Dharanenthiran +--- + net/mac80211/ieee80211_i.h | 2 +- + net/mac80211/mesh.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -683,7 +683,7 @@ struct ieee80211_if_mesh { + struct timer_list mesh_path_root_timer; + + unsigned long wrkq_flags; +- unsigned long mbss_changed[64 / BITS_PER_LONG]; ++ unsigned long mbss_changed; + + bool userspace_handles_dfs; + +--- a/net/mac80211/mesh.c ++++ b/net/mac80211/mesh.c +@@ -1183,7 +1183,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) +- set_bit(bit, ifmsh->mbss_changed); ++ set_bit(bit, &ifmsh->mbss_changed); + 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 + + /* clear any mesh work (for next join) we may have accrued */ + ifmsh->wrkq_flags = 0; +- memset(ifmsh->mbss_changed, 0, sizeof(ifmsh->mbss_changed)); ++ ifmsh->mbss_changed = 0; + + local->fif_other_bss--; + atomic_dec(&local->iff_allmultis); +@@ -1732,9 +1732,9 @@ static void mesh_bss_info_changed(struct + u32 bit; + u64 changed = 0; + +- for_each_set_bit(bit, ifmsh->mbss_changed, ++ for_each_set_bit(bit, &ifmsh->mbss_changed, + sizeof(changed) * BITS_PER_BYTE) { +- clear_bit(bit, ifmsh->mbss_changed); ++ clear_bit(bit, &ifmsh->mbss_changed); + changed |= BIT(bit); + } + 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 new file mode 100644 index 00000000000000..5d695ccfe55f2e --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/904-300-ath11k-nss_get_arvif_from_dev.patch @@ -0,0 +1,113 @@ +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; + } + } +@@ -786,24 +814,7 @@ ath11k_nss_vdev_special_data_receive(str + int ret = 0; + struct ath11k_peer *ta_peer = NULL; + +- 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/907-068-ath11k-add-rx-histogram-stats.patch b/package/kernel/mac80211/patches/ath11k_nss/907-068-ath11k-add-rx-histogram-stats.patch new file mode 100644 index 00000000000000..d3ffa5bd8da8e7 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/907-068-ath11k-add-rx-histogram-stats.patch @@ -0,0 +1,608 @@ +From 4635ca1f29bc5838d556b09e3c186b76a5198ddb Mon Sep 17 00:00:00 2001 +From: Manikanta Pubbisetty +Date: Fri, 18 Aug 2023 11:43:33 +0530 +Subject: [PATCH] ath11k: add rx histogram stats + +Adding rx rate table and byte level peer rx statistics. Also, +adding a debugfs knob to reset rx stats specific to the peer. + +Signed-off-by: Manikanta Pubbisetty +--- + drivers/net/wireless/ath/ath11k/core.h | 19 ++- + drivers/net/wireless/ath/ath11k/debugfs_sta.c | 152 ++++++++++++++++-- + drivers/net/wireless/ath/ath11k/dp_rx.c | 95 +++++++++-- + drivers/net/wireless/ath/ath11k/dp_rx.h | 19 +++ + drivers/net/wireless/ath/ath11k/hal_rx.c | 85 +++++++--- + drivers/net/wireless/ath/ath11k/hal_rx.h | 21 +++ + drivers/net/wireless/ath/ath11k/hw.c | 18 +++ + drivers/net/wireless/ath/ath11k/hw.h | 1 + + 8 files changed, 351 insertions(+), 59 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -44,6 +44,8 @@ + + #define ATH11K_INVALID_HW_MAC_ID 0xFF + #define ATH11K_CONNECTION_LOSS_HZ (3 * HZ) ++#define ATH11K_RX_RATE_TABLE_NUM 320 ++#define ATH11K_RX_RATE_TABLE_11AX_NUM 576 + + /* SMBIOS type containing Board Data File Name Extension */ + #define ATH11K_SMBIOS_BDF_EXT_TYPE 0xF8 +@@ -420,6 +422,17 @@ struct ath11k_vif_iter { + struct ath11k_vif *arvif; + }; + ++struct ath11k_rx_peer_rate_stats { ++ u64 ht_mcs_count[HAL_RX_MAX_MCS_HT + 1]; ++ u64 vht_mcs_count[HAL_RX_MAX_MCS_VHT + 1]; ++ u64 he_mcs_count[HAL_RX_MAX_MCS_HE + 1]; ++ u64 nss_count[HAL_RX_MAX_NSS]; ++ u64 bw_count[HAL_RX_BW_MAX]; ++ u64 gi_count[HAL_RX_GI_MAX]; ++ u64 legacy_count[HAL_RX_MAX_NUM_LEGACY_RATES]; ++ u64 rx_rate[ATH11K_RX_RATE_TABLE_11AX_NUM]; ++}; ++ + struct ath11k_rx_peer_stats { + u64 num_msdu; + u64 num_mpdu_fcs_ok; +@@ -431,10 +444,6 @@ struct ath11k_rx_peer_stats { + u64 non_ampdu_msdu_count; + u64 stbc_count; + u64 beamformed_count; +- u64 mcs_count[HAL_RX_MAX_MCS + 1]; +- u64 nss_count[HAL_RX_MAX_NSS]; +- u64 bw_count[HAL_RX_BW_MAX]; +- u64 gi_count[HAL_RX_GI_MAX]; + 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 { + u64 rx_duration; + u64 dcm_count; + u64 ru_alloc_cnt[HAL_RX_RU_ALLOC_TYPE_MAX]; ++ struct ath11k_rx_peer_rate_stats pkt_stats; ++ struct ath11k_rx_peer_rate_stats byte_stats; + }; + + #define ATH11K_HE_MCS_NUM 12 +--- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c ++++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c +@@ -10,6 +10,7 @@ + #include "peer.h" + #include "debug.h" + #include "dp_tx.h" ++#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 + struct ath11k *ar = arsta->arvif->ar; + struct ath11k_rx_peer_stats *rx_stats = arsta->rx_stats; + int len = 0, i, retval = 0; +- const int size = 4096; ++ const int size = 4 * 4096; + char *buf; ++ int he_rates_avail = (rx_stats->pream_cnt[HAL_RX_PREAMBLE_11AX] > 1) ? 1 : 0; ++ int rate_table_len = he_rates_avail ? ATH11K_RX_RATE_TABLE_11AX_NUM : ++ ATH11K_RX_RATE_TABLE_NUM; ++ char *legacy_rate_str[] = {"1Mbps", "2Mbps", "5.5Mbps", "6Mbps", ++ "9Mbps", "11Mbps", "12Mbps", "18Mbps", ++ "24Mbps", "36 Mbps", "48Mbps", "54Mbps"}; + + if (!rx_stats) + return -ENOENT; +@@ -422,14 +429,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); +- len += scnprintf(buf + len, size - len, +- "GI: 0.8us %llu 0.4us %llu 1.6us %llu 3.2us %llu\n", +- rx_stats->gi_count[0], rx_stats->gi_count[1], +- rx_stats->gi_count[2], rx_stats->gi_count[3]); +- len += scnprintf(buf + len, size - len, +- "BW: 20Mhz %llu 40Mhz %llu 80Mhz %llu 160Mhz %llu\n", +- rx_stats->bw_count[0], rx_stats->bw_count[1], +- rx_stats->bw_count[2], rx_stats->bw_count[3]); + 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 + 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]); +- len += scnprintf(buf + len, size - len, "\nMCS(0-11) Legacy MCS(12):"); +- for (i = 0; i < HAL_RX_MAX_MCS + 1; i++) +- len += scnprintf(buf + len, size - len, "%llu ", rx_stats->mcs_count[i]); +- len += scnprintf(buf + len, size - len, "\nNSS(1-8):"); +- for (i = 0; i < HAL_RX_MAX_NSS; i++) +- len += scnprintf(buf + len, size - len, "%llu ", rx_stats->nss_count[i]); +- len += scnprintf(buf + len, size - len, "\nRX Duration:%llu ", ++ len += scnprintf(buf + len, size - len, "\nRX Duration:%llu\n", + rx_stats->rx_duration); ++ ++ len += scnprintf(buf + len, size - len, "\nRX success packet stats:\n"); ++ len += scnprintf(buf + len, size - len, "\nHE packet stats:\n"); ++ for (i = 0; i <= HAL_RX_MAX_MCS_HE; i++) ++ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, ++ rx_stats->pkt_stats.he_mcs_count[i], ++ (i + 1) % 6 ? "\t" : "\n"); ++ len += scnprintf(buf + len, size - len, "\nVHT packet stats:\n"); ++ for (i = 0; i <= HAL_RX_MAX_MCS_VHT; i++) ++ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, ++ rx_stats->pkt_stats.vht_mcs_count[i], ++ (i + 1) % 5 ? "\t" : "\n"); ++ len += scnprintf(buf + len, size - len, "\nHT packet stats:\n"); ++ for (i = 0; i <= HAL_RX_MAX_MCS_HT; i++) ++ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, ++ rx_stats->pkt_stats.ht_mcs_count[i], ++ (i + 1) % 8 ? "\t" : "\n"); ++ len += scnprintf(buf + len, size - len, "\nLegacy rate packet stats:\n"); ++ for (i = 0; i < HAL_RX_MAX_NUM_LEGACY_RATES; i++) ++ len += scnprintf(buf + len, size - len, "%s: %llu%s", legacy_rate_str[i], ++ rx_stats->pkt_stats.legacy_count[i], ++ (i + 1) % 4 ? "\t" : "\n"); ++ len += scnprintf(buf + len, size - len, "\nNSS packet stats:\n"); ++ for (i = 0; i < HAL_RX_MAX_NSS; i++) ++ len += scnprintf(buf + len, size - len, "%dx%d: %llu ", i + 1, i + 1, ++ rx_stats->pkt_stats.nss_count[i]); ++ len += scnprintf(buf + len, size - len, ++ "\n\nGI: 0.8us %llu 0.4us %llu 1.6us %llu 3.2us %llu\n", ++ rx_stats->pkt_stats.gi_count[0], ++ rx_stats->pkt_stats.gi_count[1], ++ rx_stats->pkt_stats.gi_count[2], ++ rx_stats->pkt_stats.gi_count[3]); ++ len += scnprintf(buf + len, size - len, ++ "BW: 20Mhz %llu 40Mhz %llu 80Mhz %llu 160Mhz %llu\n", ++ rx_stats->pkt_stats.bw_count[0], ++ rx_stats->pkt_stats.bw_count[1], ++ rx_stats->pkt_stats.bw_count[2], ++ rx_stats->pkt_stats.bw_count[3]); ++ len += scnprintf(buf + len, size - len, "\nRate Table (packets):\n"); ++ for (i = 0; i < rate_table_len; i++) ++ len += scnprintf(buf + len, size - len, "%10llu%s", ++ rx_stats->pkt_stats.rx_rate[i], ++ (i + 1) % (he_rates_avail ? 12 : 8) ? "\t" : "\n"); ++ ++ len += scnprintf(buf + len, size - len, "\nRX success byte stats:\n"); ++ len += scnprintf(buf + len, size - len, "\nHE byte stats:\n"); ++ for (i = 0; i <= HAL_RX_MAX_MCS_HE; i++) ++ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, ++ rx_stats->byte_stats.he_mcs_count[i], ++ (i + 1) % 6 ? "\t" : "\n"); ++ ++ len += scnprintf(buf + len, size - len, "\nVHT byte stats:\n"); ++ for (i = 0; i <= HAL_RX_MAX_MCS_VHT; i++) ++ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, ++ rx_stats->byte_stats.vht_mcs_count[i], ++ (i + 1) % 5 ? "\t" : "\n"); ++ len += scnprintf(buf + len, size - len, "\nHT byte stats:\n"); ++ for (i = 0; i <= HAL_RX_MAX_MCS_HT; i++) ++ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, ++ rx_stats->byte_stats.ht_mcs_count[i], ++ (i + 1) % 8 ? "\t" : "\n"); ++ len += scnprintf(buf + len, size - len, "\nLegacy rate byte stats:\n"); ++ for (i = 0; i < HAL_RX_MAX_NUM_LEGACY_RATES; i++) ++ len += scnprintf(buf + len, size - len, "%s: %llu%s", legacy_rate_str[i], ++ rx_stats->byte_stats.legacy_count[i], ++ (i + 1) % 4 ? "\t" : "\n"); ++ len += scnprintf(buf + len, size - len, "\nNSS byte stats:\n"); ++ for (i = 0; i < HAL_RX_MAX_NSS; i++) ++ len += scnprintf(buf + len, size - len, "%dx%d: %llu ", i + 1, i + 1, ++ rx_stats->byte_stats.nss_count[i]); ++ len += scnprintf(buf + len, size - len, ++ "\n\nGI: 0.8us %llu 0.4us %llu 1.6us %llu 3.2us %llu\n", ++ rx_stats->byte_stats.gi_count[0], ++ rx_stats->byte_stats.gi_count[1], ++ rx_stats->byte_stats.gi_count[2], ++ rx_stats->byte_stats.gi_count[3]); ++ len += scnprintf(buf + len, size - len, ++ "BW: 20Mhz %llu 40Mhz %llu 80Mhz %llu 160Mhz %llu\n", ++ rx_stats->byte_stats.bw_count[0], ++ rx_stats->byte_stats.bw_count[1], ++ rx_stats->byte_stats.bw_count[2], ++ rx_stats->byte_stats.bw_count[3]); ++ len += scnprintf(buf + len, size - len, "\nRate Table (bytes):\n"); ++ for (i = 0; i < rate_table_len; i++) ++ len += scnprintf(buf + len, size - len, "%10llu%s", ++ 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], +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -3400,10 +3400,43 @@ exit: + return total_msdu_reaped; + } + ++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, ++ u32 num_msdu) ++{ ++ u32 rate_idx = 0; ++ u32 mcs_idx = ppdu_info->mcs; ++ u32 nss_idx = ppdu_info->nss - 1; ++ u32 bw_idx = ppdu_info->bw; ++ u32 gi_idx = ppdu_info->gi; ++ ++ if ((mcs_idx > HAL_RX_MAX_MCS_HE) || (nss_idx >= HAL_RX_MAX_NSS) || ++ (bw_idx >= HAL_RX_BW_MAX) || (gi_idx >= HAL_RX_GI_MAX)) { ++ return; ++ } ++ ++ if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11N || ++ ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC) { ++ rate_idx = mcs_idx * 8 + 8 * 10 * nss_idx; ++ rate_idx += bw_idx * 2 + gi_idx; ++ } else if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AX) { ++ gi_idx = ath11k_he_gi_to_nl80211_he_gi(ppdu_info->gi); ++ rate_idx = mcs_idx * 12 + 12 * 12 * nss_idx; ++ rate_idx += bw_idx * 3 + gi_idx; ++ } else { ++ return; ++ } ++ ++ rx_stats->pkt_stats.rx_rate[rate_idx] += num_msdu; ++ rx_stats->byte_stats.rx_rate[rate_idx] += ppdu_info->mpdu_len; ++} ++ + static void ath11k_dp_rx_update_peer_stats(struct ath11k_sta *arsta, + struct hal_rx_mon_ppdu_info *ppdu_info) + { + struct ath11k_rx_peer_stats *rx_stats = arsta->rx_stats; ++ struct ath11k *ar = arsta->arvif->ar; + u32 num_msdu; + int i; + +@@ -3413,6 +3446,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); + ++ if (!ath11k_debugfs_is_extd_rx_stats_enabled(ar)) ++ return; + 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 + ppdu_info->tid = IEEE80211_NUM_TIDS; + } + +- if (ppdu_info->nss > 0 && ppdu_info->nss <= HAL_RX_MAX_NSS) +- rx_stats->nss_count[ppdu_info->nss - 1] += num_msdu; +- +- if (ppdu_info->mcs <= HAL_RX_MAX_MCS) +- rx_stats->mcs_count[ppdu_info->mcs] += num_msdu; +- +- if (ppdu_info->gi < HAL_RX_GI_MAX) +- rx_stats->gi_count[ppdu_info->gi] += num_msdu; +- +- if (ppdu_info->bw < HAL_RX_BW_MAX) +- rx_stats->bw_count[ppdu_info->bw] += num_msdu; +- + 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 + rx_stats->dcm_count += ppdu_info->dcm; + rx_stats->ru_alloc_cnt[ppdu_info->ru_alloc] += num_msdu; + +- arsta->rssi_comb = ppdu_info->rssi_comb; +- + 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 + + rx_stats->rx_duration += ppdu_info->rx_duration; + arsta->rx_duration = rx_stats->rx_duration; ++ ++ if (ppdu_info->nss > 0 && ppdu_info->nss <= HAL_RX_MAX_NSS) { ++ rx_stats->pkt_stats.nss_count[ppdu_info->nss - 1] += num_msdu; ++ rx_stats->byte_stats.nss_count[ppdu_info->nss - 1] += ppdu_info->mpdu_len; ++ } ++ ++ if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11N && ++ ppdu_info->mcs <= HAL_RX_MAX_MCS_HT) { ++ rx_stats->pkt_stats.ht_mcs_count[ppdu_info->mcs] += num_msdu; ++ rx_stats->byte_stats.ht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len; ++ /* To fit into rate table for HT packets */ ++ ppdu_info->mcs = ppdu_info->mcs % 8; ++ } ++ ++ if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC && ++ ppdu_info->mcs <= HAL_RX_MAX_MCS_VHT) { ++ rx_stats->pkt_stats.vht_mcs_count[ppdu_info->mcs] += num_msdu; ++ rx_stats->byte_stats.vht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len; ++ } ++ ++ if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AX && ++ ppdu_info->mcs <= HAL_RX_MAX_MCS_HE) { ++ rx_stats->pkt_stats.he_mcs_count[ppdu_info->mcs] += num_msdu; ++ rx_stats->byte_stats.he_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len; ++ } ++ ++ ++ if ((ppdu_info->preamble_type == HAL_RX_PREAMBLE_11A || ++ ppdu_info->preamble_type == HAL_RX_PREAMBLE_11B) && ++ ppdu_info->rate < HAL_RX_LEGACY_RATE_INVALID) { ++ rx_stats->pkt_stats.legacy_count[ppdu_info->rate] += num_msdu; ++ rx_stats->byte_stats.legacy_count[ppdu_info->rate] += ppdu_info->mpdu_len; ++ } ++ ++ if (ppdu_info->gi < HAL_RX_GI_MAX) { ++ rx_stats->pkt_stats.gi_count[ppdu_info->gi] += num_msdu; ++ rx_stats->byte_stats.gi_count[ppdu_info->gi] += ppdu_info->mpdu_len; ++ } ++ ++ if (ppdu_info->bw < HAL_RX_BW_MAX) { ++ rx_stats->pkt_stats.bw_count[ppdu_info->bw] += num_msdu; ++ rx_stats->byte_stats.bw_count[ppdu_info->bw] += ppdu_info->mpdu_len; ++ } ++ ++ ath11k_dp_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, num_msdu); ++ + } + + 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 { + __be16 snap_type; + } __packed; + ++static inline u32 ath11k_he_gi_to_nl80211_he_gi(u8 sgi) ++{ ++ u32 ret = 0; ++ ++ switch (sgi) { ++ case RX_MSDU_START_SGI_0_8_US: ++ ret = NL80211_RATE_INFO_HE_GI_0_8; ++ break; ++ case RX_MSDU_START_SGI_1_6_US: ++ ret = NL80211_RATE_INFO_HE_GI_1_6; ++ break; ++ case RX_MSDU_START_SGI_3_2_US: ++ ret = NL80211_RATE_INFO_HE_GI_3_2; ++ break; ++ } ++ ++ return ret; ++} ++ + int ath11k_dp_rx_ampdu_start(struct ath11k_vif *arvif, + struct ieee80211_ampdu_params *params); + int ath11k_dp_rx_ampdu_stop(struct ath11k_vif *arvif, +--- 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 + 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); +- ppdu_info->gi = info1 & HAL_RX_HT_SIG_INFO_INFO1_GI; +- +- switch (ppdu_info->mcs) { +- case 0 ... 7: +- ppdu_info->nss = 1; +- break; +- case 8 ... 15: +- ppdu_info->nss = 2; +- break; +- case 16 ... 23: +- ppdu_info->nss = 3; +- break; +- case 24 ... 31: +- ppdu_info->nss = 4; +- break; +- } +- +- if (ppdu_info->nss > 1) +- ppdu_info->mcs = ppdu_info->mcs % 8; +- ++ ppdu_info->gi = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO1_GI, info1); ++ ppdu_info->nss = (ppdu_info->mcs >> 3) + 1; + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; + break; + } + case HAL_PHYRX_L_SIG_B: { + struct hal_rx_lsig_b_info *lsigb = + (struct hal_rx_lsig_b_info *)tlv_data; ++ u8 rate; ++ ++ rate = FIELD_GET(HAL_RX_LSIG_B_INFO_INFO0_RATE, ++ __le32_to_cpu(lsigb->info0)); + +- ppdu_info->rate = FIELD_GET(HAL_RX_LSIG_B_INFO_INFO0_RATE, +- __le32_to_cpu(lsigb->info0)); ++ switch (rate) { ++ case 1: ++ rate = HAL_RX_LEGACY_RATE_1_MBPS; ++ break; ++ case 2: ++ case 5: ++ rate = HAL_RX_LEGACY_RATE_2_MBPS; ++ break; ++ case 3: ++ case 6: ++ rate = HAL_RX_LEGACY_RATE_5_5_MBPS; ++ break; ++ case 4: ++ case 7: ++ rate = HAL_RX_LEGACY_RATE_11_MBPS; ++ break; ++ default: ++ rate = HAL_RX_LEGACY_RATE_INVALID; ++ } ++ ppdu_info->rate = rate; + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; + break; + } + case HAL_PHYRX_L_SIG_A: { + struct hal_rx_lsig_a_info *lsiga = + (struct hal_rx_lsig_a_info *)tlv_data; ++ u8 rate; + +- ppdu_info->rate = FIELD_GET(HAL_RX_LSIG_A_INFO_INFO0_RATE, +- __le32_to_cpu(lsiga->info0)); ++ rate = FIELD_GET(HAL_RX_LSIG_A_INFO_INFO0_RATE, ++ __le32_to_cpu(lsiga->info0)); ++ switch (rate) { ++ case 8: ++ rate = HAL_RX_LEGACY_RATE_48_MBPS; ++ break; ++ case 9: ++ rate = HAL_RX_LEGACY_RATE_24_MBPS; ++ break; ++ case 10: ++ rate = HAL_RX_LEGACY_RATE_12_MBPS; ++ break; ++ case 11: ++ rate = HAL_RX_LEGACY_RATE_6_MBPS; ++ break; ++ case 12: ++ rate = HAL_RX_LEGACY_RATE_54_MBPS; ++ break; ++ case 13: ++ rate = HAL_RX_LEGACY_RATE_36_MBPS; ++ break; ++ case 14: ++ rate = HAL_RX_LEGACY_RATE_18_MBPS; ++ break; ++ case 15: ++ rate = HAL_RX_LEGACY_RATE_9_MBPS; ++ break; ++ default: ++ rate = HAL_RX_LEGACY_RATE_INVALID; ++ } ++ ppdu_info->rate = rate; + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; + break; + } +@@ -1473,6 +1507,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; ++ ++ ppdu_info->mpdu_len += ab->hw_params.hw_ops->rx_desc_get_hal_mpdu_len(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 +@@ -19,7 +19,11 @@ struct hal_rx_wbm_rel_info { + #define VHT_SIG_SU_NSS_MASK 0x7 + + #define HAL_RX_MAX_MCS 12 ++#define HAL_RX_MAX_MCS_HT 31 ++#define HAL_RX_MAX_MCS_VHT 9 ++#define HAL_RX_MAX_MCS_HE 11 + #define HAL_RX_MAX_NSS 8 ++#define HAL_RX_MAX_NUM_LEGACY_RATES 12 + + struct hal_rx_mon_status_tlv_hdr { + u32 hdr; +@@ -104,6 +108,22 @@ struct hal_rx_user_status { + u32 mpdu_err_byte_count; + }; + ++enum hal_rx_legacy_rate { ++ HAL_RX_LEGACY_RATE_1_MBPS, ++ HAL_RX_LEGACY_RATE_2_MBPS, ++ HAL_RX_LEGACY_RATE_5_5_MBPS, ++ HAL_RX_LEGACY_RATE_6_MBPS, ++ HAL_RX_LEGACY_RATE_9_MBPS, ++ HAL_RX_LEGACY_RATE_11_MBPS, ++ HAL_RX_LEGACY_RATE_12_MBPS, ++ HAL_RX_LEGACY_RATE_18_MBPS, ++ HAL_RX_LEGACY_RATE_24_MBPS, ++ HAL_RX_LEGACY_RATE_36_MBPS, ++ HAL_RX_LEGACY_RATE_48_MBPS, ++ HAL_RX_LEGACY_RATE_54_MBPS, ++ HAL_RX_LEGACY_RATE_INVALID, ++}; ++ + #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 { + u32 num_mpdu_fcs_ok; + u32 num_mpdu_fcs_err; + u32 preamble_type; ++ u32 mpdu_len; + u16 chan_num; + u16 tcp_msdu_count; + 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 + return skb_get_hash(skb); + } + ++static u32 ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len(struct hal_rx_mpdu_info *mpdu_info) ++{ ++ return FIELD_GET(HAL_RX_MPDU_INFO_INFO1_MPDU_LEN, ++ __le32_to_cpu(mpdu_info->u.ipq8074.info1)); ++} ++ ++static u32 ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_len(struct hal_rx_mpdu_info *mpdu_info) ++{ ++ return FIELD_GET(HAL_RX_MPDU_INFO_INFO1_MPDU_LEN, ++ __le32_to_cpu(mpdu_info->u.qcn9074.info1)); ++} + 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 = + .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 = + .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, + }; + + const struct ath11k_hw_ops qca6390_ops = { +@@ -1177,6 +1190,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, ++ .rx_desc_get_hal_mpdu_len = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len, + }; + + 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, + .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 = + .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, + }; + + #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 { + 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 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/ath11k_nss/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch new file mode 100644 index 00000000000000..e7908c6daad2a7 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch @@ -0,0 +1,452 @@ +--- 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 + len += scnprintf(buf + len, size - len, "%10llu%s", + rx_stats->byte_stats.rx_rate[i], + (i + 1) % (he_rates_avail ? 12 : 8) ? "\t" : "\n"); ++ len += scnprintf(buf + len, size - len, ++ "\nDCM: %llu\nRU26: %llu \nRU52: %llu \nRU106: %llu \nRU242: %llu \nRU484: %llu \nRU996: %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, + "\nDCM: %llu\nRU: 26 %llu 52: %llu 106: %llu 242: %llu 484: %llu 996: %llu\n", +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -3236,11 +3236,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, ++ struct hal_rx_user_status* user_stats, + u32 num_msdu) + { + u32 rate_idx = 0; +- u32 mcs_idx = ppdu_info->mcs; +- u32 nss_idx = ppdu_info->nss - 1; ++ u32 mcs_idx = (user_stats) ? user_stats->mcs : ppdu_info->mcs; ++ u32 nss_idx = (user_stats) ? user_stats->nss - 1 : ppdu_info->nss - 1; + u32 bw_idx = ppdu_info->bw; + u32 gi_idx = ppdu_info->gi; + +@@ -3262,10 +3263,13 @@ ath11k_dp_rx_update_peer_rate_table_stat + } + + rx_stats->pkt_stats.rx_rate[rate_idx] += num_msdu; +- rx_stats->byte_stats.rx_rate[rate_idx] += ppdu_info->mpdu_len; ++ if (user_stats) ++ rx_stats->byte_stats.rx_rate[rate_idx] += user_stats->mpdu_ok_byte_count; ++ else ++ rx_stats->byte_stats.rx_rate[rate_idx] += ppdu_info->mpdu_len; + } + +-static void ath11k_dp_rx_update_peer_stats(struct ath11k_sta *arsta, ++static void ath11k_dp_rx_update_peer_su_stats(struct ath11k_sta *arsta, + 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 + 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; +- rx_stats->ru_alloc_cnt[ppdu_info->ru_alloc] += num_msdu; + + 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 + + if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11N && + ppdu_info->mcs <= HAL_RX_MAX_MCS_HT) { +- rx_stats->pkt_stats.ht_mcs_count[ppdu_info->mcs] += num_msdu; +- rx_stats->byte_stats.ht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len; +- /* To fit into rate table for HT packets */ +- ppdu_info->mcs = ppdu_info->mcs % 8; ++ rx_stats->pkt_stats.ht_mcs_count[ppdu_info->mcs] += num_msdu; ++ rx_stats->byte_stats.ht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len; ++ /* To fit into rate table for HT packets */ ++ ppdu_info->mcs = ppdu_info->mcs % 8; + } + + if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC && +@@ -3377,7 +3380,120 @@ static void ath11k_dp_rx_update_peer_sta + rx_stats->byte_stats.bw_count[ppdu_info->bw] += ppdu_info->mpdu_len; + } + +- ath11k_dp_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, num_msdu); ++ ath11k_dp_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, NULL, num_msdu); ++ ++} ++ ++static void ath11k_dp_rx_update_user_stats(struct ath11k *ar, ++ struct hal_rx_mon_ppdu_info *ppdu_info, ++ u32 uid) ++{ ++ struct ath11k_sta *arsta = NULL; ++ struct ath11k_rx_peer_stats *rx_stats = NULL; ++ struct hal_rx_user_status* user_stats = &ppdu_info->userstats[uid]; ++ struct ath11k_peer *peer; ++ u32 num_msdu; ++ ++ if (user_stats->ast_index == 0 || user_stats->ast_index == 0xFFFF) ++ return; ++ ++ peer = ath11k_peer_find_by_ast(ar->ab, user_stats->ast_index); ++ ++ if (peer == NULL) { ++ ath11k_warn(ar->ab, "peer ast idx %d can't be found\n", ++ user_stats->ast_index); ++ return; ++ } ++ ++ arsta = (struct ath11k_sta *)peer->sta->drv_priv; ++ rx_stats = arsta->rx_stats; ++ ++ if (!rx_stats) ++ return; ++ ++ arsta->rssi_comb = ppdu_info->rssi_comb; ++ ++ num_msdu = user_stats->tcp_msdu_count + user_stats->tcp_ack_msdu_count + ++ user_stats->udp_msdu_count + user_stats->other_msdu_count; ++ ++ rx_stats->num_msdu += num_msdu; ++ rx_stats->tcp_msdu_count += user_stats->tcp_msdu_count + ++ user_stats->tcp_ack_msdu_count; ++ rx_stats->udp_msdu_count += user_stats->udp_msdu_count; ++ rx_stats->other_msdu_count += user_stats->other_msdu_count; ++ ++ if (ppdu_info->ldpc < HAL_RX_SU_MU_CODING_MAX) ++ rx_stats->coding_count[ppdu_info->ldpc] += num_msdu; ++ ++ if (user_stats->tid <= IEEE80211_NUM_TIDS) ++ rx_stats->tid_count[user_stats->tid] += num_msdu; ++ ++ if (user_stats->preamble_type < HAL_RX_PREAMBLE_MAX) ++ rx_stats->pream_cnt[user_stats->preamble_type] += num_msdu; ++ ++ if (ppdu_info->reception_type < HAL_RX_RECEPTION_TYPE_MAX) ++ rx_stats->reception_type[ppdu_info->reception_type] += num_msdu; ++ ++ if (ppdu_info->is_stbc) ++ rx_stats->stbc_count += num_msdu; ++ ++ if (ppdu_info->beamformed) ++ rx_stats->beamformed_count += num_msdu; ++ ++ if (user_stats->mpdu_cnt_fcs_ok > 1) ++ rx_stats->ampdu_msdu_count += num_msdu; ++ else ++ rx_stats->non_ampdu_msdu_count += num_msdu; ++ ++ rx_stats->num_mpdu_fcs_ok += user_stats->mpdu_cnt_fcs_ok; ++ rx_stats->num_mpdu_fcs_err += user_stats->mpdu_cnt_fcs_err; ++ rx_stats->dcm_count += ppdu_info->dcm; ++ if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA || ++ ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO) ++ rx_stats->ru_alloc_cnt[user_stats->ul_ofdma_ru_size] += num_msdu; ++ ++ rx_stats->rx_duration += ppdu_info->rx_duration; ++ arsta->rx_duration = rx_stats->rx_duration; ++ ++ if (user_stats->nss > 0 && user_stats->nss <= HAL_RX_MAX_NSS) { ++ rx_stats->pkt_stats.nss_count[user_stats->nss - 1] += num_msdu; ++ rx_stats->byte_stats.nss_count[user_stats->nss - 1] += user_stats->mpdu_ok_byte_count; ++ } ++ ++ if (user_stats->preamble_type == HAL_RX_PREAMBLE_11AX && ++ user_stats->mcs <= HAL_RX_MAX_MCS_HE) { ++ rx_stats->pkt_stats.he_mcs_count[user_stats->mcs] += num_msdu; ++ rx_stats->byte_stats.he_mcs_count[user_stats->mcs] += user_stats->mpdu_ok_byte_count; ++ } ++ ++ if (ppdu_info->gi < HAL_RX_GI_MAX) { ++ rx_stats->pkt_stats.gi_count[ppdu_info->gi] += num_msdu; ++ rx_stats->byte_stats.gi_count[ppdu_info->gi] += user_stats->mpdu_ok_byte_count; ++ } ++ ++ if (ppdu_info->bw < HAL_RX_BW_MAX) { ++ rx_stats->pkt_stats.bw_count[ppdu_info->bw] += num_msdu; ++ rx_stats->byte_stats.bw_count[ppdu_info->bw] += user_stats->mpdu_ok_byte_count; ++ } ++ ++ ath11k_dp_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, user_stats, num_msdu); ++} ++ ++static void ath11k_dp_rx_update_peer_mu_stats(struct ath11k *ar, ++ struct hal_rx_mon_ppdu_info *ppdu_info) ++{ ++ u32 num_users, i; ++ ++ if (!ath11k_debugfs_is_extd_rx_stats_enabled(ar)) ++ return; ++ ++ num_users = ppdu_info->num_users; ++ if (num_users > HAL_MAX_UL_MU_USERS) ++ num_users = HAL_MAX_UL_MU_USERS; ++ ++ for (i = 0; i < num_users; i++) { ++ ath11k_dp_rx_update_user_stats(ar, ppdu_info, i); ++ } + + } + +@@ -5846,6 +5962,55 @@ static void ath11k_dp_rx_mon_dest_proces + } + } + ++void ath11k_dp_rx_mon_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info) ++{ ++ struct hal_rx_user_status *rx_user_status; ++ u32 num_users; ++ uint32_t i; ++ uint32_t mu_ul_user_v0_word0; ++ uint32_t mu_ul_user_v0_word1; ++ uint32_t ru_size; ++ ++ if (!(ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA || ++ ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO)) ++ return; ++ ++ num_users = ppdu_info->num_users; ++ if (num_users > HAL_MAX_UL_MU_USERS) ++ num_users = HAL_MAX_UL_MU_USERS; ++ ++ for (i = 0; i < num_users; i++) { ++ rx_user_status = &ppdu_info->userstats[i]; ++ mu_ul_user_v0_word0 = ++ rx_user_status->ul_ofdma_user_v0_word0; ++ mu_ul_user_v0_word1 = ++ rx_user_status->ul_ofdma_user_v0_word1; ++ ++ if (FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID, ++ mu_ul_user_v0_word0) && ++ !FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VER, ++ mu_ul_user_v0_word0)) { ++ rx_user_status->mcs = ++ FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_MCS, ++ mu_ul_user_v0_word1); ++ rx_user_status->nss = ++ FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_NSS, ++ mu_ul_user_v0_word1) + 1; ++ ++ rx_user_status->ofdma_info_valid = 1; ++ rx_user_status->ul_ofdma_ru_start_index = ++ FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_START, ++ mu_ul_user_v0_word1); ++ ++ ru_size = FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE, ++ mu_ul_user_v0_word1); ++ rx_user_status->ul_ofdma_ru_width = ru_size; ++ rx_user_status->ul_ofdma_ru_size = ru_size; ++ } ++ } ++ ++} ++ + int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id, + struct napi_struct *napi, int budget) + { +@@ -5919,8 +6084,13 @@ int ath11k_dp_rx_process_mon_status(stru + + 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); ++ 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)) +--- a/drivers/net/wireless/ath/ath11k/hal_rx.c ++++ b/drivers/net/wireless/ath/ath11k/hal_rx.c +@@ -804,7 +804,6 @@ void ath11k_hal_reo_init_cmd_ring(struct + } + } + +-#define HAL_MAX_UL_MU_USERS 37 + static inline void + ath11k_hal_rx_handle_ofdma_info(void *rx_tlv, + struct hal_rx_user_status *rx_user_status) +@@ -836,6 +835,8 @@ ath11k_hal_rx_populate_mu_user_info(void + { + rx_user_status->ast_index = ppdu_info->ast_index; + rx_user_status->tid = ppdu_info->tid; ++ rx_user_status->tcp_ack_msdu_count = ++ ppdu_info->tcp_ack_msdu_count; + rx_user_status->tcp_msdu_count = + ppdu_info->tcp_msdu_count; + rx_user_status->udp_msdu_count = +@@ -859,6 +860,9 @@ ath11k_hal_rx_populate_mu_user_info(void + ppdu_info->num_mpdu_fcs_ok; + rx_user_status->mpdu_cnt_fcs_err = + ppdu_info->num_mpdu_fcs_err; ++ memcpy(&rx_user_status->mpdu_fcs_ok_bitmap[0], &ppdu_info->mpdu_fcs_ok_bitmap[0], ++ HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * ++ sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0])); + + ath11k_hal_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status); + } +@@ -888,6 +892,14 @@ ath11k_hal_rx_parse_mon_status_tlv(struc + __le32_to_cpu(ppdu_start->info0)); + ppdu_info->chan_num = __le32_to_cpu(ppdu_start->chan_num); + ppdu_info->ppdu_ts = __le32_to_cpu(ppdu_start->ppdu_start_ts); ++ ++ if (ppdu_info->ppdu_id != ppdu_info->last_ppdu_id) { ++ ppdu_info->last_ppdu_id = ppdu_info->ppdu_id; ++ ppdu_info->num_users = 0; ++ memset(&ppdu_info->mpdu_fcs_ok_bitmap, 0, ++ HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * ++ sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0])); ++ } + break; + } + case HAL_RX_PPDU_END_USER_STATS: { +@@ -942,15 +954,16 @@ ath11k_hal_rx_parse_mon_status_tlv(struc + + if (userid < HAL_MAX_UL_MU_USERS) { + struct hal_rx_user_status *rxuser_stats = +- &ppdu_info->userstats; ++ &ppdu_info->userstats[userid]; ++ ppdu_info->num_users += 1; + + ath11k_hal_rx_handle_ofdma_info(tlv_data, rxuser_stats); + ath11k_hal_rx_populate_mu_user_info(tlv_data, ppdu_info, + rxuser_stats); + } +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[0] = ++ ppdu_info->mpdu_fcs_ok_bitmap[0] = + __le32_to_cpu(eu_stats->rsvd1[0]); +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[1] = ++ ppdu_info->mpdu_fcs_ok_bitmap[1] = + __le32_to_cpu(eu_stats->rsvd1[1]); + + break; +@@ -958,12 +971,12 @@ ath11k_hal_rx_parse_mon_status_tlv(struc + case HAL_RX_PPDU_END_USER_STATS_EXT: { + struct hal_rx_ppdu_end_user_stats_ext *eu_stats = + (struct hal_rx_ppdu_end_user_stats_ext *)tlv_data; +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[2] = eu_stats->info1; +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[3] = eu_stats->info2; +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[4] = eu_stats->info3; +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[5] = eu_stats->info4; +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[6] = eu_stats->info5; +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[7] = eu_stats->info6; ++ ppdu_info->mpdu_fcs_ok_bitmap[2] = eu_stats->info1; ++ ppdu_info->mpdu_fcs_ok_bitmap[3] = eu_stats->info2; ++ ppdu_info->mpdu_fcs_ok_bitmap[4] = eu_stats->info3; ++ ppdu_info->mpdu_fcs_ok_bitmap[5] = eu_stats->info4; ++ ppdu_info->mpdu_fcs_ok_bitmap[6] = eu_stats->info5; ++ ppdu_info->mpdu_fcs_ok_bitmap[7] = eu_stats->info6; + break; + } + case HAL_PHYRX_HT_SIG: { +--- a/drivers/net/wireless/ath/ath11k/hal_rx.h ++++ b/drivers/net/wireless/ath/ath11k/hal_rx.h +@@ -72,6 +72,10 @@ enum hal_rx_reception_type { + #define HAL_RX_FCS_LEN 4 + #define HAL_AST_IDX_INVALID 0xFFFF + ++#define HAL_MAX_UL_MU_USERS 37 ++#define HAL_RX_MAX_MPDU 256 ++#define HAL_RX_NUM_WORDS_PER_PPDU_BITMAP (HAL_RX_MAX_MPDU >> 5) ++ + enum hal_rx_mon_status { + HAL_RX_MON_STATUS_PPDU_NOT_DONE, + HAL_RX_MON_STATUS_PPDU_DONE, +@@ -82,14 +86,15 @@ struct hal_rx_user_status { + u32 mcs:4, + nss:3, + ofdma_info_valid:1, +- dl_ofdma_ru_start_index:7, +- dl_ofdma_ru_width:7, +- dl_ofdma_ru_size:8; ++ ul_ofdma_ru_start_index:7, ++ ul_ofdma_ru_width:7, ++ ul_ofdma_ru_size:8; + u32 ul_ofdma_user_v0_word0; + u32 ul_ofdma_user_v0_word1; + u32 ast_index; + u32 tid; + u16 tcp_msdu_count; ++ u16 tcp_ack_msdu_count; + u16 udp_msdu_count; + u16 other_msdu_count; + u16 frame_control; +@@ -103,7 +108,7 @@ struct hal_rx_user_status { + u8 rs_flags; + u32 mpdu_cnt_fcs_ok; + u32 mpdu_cnt_fcs_err; +- u32 mpdu_fcs_ok_bitmap[8]; ++ u32 mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP]; + u32 mpdu_ok_byte_count; + u32 mpdu_err_byte_count; + }; +@@ -144,6 +149,7 @@ struct hal_sw_mon_ring_entries { + + struct hal_rx_mon_ppdu_info { + u32 ppdu_id; ++ u32 last_ppdu_id; + u32 ppdu_ts; + u32 num_mpdu_fcs_ok; + u32 num_mpdu_fcs_err; +@@ -212,9 +218,20 @@ struct hal_rx_mon_ppdu_info { + u8 ltf_size; + u8 rxpcu_filter_pass; + char rssi_chain[8][8]; +- struct hal_rx_user_status userstats; ++ 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]; + }; + ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID BIT(30) ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VER BIT(31) ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_NSS GENMASK(2, 0) ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_MCS GENMASK(6, 3) ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_LDPC BIT(7) ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_DCM BIT(8) ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_START GENMASK(15, 9) ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE GENMASK(18, 16) ++ + #define HAL_RX_PPDU_START_INFO0_PPDU_ID GENMASK(15, 0) + + 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_ + return NULL; + } + ++struct ath11k_peer *ath11k_peer_find_by_ast(struct ath11k_base *ab, ++ int ast_hash) ++{ ++ struct ath11k_peer *peer; ++ ++ lockdep_assert_held(&ab->base_lock); ++ ++ list_for_each_entry(peer, &ab->peers, list) ++ if (ast_hash == peer->ast_hash) ++ return peer; ++ ++ 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, +--- 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 + 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); ++struct ath11k_peer *ath11k_peer_find_by_ast(struct ath11k_base *ab, int ast_hash); + void ath11k_peer_cleanup(struct ath11k *ar, u32 vdev_id); + int ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, u8 *addr); + int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, diff --git a/package/kernel/mac80211/patches/ath11k_nss/907-ath11k-remove-error-on-soc-debugfs-fail.patch b/package/kernel/mac80211/patches/ath11k_nss/907-ath11k-remove-error-on-soc-debugfs-fail.patch new file mode 100644 index 00000000000000..b47785828a2bd9 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/907-ath11k-remove-error-on-soc-debugfs-fail.patch @@ -0,0 +1,146 @@ +From 41363c3109235a96d90d5946bbc01d1cc8dad47e Mon Sep 17 00:00:00 2001 +From: Anilkumar Kolli +Date: Sun, 6 Sep 2020 11:01:38 +0530 +Subject: [PATCH] ath11k: update debugfs support for mupltiple radios in PCI +bus + +debugfs_ath11k struct is moved to ath11k_core, since its common +for both pci and ahb. + +Current ath11k_pci insmod fails if there are multiple PCI rdaios, +debugfs directory is created with soc_name and bus_id to allow +creating debugfs directory for second PCI radio. + +with this Debugfs entries looks like, + # ls -l /sys/kernel/debug/ath11k/ + ipq8074 hw2.0 qcn9000 hw1.0_0000:01:00.0 qcn9000 hw1.0_0001:01:00.0 + + # ls -l /sys/kernel/debug/ath11k/ipq8074 hw2.0/ + mac0 mac1 simulate_fw_crash soc_dp_stats + + # ls -l /sys/kernel/debug/ath11k/qcn9000 hw1.0_0000:01:00.0 + mac0 simulate_fw_crash soc_dp_stats + + # /sys/kernel/debug/ath11k/qcn9000 hw1.0_0001:01:00.0: + mac0 simulate_fw_crash soc_dp_stats + +Signed-off-by: Anilkumar Kolli +--- + drivers/net/wireless/ath/ath11k/core.c | 12 +++++++ + drivers/net/wireless/ath/ath11k/core.h | 1 - + drivers/net/wireless/ath/ath11k/debugfs.c | 57 ++++++++++++++++++++++++------ + drivers/net/wireless/ath/ath11k/debugfs.h | 11 ++++++ + 5 files changed, 72 insertions(+), 13 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -2260,5 +2260,17 @@ err_sc_free: + } + EXPORT_SYMBOL(ath11k_core_alloc); + ++int ath11k_init(void) ++{ ++ return ath11k_debugfs_create(); ++} ++module_init(ath11k_init); ++ ++void ath11k_exit(void) ++{ ++ ath11k_debugfs_destroy(); ++} ++module_exit(ath11k_exit); ++ + MODULE_DESCRIPTION("Core module for Qualcomm Atheros 802.11ax wireless LAN cards."); + 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 @@ + #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 + + void ath11k_debugfs_pdev_destroy(struct ath11k_base *ab) + { +- debugfs_remove_recursive(ab->debugfs_soc); +- ab->debugfs_soc = NULL; + } + + int ath11k_debugfs_soc_create(struct ath11k_base *ab) +@@ -1282,6 +1282,24 @@ void ath11k_debugfs_soc_destroy(struct a + } + EXPORT_SYMBOL(ath11k_debugfs_soc_destroy); + ++int ath11k_debugfs_create(void) ++{ ++ debugfs_ath11k = debugfs_create_dir("ath11k", NULL); ++ if (IS_ERR_OR_NULL(debugfs_ath11k)) { ++ if (IS_ERR(debugfs_ath11k)) ++ return PTR_ERR(debugfs_ath11k); ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++void ath11k_debugfs_destroy(void) ++{ ++ debugfs_remove_recursive(debugfs_ath11k); ++ debugfs_ath11k = NULL; ++} ++ + 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 + char pdev_name[10]; + char buf[100] = {0}; + ++ if (!(IS_ERR_OR_NULL(ar->debug.debugfs_pdev))) ++ return 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); +--- a/drivers/net/wireless/ath/ath11k/debugfs.h ++++ b/drivers/net/wireless/ath/ath11k/debugfs.h +@@ -282,6 +282,8 @@ do { \ + #endif + + #ifdef CPTCFG_ATH11K_DEBUGFS ++int ath11k_debugfs_create(void); ++void ath11k_debugfs_destroy(void); + 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 + } + + #else ++static inline int ath11k_debugfs_create(void) ++{ ++ return 0; ++} ++ ++static inline void ath11k_debugfs_destroy(void) ++{ ++} ++ + static inline int ath11k_debugfs_soc_create(struct ath11k_base *ab) + { + return 0; diff --git a/package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch b/package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch new file mode 100644 index 00000000000000..bba58322a254e7 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch @@ -0,0 +1,253 @@ +From 91df8aa674d2d4064ab22f47515c3fb126527208 Mon Sep 17 00:00:00 2001 +From: Karthikeyan Kathirvel +Date: Thu, 12 Nov 2020 15:02:56 +0530 +Subject: [PATCH] ath11k: NSS MCBC Exception added for STA + +Since NSS FW is not supporting PN check for MCBC pkts, those pkts are +excepted from NSS offload to pass through mac80211 PN check. + +Signed-off-by: Karthikeyan Kathirvel +Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 +--- + drivers/net/wireless/ath/ath11k/nss.c | 128 +++++++++++++++++++++ + drivers/net/wireless/ath/ath11k/nss.h | 51 ++++---- + 2 files changed, 153 insertions(+), 26 deletions(-) + create mode 100644 mac80211/patches/301-ath11k-nss-mcbc-exception.patch + +--- 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 + + static void ath11k_nss_wds_type_rx(struct ath11k *ar, struct net_device *dev, + u8* src_mac, u8 is_sa_valid, u8 addr4_valid, +- u16 peer_id, bool *drop) ++ u16 peer_id) + { + 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 + } + } + +- if (!ta_peer->nss.ext_vdev_up) +- *drop = true; + } + + spin_unlock_bh(&ab->base_lock); +@@ -692,8 +690,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, +- struct nss_wifi_vdev_wds_per_packet_metadata *wds_metadata, +- bool *drop) ++ struct nss_wifi_vdev_wds_per_packet_metadata *wds_metadata) + { + struct ath11k *ar = arvif->ar; + struct ath11k_base *ab = ar->ab; +@@ -715,7 +712,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, +- addr4_valid, peer_id, drop); ++ addr4_valid, peer_id); + 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; + 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 ath11k_peer *ta_peer = NULL; + + if (!dev) { + dev_kfree_skb_any(skb); +@@ -834,15 +833,50 @@ ath11k_nss_vdev_special_data_receive(str + return; + } + +- if (eth_decap && wifi_metadata->pkt_type == +- 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, +- wds_metadata, &drop); +- } ++ switch(wifi_metadata->pkt_type) { ++ case NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_WDS_LEARN: ++ if (eth_decap) { ++ wds_metadata = &wifi_metadata->metadata.wds_metadata; ++ ath11k_nss_vdev_spl_receive_ext_wdsdata(arvif, skb, ++ wds_metadata); ++ } ++ dev_kfree_skb_any(skb); ++ break; ++ case NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_MCBC_RX: ++ ath11k_dbg_dump(ab, ATH11K_DBG_DP_RX, "", ++ "mcbc packet exception from nss: ", ++ 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_4ADDR: ++ if (eth_decap) { ++ addr4_metadata = &wifi_metadata->metadata.addr4_metadata; ++ ++ spin_lock_bh(&ab->base_lock); ++ ta_peer = ath11k_peer_find_by_id(ab, addr4_metadata->peer_id); ++ if (!ta_peer) { ++ spin_unlock_bh(&ab->base_lock); ++ dev_kfree_skb_any(skb); ++ return; ++ } + +- if (!drop) +- ath11k_nss_deliver_rx(arvif->vif, skb, eth_decap, data_offs, napi); ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, "4addr exception ta_peer %pM\n", ++ ta_peer->addr); ++ if (!ta_peer->nss.ext_vdev_up && addr4_metadata->addr4_valid) ++ ieee80211_rx_nss_notify_4addr(dev, ta_peer->addr); ++ spin_unlock_bh(&ab->base_lock); ++ } ++ dev_kfree_skb_any(skb); ++ break; ++ default: ++ ath11k_warn(ab, "unsupported pkt_type %d from nss\n", wifi_metadata->pkt_type); ++ dev_kfree_skb_any(skb); ++ } + } + + static void +@@ -1049,6 +1083,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; ++ case ATH11K_NSS_WIFI_VDEV_CFG_MCBC_EXC_TO_HOST_CMD: ++ cmd = NSS_WIFI_VDEV_CFG_MCBC_EXC_TO_HOST_CMD; ++ break; + default: + return -EINVAL; + } +@@ -1299,12 +1336,31 @@ int ath11k_nss_vdev_create(struct ath11k + goto free_vdev; + + switch (arvif->vif->type) { +- case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_STATION: + ret = ath11k_nss_vdev_configure(arvif); + if (ret) + goto unregister_vdev; + ++ ret = ath11k_nss_vdev_set_cmd(arvif, ++ ATH11K_NSS_WIFI_VDEV_CFG_MCBC_EXC_TO_HOST_CMD, ++ ATH11K_NSS_ENABLE_MCBC_EXC); ++ if (ret) { ++ ath11k_err(ab, "failed to set MCBC in nss %d\n", ret); ++ goto unregister_vdev; ++ } ++ break; ++ case NL80211_IFTYPE_AP: ++ ret = ath11k_nss_vdev_configure(arvif); ++ if (ret) ++ goto unregister_vdev; ++ ++ ret = ath11k_nss_vdev_set_cmd(arvif, ++ ATH11K_NSS_WIFI_VDEV_CFG_WDS_BACKHAUL_CMD, ++ true); ++ if (ret) { ++ ath11k_warn(ab, "failed to cfg wds backhaul in nss %d\n", ret); ++ 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( + { + struct ath11k *ar = arvif->ar; + struct ath11k_base *ab = ar->ab; +- nss_tx_status_t status; + 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( + + if (!arvif->nss.ctx) { + ath11k_warn(ab, "failed to register nss vdev if_num %d nss_err:%d\n", +- arvif->nss.if_num, status); ++ arvif->nss.if_num, NSS_TX_FAILURE); + return -EINVAL; + } + +--- 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 { + 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/ath11k_nss/908-330-ath11k-sync-wds_ast_entry-updates.patch b/package/kernel/mac80211/patches/ath11k_nss/908-330-ath11k-sync-wds_ast_entry-updates.patch new file mode 100644 index 00000000000000..6ebd709e7d3298 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/908-330-ath11k-sync-wds_ast_entry-updates.patch @@ -0,0 +1,522 @@ +From 9e1f28f343347774b01f330d76d2c5323fcd07ae Mon Sep 17 00:00:00 2001 +From: Rameshkumar Sundaram +Date: Fri, 24 Sep 2021 18:25:08 +0530 +Subject: [PATCH] ath11k: sync wds ast entry on peer/entry deletions + +Peer specific ast entries list is shared between +peer_unmap_event(softirq) and peer_ast_wds_wmi_wk +(worker). The worker sends a WMI command and hence tends to +sleep. +complete_work_sync() is used in peer_unmap_event bh handler +which tries to yield the CPU(calls schedule) +until the worker completes. This results kernel reporting +schedule in atomic context and system crash. +Add new global wmi_ast_list and add all ast add/update +work to this list. +Add a new global wmi_ast_work and queue this +work on each entry to global wmi_ast_list list. +Process the wmi_ast_list in worker and send updates +to FW. +Each ast entry node is shared between global wmi_ast list +and peer specific ast_list and deletes will be done +in sync between two lists. +On peer deletion all the peer specific entries will +be deleted from wmi_ast_list and peer delete in progress +will be set to avoid new ast entries adding up and therefore +peer unmap evnt won't find any ast worker in progress +entries to free in irq context. +This peer ast cleanup and worker processing same entry +will be synchronized with new base_ast_lock mutex. +FW indpendently Deleting a single wds ast entry in irq context & +worker already processing the same cannot be synchronized. +As we can't hold bh scheduling while worker tries to sleep, +and entry in scheduled update work will be sent to FW. + +Signed-off-by: Rameshkumar Sundaram +--- + drivers/net/wireless/ath/ath11k/ahb.c | 1 + + drivers/net/wireless/ath/ath11k/core.c | 3 + + drivers/net/wireless/ath/ath11k/core.h | 4 + + drivers/net/wireless/ath/ath11k/nss.c | 6 +- + drivers/net/wireless/ath/ath11k/nss.h | 8 +- + drivers/net/wireless/ath/ath11k/pci.c | 1 + + drivers/net/wireless/ath/ath11k/peer.c | 172 ++++++++++++++++++++++++--------- + drivers/net/wireless/ath/ath11k/peer.h | 3 +- + 8 files changed, 144 insertions(+), 54 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/ahb.c ++++ b/drivers/net/wireless/ath/ath11k/ahb.c +@@ -1245,6 +1245,7 @@ static void ath11k_ahb_remove_prepare(st + set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags); + cancel_work_sync(&ab->restart_work); + cancel_work_sync(&ab->qmi.event_work); ++ cancel_work_sync(&ab->wmi_ast_work); + } + + 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 + + mutex_init(&ab->core_lock); + mutex_init(&ab->tbl_mtx_lock); ++ mutex_init(&ab->base_ast_lock); + 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 + 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); ++ INIT_WORK(&ab->wmi_ast_work, ath11k_peer_ast_wds_wmi_wk); ++ INIT_LIST_HEAD(&ab->wmi_ast_list); + timer_setup(&ab->rx_replenish_retry, ath11k_ce_rx_replenish_retry, 0); + init_completion(&ab->htc_suspend); + 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 @@ + #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 { + + 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; ++ + /* 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 + spin_unlock_bh(&ab->base_lock); + } + +-static void ath11k_nss_mec_handler(struct ath11k *ar, u8* mec_mac_addr) ++static void ath11k_nss_mec_handler(struct ath11k_vif *arvif, u8* mec_mac_addr) + { ++ struct ath11k *ar = arvif->ar; + 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 + memcpy(mac_addr, mac_addr_h16, ETH_ALEN - 4); + memcpy(mac_addr + 2, mac_addr_l32, 4); + +- if (!ether_addr_equal(ar->mac_addr, mac_addr)) { ++ if (!ether_addr_equal(arvif->vif->addr, mac_addr)) { + 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_ + addr4_valid, peer_id); + break; + case NSS_WIFI_VDEV_WDS_TYPE_MEC: +- ath11k_nss_mec_handler(ar, (u8 *)(skb->data)); ++ ath11k_nss_mec_handler(arvif, (u8 *)(skb->data)); + break; + default: + ath11k_warn(ab, "unsupported wds_type %d\n", wds_type); +@@ -3848,11 +3849,7 @@ int ath11k_nss_add_wds_peer(struct ath11 + wds_peer_msg->ast_type = type; + wds_peer_msg->peer_id = peer->peer_id; + +- if (type == ATH11K_AST_TYPE_MEC) +- ether_addr_copy(wds_peer_msg->peer_mac, ar->mac_addr); +- else +- ether_addr_copy(wds_peer_msg->peer_mac, peer->addr); +- ++ ether_addr_copy(wds_peer_msg->peer_mac, peer->addr); + 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: + return ret; + } + +-int ath11k_nss_del_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, ++int ath11k_nss_del_wds_peer(struct ath11k *ar, u8 *peer_addr, int peer_id, + u8 *dest_mac) + { + struct ath11k_base *ab = ar->ab; +@@ -3993,8 +3990,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; +- wds_peer_msg->peer_id = peer->peer_id; +- ether_addr_copy(wds_peer_msg->peer_mac, peer->addr); ++ wds_peer_msg->peer_id = peer_id; ++ ether_addr_copy(wds_peer_msg->peer_mac, peer_addr); + ether_addr_copy(wds_peer_msg->dest_mac, dest_mac); + + 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 + 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); +-int ath11k_nss_del_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, +- u8 *dest_mac); ++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, + 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 + return 0; + } + +-static inline int ath11k_nss_del_wds_peer(struct ath11k_vif *arvif, struct ath11k_peer *peer, +- u8 *dest_mac) ++static inline int ath11k_nss_del_wds_peer(struct ath11k *ar, u8 *peer_addr, ++ int peer_id, u8 *dest_mac) + { + return 0; + } +--- 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 + } + + set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags); ++ cancel_work_sync(&ab->wmi_ast_work); + + ath11k_core_deinit(ab); + +--- a/drivers/net/wireless/ath/ath11k/peer.c ++++ b/drivers/net/wireless/ath/ath11k/peer.c +@@ -160,49 +160,68 @@ struct ath11k_ast_entry *ath11k_peer_ast + + void ath11k_peer_ast_wds_wmi_wk(struct work_struct *wk) + { +- struct ath11k_ast_entry *ast_entry = container_of(wk, +- struct ath11k_ast_entry, +- wds_wmi_wk); +- struct ath11k *ar; ++ struct ath11k_ast_entry *ast_entry, *entry; ++ struct ath11k_base *ab = container_of(wk, struct ath11k_base, wmi_ast_work); + struct ath11k_peer *peer; ++ struct ath11k *ar; + int ret; ++ u8 peer_addr[ETH_ALEN]; ++ int peer_id; + +- if (!ast_entry) +- return; ++ ast_entry = kzalloc(sizeof(*ast_entry), GFP_ATOMIC); + +- ar = ast_entry->ar; +- peer = ast_entry->peer; ++ mutex_lock(&ab->base_ast_lock); ++ spin_lock_bh(&ab->base_lock); ++ ++ while ((entry = list_first_entry_or_null(&ab->wmi_ast_list, ++ struct ath11k_ast_entry, wmi_list))) { ++ list_del_init(&entry->wmi_list); + +- ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "ath11k_peer_ast_wds_wmi_wk action %d ast_entry %pM next_node %pM vdev %d\n", +- ast_entry->action, ast_entry->addr, ast_entry->next_node_mac, +- ast_entry->vdev_id); +- +- if (ast_entry->action == ATH11K_WDS_WMI_ADD) { +- ret = ath11k_wmi_send_add_update_wds_entry_cmd(ar, +- ast_entry->next_node_mac, +- ast_entry->addr, +- ast_entry->vdev_id, +- true); +- if (ret) { +- ath11k_warn(ar->ab, "add wds_entry_cmd failed %d for %pM next_node %pM\n", +- ret, ast_entry->addr, +- ast_entry->next_node_mac); +- if (peer) +- ath11k_nss_del_wds_peer(ar, peer, +- ast_entry->addr); ++ if (!entry->ar || (entry->peer && entry->peer->delete_in_progress)) { ++ continue; + } +- } else if (ast_entry->action == ATH11K_WDS_WMI_UPDATE) { +- if (!peer) +- return; ++ memcpy(ast_entry, entry, sizeof(*ast_entry)); ++ ar = ast_entry->ar; ++ peer = ast_entry->peer; ++ memcpy(peer_addr, peer->addr, sizeof(peer_addr)); ++ peer_id = peer->peer_id; ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, ++ "ath11k_peer_ast_wds_wmi_wk action %d ast_entry %pM peer %pM vdev %d\n", ++ ast_entry->action, ast_entry->addr, peer_addr, ++ ast_entry->vdev_id); + +- ret = ath11k_wmi_send_add_update_wds_entry_cmd(ar, peer->addr, +- ast_entry->addr, +- ast_entry->vdev_id, +- false); +- if (ret) +- ath11k_warn(ar->ab, "update wds_entry_cmd failed %d for %pM on peer %pM\n", +- ret, ast_entry->addr, peer->addr); ++ if (ast_entry->action == ATH11K_WDS_WMI_ADD) { ++ spin_unlock_bh(&ab->base_lock); ++ ret = ath11k_wmi_send_add_update_wds_entry_cmd(ar, peer_addr, ++ ast_entry->addr, ++ ast_entry->vdev_id, ++ true); ++ if (ret) { ++ ath11k_warn(ar->ab, "add wds_entry_cmd failed %d for %pM, peer %pM\n", ++ ret, ast_entry->addr, peer_addr); ++ if (peer) ++ ath11k_nss_del_wds_peer(ar, peer_addr, peer_id, ++ ast_entry->addr); ++ } ++ } else if (ast_entry->action == ATH11K_WDS_WMI_UPDATE) { ++ if (!peer) { ++ continue; ++ } ++ spin_unlock_bh(&ab->base_lock); ++ ret = ath11k_wmi_send_add_update_wds_entry_cmd(ar, peer_addr, ++ ast_entry->addr, ++ ast_entry->vdev_id, ++ false); ++ if (ret) ++ ath11k_warn(ar->ab, "update wds_entry_cmd failed %d for %pM on peer %pM\n", ++ ret, ast_entry->addr, peer_addr); ++ } ++ spin_lock_bh(&ab->base_lock); + } ++ spin_unlock_bh(&ab->base_lock); ++ mutex_unlock(&ab->base_ast_lock); ++ kfree(ast_entry); + } + + int ath11k_peer_add_ast(struct ath11k *ar, struct ath11k_peer *peer, +@@ -211,6 +230,8 @@ int ath11k_peer_add_ast(struct ath11k *a + struct ath11k_ast_entry *ast_entry = NULL; + struct ath11k_base *ab = ar->ab; + ++ lockdep_assert_held(&ab->base_lock); ++ + if (ab->num_ast_entries == ab->max_ast_index) { + ath11k_warn(ab, "failed to add ast for %pM due to insufficient ast entry resource %d in target\n", + mac_addr, ab->max_ast_index); +@@ -226,6 +247,9 @@ int ath11k_peer_add_ast(struct ath11k *a + } + } + ++ if (peer && peer->delete_in_progress) ++ return -EINVAL; ++ + ast_entry = kzalloc(sizeof(*ast_entry), GFP_ATOMIC); + if (!ast_entry) { + ath11k_warn(ab, "failed to alloc ast_entry for %pM\n", +@@ -257,7 +281,7 @@ int ath11k_peer_add_ast(struct ath11k *a + } + + INIT_LIST_HEAD(&ast_entry->ase_list); +- INIT_WORK(&ast_entry->wds_wmi_wk, ath11k_peer_ast_wds_wmi_wk); ++ INIT_LIST_HEAD(&ast_entry->wmi_list); + ast_entry->vdev_id = peer->vdev_id; + ast_entry->pdev_idx = peer->pdev_idx; + ast_entry->is_mapped = false; +@@ -271,16 +295,12 @@ int ath11k_peer_add_ast(struct ath11k *a + ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_add_ast peer %pM ast_entry %pM, ast_type %d\n", + peer->addr, mac_addr, ast_entry->type); + +- if (type == ATH11K_AST_TYPE_MEC) +- ether_addr_copy(ast_entry->next_node_mac, ar->mac_addr); +- else if (type == ATH11K_AST_TYPE_WDS) +- ether_addr_copy(ast_entry->next_node_mac, peer->addr); +- + if ((ast_entry->type == ATH11K_AST_TYPE_WDS) || + (ast_entry->type == ATH11K_AST_TYPE_MEC)) { + ath11k_nss_add_wds_peer(ar, peer, mac_addr, ast_entry->type); + ast_entry->action = ATH11K_WDS_WMI_ADD; +- ieee80211_queue_work(ar->hw, &ast_entry->wds_wmi_wk); ++ list_add_tail(&ast_entry->wmi_list, &ab->wmi_ast_list); ++ ieee80211_queue_work(ar->hw, &ab->wmi_ast_work); + } + + ab->num_ast_entries++; +@@ -293,6 +313,8 @@ int ath11k_peer_update_ast(struct ath11k + struct ath11k_peer *old_peer = ast_entry->peer; + struct ath11k_base *ab = ar->ab; + ++ lockdep_assert_held(&ab->base_lock); ++ + if (!ast_entry->is_mapped) { + ath11k_warn(ab, "ath11k_peer_update_ast: ast_entry %pM not mapped yet\n", + ast_entry->addr); +@@ -305,6 +327,9 @@ int ath11k_peer_update_ast(struct ath11k + (ast_entry->is_active)) + return 0; + ++ if (peer && peer->delete_in_progress) ++ return -EINVAL; ++ + ast_entry->vdev_id = peer->vdev_id; + ast_entry->pdev_idx = peer->pdev_idx; + ast_entry->type = ATH11K_AST_TYPE_WDS; +@@ -317,7 +342,14 @@ int ath11k_peer_update_ast(struct ath11k + old_peer->addr, peer->addr, ast_entry->addr); + + ast_entry->action = ATH11K_WDS_WMI_UPDATE; +- ieee80211_queue_work(ar->hw, &ast_entry->wds_wmi_wk); ++ ++ /* wmi_list entry might've been processed & removed.*/ ++ if (list_empty(&ast_entry->wmi_list)) ++ list_add_tail(&ast_entry->wmi_list, &ab->wmi_ast_list); ++ else ++ list_move_tail(&ast_entry->wmi_list, &ab->wmi_ast_list); ++ ++ ieee80211_queue_work(ar->hw, &ab->wmi_ast_work); + + return 0; + } +@@ -363,16 +395,23 @@ void ath11k_peer_del_ast(struct ath11k * + ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_del_ast pdev:%d peer %pM ast_entry %pM\n", + ar->pdev->pdev_id, peer->addr, ast_entry->addr); + +- if (ast_entry->is_mapped) +- list_del(&ast_entry->ase_list); ++ if ((ast_entry->type == ATH11K_AST_TYPE_WDS) || ++ (ast_entry->type == ATH11K_AST_TYPE_MEC)) { ++ if (!list_empty(&ast_entry->wmi_list)) { ++ ath11k_dbg(ab, ATH11K_DBG_MAC, ++ "ath11k_peer_del_ast deleting unprocessed ast entry %pM " ++ "of peer %pM from wmi list\n", ast_entry->addr, peer->addr); ++ list_del_init(&ast_entry->wmi_list); ++ } ++ } ++ list_del(&ast_entry->ase_list); + + /* WDS, MEC type AST entries need to be deleted on NSS */ + if (ast_entry->next_hop) +- ath11k_nss_del_wds_peer(ar, peer, ast_entry->addr); ++ ath11k_nss_del_wds_peer(ar, peer->addr, peer->peer_id, ++ ast_entry->addr); + +- cancel_work_sync(&ast_entry->wds_wmi_wk); + kfree(ast_entry); +- + ab->num_ast_entries--; + } + +@@ -681,6 +720,10 @@ void ath11k_peer_cleanup(struct ath11k * + + lockdep_assert_held(&ar->conf_mutex); + ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ mutex_lock(&ab->base_ast_lock); ++#endif ++ + mutex_lock(&ab->tbl_mtx_lock); + spin_lock_bh(&ab->base_lock); + list_for_each_entry_safe(peer, tmp_peer, &ab->peers, list) { +@@ -709,6 +752,9 @@ void ath11k_peer_cleanup(struct ath11k * + + spin_unlock_bh(&ab->base_lock); + mutex_unlock(&ab->tbl_mtx_lock); ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ mutex_unlock(&ab->base_ast_lock); ++#endif + } + + static int ath11k_wait_for_peer_deleted(struct ath11k *ar, int vdev_id, const u8 *addr) +@@ -743,12 +789,18 @@ static int __ath11k_peer_delete(struct a + int ret; + struct ath11k_peer *peer; + struct ath11k_base *ab = ar->ab; ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ struct ath11k_ast_entry *ast_entry, *tmp_ast; ++#endif + + lockdep_assert_held(&ar->conf_mutex); + + reinit_completion(&ar->peer_delete_done); + ath11k_nss_peer_delete(ar->ab, vdev_id, addr); + ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ mutex_lock(&ab->base_ast_lock); ++#endif + mutex_lock(&ab->tbl_mtx_lock); + spin_lock_bh(&ab->base_lock); + +@@ -771,17 +823,35 @@ static int __ath11k_peer_delete(struct a + return -EINVAL; + } + +- /* Check if the found peer is what we want to remove. +- * While the sta is transitioning to another band we may +- * have 2 peer with the same addr assigned to different +- * vdev_id. Make sure we are deleting the correct peer. +- */ +- if (peer && peer->vdev_id == vdev_id) ++ if (peer) { ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ peer->delete_in_progress = true; ++ if (peer->self_ast_entry) { ++ ath11k_peer_del_ast(ar, peer->self_ast_entry); ++ peer->self_ast_entry = NULL; ++ } ++ ++ list_for_each_entry_safe(ast_entry, tmp_ast, ++ &peer->ast_entry_list, ase_list) ++ if ((ast_entry->type == ATH11K_AST_TYPE_WDS) || ++ (ast_entry->type == ATH11K_AST_TYPE_MEC)) { ++ if (!list_empty(&ast_entry->wmi_list)) { ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, ++ "%s deleting unprocessed ast entry %pM of peer %pM from wmi list\n", ++ __func__, ast_entry->addr, addr); ++ list_del_init(&ast_entry->wmi_list); ++ } ++ } ++#endif + ath11k_peer_rhash_delete(ab, peer); ++ } + + spin_unlock_bh(&ab->base_lock); + mutex_unlock(&ab->tbl_mtx_lock); + ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ mutex_unlock(&ab->base_ast_lock); ++#endif + + ret = ath11k_wmi_send_peer_delete_cmd(ar, addr, vdev_id); + 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 { + struct ath11k_ast_entry { + u16 ast_idx; + u8 addr[ETH_ALEN]; +- u8 next_node_mac[ETH_ALEN]; + enum ath11k_wds_wmi_action action; +- struct work_struct wds_wmi_wk; + struct ath11k_peer *peer; + struct ath11k *ar; + bool next_hop; +@@ -47,6 +45,7 @@ struct ath11k_ast_entry { + 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 { + bool dp_setup_done; + struct ppdu_user_delayba ppdu_stats_delayba; + bool delayba_flag; ++ bool delete_in_progress; + }; + + void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id); 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/ath11k_nss/908-362-ath11k-fix-incorrect-ast-index-assignment-for-wds-peer.patch new file mode 100644 index 00000000000000..f734c5aea8d876 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/908-362-ath11k-fix-incorrect-ast-index-assignment-for-wds-peer.patch @@ -0,0 +1,96 @@ +From 396176575be9767a79d451fba4fe2931305f0435 Mon Sep 17 00:00:00 2001 +From: Raj Kumar Bhagat +Date: Mon, 7 Nov 2022 21:49:20 +0530 +Subject: [PATCH] ath11k: fix incorrect ast index assignment for wds peer + +Currently, same ast index is assigned for different nss wds peer mac +addresses which is incorrect. However, firmware provides the correct +and different ast index for different mac addresses. + +Hence, fix this issue by assigning the correct ast index provided by +the firmware. + +Signed-off-by: Raj Kumar Bhagat +--- + drivers/net/wireless/ath/ath11k/nss.c | 5 +++-- + drivers/net/wireless/ath/ath11k/nss.h | 6 ++++-- + drivers/net/wireless/ath/ath11k/peer.c | 3 +-- + 3 files changed, 8 insertions(+), 6 deletions(-) + +--- 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: + } + + int ath11k_nss_map_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, +- u8 *dest_mac, enum ath11k_ast_entry_type type) ++ u8 *dest_mac, struct ath11k_ast_entry *ast_entry) + { + struct ath11k_base *ab = ar->ab; + struct nss_wifili_wds_peer_map_msg *wds_peer_map_msg; + struct nss_wifili_msg *wlmsg = NULL; + nss_wifili_msg_callback_t msg_cb; + nss_tx_status_t status; ++ enum ath11k_ast_entry_type type = ast_entry->type; + int ret = 0; + + wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); +@@ -2503,7 +2502,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; +- wds_peer_map_msg->ast_idx = peer->hw_peer_id; ++ wds_peer_map_msg->ast_idx = ast_entry->ast_idx; + + if (type == ATH11K_AST_TYPE_MEC) + 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; + struct ath11k_base; + struct ath11k_vif; + struct ath11k_peer; ++struct ath11k_ast_entry; + 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 + 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, +- u8 *dest_mac, enum ath11k_ast_entry_type type); ++ u8 *dest_mac, struct ath11k_ast_entry *ast_entry); + 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_ + } + + static inline int ath11k_nss_map_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, +- u8 *dest_mac, int type) ++ u8 *dest_mac, ++ struct ath11k_ast_entry *ast_entry) + { + return 0; + } +--- a/drivers/net/wireless/ath/ath11k/peer.c ++++ b/drivers/net/wireless/ath/ath11k/peer.c +@@ -373,8 +373,7 @@ void ath11k_peer_map_ast(struct ath11k * + + if ((ast_entry->type == ATH11K_AST_TYPE_WDS) || + (ast_entry->type == ATH11K_AST_TYPE_MEC)) +- ath11k_nss_map_wds_peer(ar, peer, mac_addr, +- ast_entry->type); ++ ath11k_nss_map_wds_peer(ar, peer, mac_addr, ast_entry); + + ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_map_ast peer %pM ast_entry %pM\n", + peer->addr, ast_entry->addr); From a255885a83ebb4f1258228c829e9c281ecf88256 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 13 Jan 2024 17:13:16 -0500 Subject: [PATCH 087/225] ath11k_nss: fix `'ppdu_info' is a pointer...` error --- ...ul-ofdma-ru-allocation-in-peer-stats.patch | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) 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/ath11k_nss/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch index e7908c6daad2a7..9be70411b10996 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/ath11k_nss/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch @@ -247,19 +247,20 @@ int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id, struct napi_struct *napi, int budget) { -@@ -5919,8 +6084,13 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -5917,10 +6082,13 @@ int ath11k_dp_rx_process_mon_status(stru + goto next_skb; + } - if ((ppdu_info->fc_valid) && - (ppdu_info->ast_index != HAL_AST_IDX_INVALID)) { -- arsta = (struct ath11k_sta *)peer->sta->drv_priv; +- 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; - ath11k_dp_rx_update_peer_stats(arsta, 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); -+ } ++ 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 (ath11k_debugfs_is_pktlog_peer_valid(ar, peer->addr)) From 449ed88b550f40af8068e88ffe6e973d7d22a12b Mon Sep 17 00:00:00 2001 From: Qosmio Date: Tue, 16 Jan 2024 18:45:18 -0500 Subject: [PATCH 088/225] ath11k_nss: bugfix NSS memleak + enhancements bugfixes: * Rreverted patch `105-ath11k-fix-monitor-crash-if-tx-offload-is-enabled.patch`. Initial test show lower memory use. `ieee80211_tx_status_8023` was also removed upstream for a reason as it wasn't being used, and the logic behind it was flawed. See https://patchwork.kernel.org/project/linux-wireless/patch/20230308174703.12270-2-quic_pradeepc@quicinc.com * Mmemory profile for '256M' was missing logic that was in 512/1G. Should build correctly now * added more qsdk related patches to nss/offload --- package/kernel/mac80211/Makefile | 2 +- ...nitor-crash-if-tx-offload-is-enabled.patch | 60 -- ...-ath11k_nss-add-nss-driver-interface.patch | 4 +- .../199-003-ath11k-add-nss-support.patch | 6 +- ...-ath11k-Add-support-for-dynamic-vlan.patch | 6 +- ...207-ath11k-Enable-256_512MB-profiles.patch | 16 +- .../patches/ath11k_nss/900-fix-build.patch | 46 -- ...load-changes-to-NSS-driver-interface.patch | 19 +- ...04-300-ath11k-nss_get_arvif_from_dev.patch | 4 +- ...support-to-send-the-QoS-Null-Data-fr.patch | 31 + .../906-ath11k-m3-ssr-dump-collection.patch | 10 +- .../908-301-ath11k-nss-mcbc-exception.patch | 6 +- .../911-244-ath11k-dp-tx-perf.patch | 623 ++++++++++++++++++ ...-0001-ath11k-optimize-tx-completions.patch | 269 ++++++++ ...se-DECLARE_BITMAP-for-idr-operations.patch | 288 ++++++++ ...1k-add-simple-tx-handler-for-AP-mode.patch | 185 ++++++ .../911-335-ath11k-fix-ar-ops-crash.patch | 71 ++ ...Add-retry-mechanism-for-update_rx_qu.patch | 384 +++++++++++ ...rt-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch | 52 ++ ...-frags-from-uninitialized-peer-in-dp.patch | 74 +++ ...356-ath11k-invalid-desc-sanity-check.patch | 74 +++ ...k-skb_headroom-before-using-skb_push.patch | 209 ++++++ ...fix-RCU-stall-in-mesh-fast-xmit-path.patch | 120 ++++ ...ix-crash-when-accessing-null-pointer.patch | 87 +++ ...ing-memset-of-ppdu-info-for-next-skb.patch | 87 +++ 25 files changed, 2578 insertions(+), 155 deletions(-) delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/105-ath11k-fix-monitor-crash-if-tx-offload-is-enabled.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/906-456-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/911-244-ath11k-dp-tx-perf.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/911-335-0001-ath11k-optimize-tx-completions.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/911-335-0002-ath11k-use-DECLARE_BITMAP-for-idr-operations.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/911-335-0006-ath11k-add-simple-tx-handler-for-AP-mode.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/911-335-ath11k-fix-ar-ops-crash.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/913-341-ath11k-fix-support-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/913-353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/913-356-ath11k-invalid-desc-sanity-check.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/913-374-ath11k-Check-skb_headroom-before-using-skb_push.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/913-686-mac80211-fix-RCU-stall-in-mesh-fast-xmit-path.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/913-726-mac80211-fix-crash-when-accessing-null-pointer.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/913-830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 713e6d57122a43..fe3350ab593faa 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 PKG_VERSION:=6.5 -PKG_RELEASE:=5 +PKG_RELEASE:=6 # PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.15.58/ PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/ PKG_HASH:=908c22dceba185eab83caa5a1e58ce6b3ebdc58f099c3fd3e11c7352ebfab2d7 diff --git a/package/kernel/mac80211/patches/ath11k_nss/105-ath11k-fix-monitor-crash-if-tx-offload-is-enabled.patch b/package/kernel/mac80211/patches/ath11k_nss/105-ath11k-fix-monitor-crash-if-tx-offload-is-enabled.patch deleted file mode 100644 index 9304833c87d1c3..00000000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/105-ath11k-fix-monitor-crash-if-tx-offload-is-enabled.patch +++ /dev/null @@ -1,60 +0,0 @@ - drivers/net/wireless/ath/ath11k/dp_tx.c | 20 +++++++++++++++++--- - 1 file changed, 17 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/ath/ath11k/dp_tx.c -+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -@@ -322,6 +322,8 @@ ath11k_dp_tx_htt_tx_complete_buf(struct - struct ath11k_skb_cb *skb_cb; - struct ath11k *ar; - struct ath11k_peer *peer; -+ struct ieee80211_vif *vif; -+ u8 flags = 0; - - spin_lock(&tx_ring->tx_idr_lock); - msdu = idr_remove(&tx_ring->txbuf_idr, ts->msdu_id); -@@ -348,6 +350,14 @@ ath11k_dp_tx_htt_tx_complete_buf(struct - return; - } - -+ if (!skb_cb->vif) { -+ dev_kfree_skb_any(msdu); -+ return; -+ } -+ -+ flags = skb_cb->flags; -+ vif = skb_cb->vif; -+ - memset(&info->status, 0, sizeof(info->status)); - - if (ts->acked) { -@@ -555,6 +565,8 @@ static void ath11k_dp_tx_complete_msdu(s - struct ath11k_peer *peer; - struct ath11k_sta *arsta; - struct rate_info rate; -+ struct ieee80211_vif *vif; -+ u8 flags = 0; - - if (WARN_ON_ONCE(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) { - /* Must not happen */ -@@ -575,6 +587,9 @@ static void ath11k_dp_tx_complete_msdu(s - return; - } - -+ flags = skb_cb->flags; -+ vif = skb_cb->vif; -+ - info = IEEE80211_SKB_CB(msdu); - memset(&info->status, 0, sizeof(info->status)); - -@@ -641,7 +656,10 @@ static void ath11k_dp_tx_complete_msdu(s - - spin_unlock_bh(&ab->base_lock); - -- ieee80211_tx_status_ext(ar->hw, &status); -+ if (flags & ATH11K_SKB_HW_80211_ENCAP) -+ ieee80211_tx_status_8023(ar->hw, vif, msdu); -+ else -+ ieee80211_tx_status_ext(ar->hw, &status); - } - - static inline void ath11k_dp_tx_status_parse(struct ath11k_base *ab, diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch b/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch index beee16098f14c3..79f8190d5b990f 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch @@ -600,8 +600,8 @@ Signed-off-by: Sriram R + __attribute__((unused)) struct napi_struct *napi) +{ + enum ath11k_hw_txrx_mode decap_type; -+ struct wireless_dev *wdev; -+ struct ieee80211_vif *vif; ++ struct wireless_dev *wdev = NULL; ++ struct ieee80211_vif *vif = NULL; + struct ath11k_vif *arvif; + struct ath11k_base *ab; + bool eth_decap = false; diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch b/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch index ffae0a9448ef8b..34b30984ca76d2 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch @@ -557,15 +557,13 @@ Signed-off-by: Sriram R exit: mutex_unlock(&ar->conf_mutex); return ret; -@@ -6216,10 +6279,16 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6216,10 +6279,14 @@ static void ath11k_mac_op_tx(struct ieee if (control->sta) arsta = ath11k_sta_to_arsta(control->sta); - ret = ath11k_dp_tx(ar, arvif, arsta, skb); -+ if (ar->ab->nss.enabled) { -+ arvif->ar->ab->nss.debug_mode = true; ++ if (ar->ab->nss.enabled) + ret = ath11k_nss_tx(arvif, skb); -+ } + else + ret = ath11k_dp_tx(ar, arvif, arsta, skb); if (unlikely(ret)) { diff --git a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch index b17b9fb419745d..a937ffba79961c 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch @@ -150,9 +150,9 @@ Signed-off-by: Seevalamuthu Mariappan spin_lock_bh(&tx_ring->tx_idr_lock); idr_remove(&tx_ring->txbuf_idr, FIELD_GET(DP_TX_DESC_ID_MSDU_ID, ti.desc_id)); -@@ -358,6 +429,9 @@ ath11k_dp_tx_htt_tx_complete_buf(struct - flags = skb_cb->flags; - vif = skb_cb->vif; +@@ -348,6 +419,9 @@ 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 */ diff --git a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch index a4c063ce69ba49..eaf14c700dd4c8 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch @@ -50,11 +50,11 @@ Signed-off-by: Ramya Gnanasekar /* Target configuration defines */ +#if defined(CPTCFG_ATH11K_MEM_PROFILE_256M) -+#define TARGET_NUM_VDEVS 8 -+#define TARGET_NUM_PEERS_PDEV (128 + TARGET_NUM_VDEVS) ++#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 128 -+#define ATH11K_QMI_TARGET_MEM_MODE ATH11K_QMI_TARGET_MEM_MODE_512M ++#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 @@ -374,13 +374,7 @@ Signed-off-by: Ramya Gnanasekar --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c -@@ -1592,10 +1592,13 @@ static ssize_t ath11k_dump_mgmt_stats(st - size_t count, loff_t *ppos) - { - struct ath11k *ar = file->private_data; -+#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M -+ struct ath11k_base *ab = ar->ab; -+#endif +@@ -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; diff --git a/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch b/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch index 180fb7feab2e49..12feacda8555f7 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch @@ -104,19 +104,6 @@ NL80211_CMD_COLOR_CHANGE_COMPLETED, 0, 0); } ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -5241,6 +5241,10 @@ void ieee80211_tx_status_ext(struct ieee - * (NULL for multicast packets) - * @info: tx status information - */ -+void ieee80211_tx_status_8023(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ struct sk_buff *skb); -+ - static inline void ieee80211_tx_status_noskb(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, - struct ieee80211_tx_info *info) --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -4777,7 +4777,7 @@ void ieee80211_color_collision_detection @@ -160,39 +147,6 @@ /* now keys can no longer be reached */ ieee80211_free_sta_keys(local, sta); ---- a/net/mac80211/status.c -+++ b/net/mac80211/status.c -@@ -1244,6 +1244,30 @@ void ieee80211_tx_rate_update(struct iee - } - EXPORT_SYMBOL(ieee80211_tx_rate_update); - -+void ieee80211_tx_status_8023(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ struct sk_buff *skb) -+{ -+ struct ieee80211_sub_if_data *sdata; -+ struct ieee80211_tx_status status = { -+ .skb = skb, -+ .info = IEEE80211_SKB_CB(skb), -+ }; -+ struct sta_info *sta; -+ -+ sdata = vif_to_sdata(vif); -+ -+ rcu_read_lock(); -+ -+ if (!ieee80211_lookup_ra_sta(sdata, skb, &sta) && !IS_ERR(sta)) -+ status.sta = &sta->sta; -+ -+ ieee80211_tx_status_ext(hw, &status); -+ -+ rcu_read_unlock(); -+} -+EXPORT_SYMBOL(ieee80211_tx_status_8023); -+ - void ieee80211_report_low_ack(struct ieee80211_sta *pubsta, u32 num_packets) - { - struct sta_info *sta = container_of(pubsta, struct sta_info, sta); --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -19414,7 +19414,7 @@ void cfg80211_ch_switch_started_notify(s 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/ath11k_nss/902-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch index 7e2a9f0ee4dd4b..47146c459e796e 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/ath11k_nss/902-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch @@ -13,20 +13,7 @@ Signed-off-by: Sathishkumar Muruganandam --- a/drivers/net/wireless/ath/ath11k/nss.c +++ b/drivers/net/wireless/ath/ath11k/nss.c -@@ -9,10 +9,12 @@ - #include "nss.h" - #include "core.h" - #include "peer.h" -+#include "dp_tx.h" - #include "dp_rx.h" - #include "dp_tx.h" - #include "hif.h" - #include "wmi.h" -+#include "wmi.h" - #include "../../../../../net/mac80211/sta_info.h" - - /*-----------------------------ATH11K-NSS Helpers--------------------------*/ -@@ -348,6 +350,22 @@ void ath11k_nss_wifili_event_receive(str +@@ -348,6 +348,22 @@ void ath11k_nss_wifili_event_receive(str ath11k_nss_wifili_link_desc_return(ab, (void *)&msg->msg.linkdescinfomsg); break; @@ -301,8 +288,8 @@ Signed-off-by: Sathishkumar Muruganandam __attribute__((unused)) struct napi_struct *napi) { - enum ath11k_hw_txrx_mode decap_type; - struct wireless_dev *wdev; - struct ieee80211_vif *vif; + 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_ ath11k_dbg_dump(ab, ATH11K_DBG_DP_RX, "", "dp rx msdu from nss: ", 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 index 5d695ccfe55f2e..86812a1830d817 100644 --- 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 @@ -85,9 +85,9 @@ Signed-off-by: Vasanthakumar Thiagarajan break; } } -@@ -786,24 +814,7 @@ ath11k_nss_vdev_special_data_receive(str +@@ -785,24 +813,7 @@ ath11k_nss_vdev_special_data_receive(str + int data_offs = 0; int ret = 0; - struct ath11k_peer *ta_peer = NULL; - if (!dev) { - dev_kfree_skb_any(skb); 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/ath11k_nss/906-456-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch new file mode 100644 index 00000000000000..10c39288094b5f --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/906-456-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch @@ -0,0 +1,31 @@ +From 047c8f3ea16fe1d071f83b51b8c132f797903c91 Mon Sep 17 00:00:00 2001 +From: Karthikeyan Periyasamy +Date: Tue, 10 Oct 2023 09:13:38 +0530 +Subject: [PATCH] wifi: ath11k: Add support to send the QoS Null Data frame + through exception path + +When we try to send QoS NULL Data frame in Ethernet encap type, it modified +as QoS Data frame with TID 0 (encryption enabled one if security enabled). +But expectation is, it should be send as open type frame with TID 7 since +its a QoS NULL data frame. + +Added this frame under exception route to bypass TCL with the help of FW. + +Signed-off-by: Karthikeyan Periyasamy +--- + drivers/net/wireless/ath/ath11k/dp_tx.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- 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: + + 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))) + is_diff_encap = true; + else + ath11k_dp_tx_encap_nwifi(skb); diff --git a/package/kernel/mac80211/patches/ath11k_nss/906-ath11k-m3-ssr-dump-collection.patch b/package/kernel/mac80211/patches/ath11k_nss/906-ath11k-m3-ssr-dump-collection.patch index a48875034c96b0..d65d230fa10984 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/906-ath11k-m3-ssr-dump-collection.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/906-ath11k-m3-ssr-dump-collection.patch @@ -720,13 +720,9 @@ .hal_params = &ath11k_hw_hal_params_ipq8074, .supports_dynamic_smps_6ghz = false, .alloc_cacheable_memory = true, -@@ -347,10 +368,10 @@ static struct ath11k_hw_params ath11k_hw - .supports_shadow_regs = false, - .idle_ps = false, - .supports_sta_ps = false, -- .coldboot_cal_mm = false, -+ .coldboot_cal_mm = true, - .coldboot_cal_ftm = true, +@@ -350,7 +371,7 @@ static struct ath11k_hw_params ath11k_hw + .coldboot_cal_mm = false, + .coldboot_cal_ftm = false, .cbcal_restart_fw = true, - .fw_mem_mode = 2, + .fw_mem_mode = ATH11K_QMI_TARGET_MEM_MODE, diff --git a/package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch b/package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch index bba58322a254e7..47c6b7ec3e5ae2 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch @@ -69,9 +69,9 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 int ret = 0; + struct ath11k_peer *ta_peer = NULL; - if (!dev) { - dev_kfree_skb_any(skb); -@@ -834,15 +833,50 @@ ath11k_nss_vdev_special_data_receive(str + arvif = ath11k_nss_get_arvif_from_dev(dev); + if (!arvif) { +@@ -843,15 +842,50 @@ ath11k_nss_vdev_special_data_receive(str return; } diff --git a/package/kernel/mac80211/patches/ath11k_nss/911-244-ath11k-dp-tx-perf.patch b/package/kernel/mac80211/patches/ath11k_nss/911-244-ath11k-dp-tx-perf.patch new file mode 100644 index 00000000000000..d338b0a49972ea --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/911-244-ath11k-dp-tx-perf.patch @@ -0,0 +1,623 @@ +From a19b1279d75dd1306c6eac291e985657f988780c Mon Sep 17 00:00:00 2001 +From: P Praneesh +Date: Thu, 7 Jan 2021 16:32:30 +0530 +Subject: [PATCH] ath11k: dp_tx perf improvements + + Contains below changes, + 1. Add branch prediction in tx path + 2. Allow fast tx completion by freeing skb when stats is disabled. + 3. Remove mod operator overhead for dst ring access to avoid(to be profiled) + 4. Lockless tcl ring usage since rings are selected per cpu + +Sample stats disable command: +echo 1 > /sys/kernel/debug/ath11k/qcn9000\ hw1.0_0000\:01\:00.0/stats_disable +echo 1 > /sys/kernel/debug/ath11k/ipq8074\ hw2.0/stats_disable + +Signed-off-by: Sriram R +Signed-off-by: P Praneesh +--- + drivers/net/wireless/ath/ath11k/core.h | 1 + + drivers/net/wireless/ath/ath11k/dp.c | 7 +- + drivers/net/wireless/ath/ath11k/dp_tx.c | 118 ++++++++++++++++++-------------- + drivers/net/wireless/ath/ath11k/dp_tx.h | 2 + + drivers/net/wireless/ath/ath11k/hal.c | 9 ++- + drivers/net/wireless/ath/ath11k/mac.c | 9 ++- + 6 files changed, 88 insertions(+), 58 deletions(-) + +--- 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_ + enum ath11k_skb_flags { + ATH11K_SKB_HW_80211_ENCAP = BIT(0), + ATH11K_SKB_CIPHER_SET = BIT(1), ++ ATH11K_SKB_TX_STATUS = BIT(2), + }; + + struct ath11k_skb_cb { +@@ -920,7 +921,12 @@ struct ath11k_soc_dp_tx_err_stats { + /* 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 */ + 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 + if (!ab->hw_params.supports_shadow_regs) + return; + +- for (i = 0; i < ab->hw_params.max_tx_ring; i++) ++ for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) + 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 + 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); +- for (i = 0; i < ab->hw_params.max_tx_ring; i++) { ++ 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); + } +@@ -411,6 +411,11 @@ static int ath11k_dp_srng_common_setup(s + goto err; + } + ++ if (ab->hw_params.max_tx_ring > DP_TCL_NUM_RING_MAX) { ++ srng = &ab->hal.srng_list[dp->tcl_cmd_ring.ring_id]; ++ ath11k_hal_tx_init_data_ring(ab, srng, HAL_TCL_CMD); ++ } ++ + 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 + goto err; + } + +- for (i = 0; i < ab->hw_params.max_tx_ring; i++) { ++ for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { + 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 + } + + srng = &ab->hal.srng_list[dp->tx_ring[i].tcl_data_ring.ring_id]; +- ath11k_hal_tx_init_data_ring(ab, srng); ++ ath11k_hal_tx_init_data_ring(ab, srng, HAL_TCL_DATA); + + 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 * + + ath11k_dp_reo_cmd_list_cleanup(ab); + +- for (i = 0; i < ab->hw_params.max_tx_ring; i++) { ++ for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { + 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 * + + size = sizeof(struct hal_wbm_release_ring) * DP_TX_COMP_RING_SIZE; + +- for (i = 0; i < ab->hw_params.max_tx_ring; i++) { ++ for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { + idr_init(&dp->tx_ring[i].txbuf_idr); + spin_lock_init(&dp->tx_ring[i].tx_idr_lock); + 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 + u32 ring_selector = 0; + u8 ring_map = 0; + bool tcl_ring_retry, is_diff_encap = false; +- u8 align_pad, htt_meta_size = 0; +- +- if (unlikely(test_bit(ATH11K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags))) +- return -ESHUTDOWN; ++ u8 align_pad, htt_meta_size = 0, max_tx_ring, tcl_ring_id, ring_id; + + if (unlikely(!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && + !ieee80211_is_data(hdr->frame_control))) + return -ENOTSUPP; + +- ring_selector = ab->hw_params.hw_ops->get_ring_selector(skb); ++ max_tx_ring = ab->hw_params.max_tx_ring; ++ ++#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); ++ return -ENOSPC; ++ } ++#endif ++ ring_selector = smp_processor_id();; + pool_id = ring_selector; + + tcl_ring_sel: + tcl_ring_retry = false; + +- ti.ring_id = ring_selector % ab->hw_params.max_tx_ring; +- ti.rbm_id = ab->hw_params.hal_params->tcl2wbm_rbm_map[ti.ring_id].rbm_id; ++ 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; + +- ring_map |= BIT(ti.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: + spin_unlock_bh(&tx_ring->tx_idr_lock); + + if (unlikely(ret < 0)) { +- if (ring_map == (BIT(ab->hw_params.max_tx_ring) - 1) || ++ if (ring_map == (BIT(max_tx_ring) - 1) || + !ab->hw_params.tcl_ring_retry) { +- atomic_inc(&ab->soc_stats.tx_err.misc_fail); ++ ab->soc_stats.tx_err.idr_na[tcl_ring_id]++; + return -ENOSPC; + } + +@@ -260,6 +268,11 @@ tcl_ring_sel: + ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN; + } + ++ ti.data_len = skb->len - ti.pkt_offset; ++ skb_cb->pkt_offset = ti.pkt_offset; ++ skb_cb->vif = arvif->vif; ++ skb_cb->ar = ar; ++ + 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: + goto fail_remove_idr; + } + +- ti.data_len = skb->len - ti.pkt_offset; +- skb_cb->pkt_offset = ti.pkt_offset; + skb_cb->paddr = ti.paddr; +- skb_cb->vif = arvif->vif; +- skb_cb->ar = ar; + +- hal_ring_id = tx_ring->tcl_data_ring.ring_id; ++ if (ring_id == DP_TCL_NUM_RING_MAX) ++ hal_ring_id = dp->tcl_cmd_ring.ring_id; ++ else ++ 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); +@@ -287,7 +300,7 @@ tcl_ring_sel: + * desc because the desc is directly enqueued onto hw queue. + */ + ath11k_hal_srng_access_end(ab, tcl_ring); +- ab->soc_stats.tx_err.desc_na[ti.ring_id]++; ++ ab->soc_stats.tx_err.desc_na[tcl_ring_id]++; + spin_unlock_bh(&tcl_ring->lock); + ret = -ENOMEM; + +@@ -296,8 +309,8 @@ tcl_ring_sel: + * checking this ring earlier for each pkt tx. + * Restart ring selection if some rings are not checked yet. + */ +- if (unlikely(ring_map != (BIT(ab->hw_params.max_tx_ring)) - 1) && +- ab->hw_params.tcl_ring_retry && ab->hw_params.max_tx_ring > 1) { ++ if (unlikely(ring_map != (BIT(max_tx_ring)) - 1) && ++ ab->hw_params.tcl_ring_retry && max_tx_ring > 1) { + tcl_ring_retry = true; + ring_selector++; + } +@@ -308,17 +321,17 @@ tcl_ring_sel: + ath11k_hal_tx_cmd_desc_setup(ab, hal_tcl_desc + + sizeof(struct hal_tlv_hdr), &ti); + ++ atomic_inc(&ar->dp.num_tx_pending); ++ atomic_inc(&ab->num_max_allowed); + ath11k_hal_srng_access_end(ab, tcl_ring); + +- ath11k_dp_shadow_start_timer(ab, tcl_ring, &dp->tx_ring_timer[ti.ring_id]); ++ ath11k_dp_shadow_start_timer(ab, tcl_ring, &dp->tx_ring_timer[ti.buf_id]); + + spin_unlock_bh(&tcl_ring->lock); + + ath11k_dbg_dump(ab, ATH11K_DBG_DP_TX, NULL, "dp tx msdu: ", + skb->data, skb->len); + +- atomic_inc(&ar->dp.num_tx_pending); +- atomic_inc(&ab->num_max_allowed); + + return 0; + +@@ -365,7 +378,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); +- atomic_dec(&ab->num_max_allowed); + } + + static void +@@ -379,6 +391,7 @@ ath11k_dp_tx_htt_tx_complete_buf(struct + struct ath11k_skb_cb *skb_cb; + struct ath11k *ar; + struct ath11k_peer *peer; ++ u8 flags = 0; + + 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 + + if (atomic_dec_and_test(&ar->dp.num_tx_pending)) + wake_up(&ar->dp.tx_empty_waitq); +- atomic_dec(&ab->num_max_allowed); + + dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); + ++ flags = skb_cb->flags; ++ ++ /* Free skb here if stats is disabled */ ++ if (ab->stats_disable && !(flags & ATH11K_SKB_TX_STATUS)) { ++ if (msdu->destructor) { ++ msdu->wifi_acked_valid = 1; ++ msdu->wifi_acked = ts->acked; ++ } ++ if (skb_has_frag_list(msdu)) { ++ kfree_skb_list(skb_shinfo(msdu)->frag_list); ++ skb_shinfo(msdu)->frag_list = NULL; ++ } ++ dev_kfree_skb(msdu); ++ return; ++ } ++ ++ if (unlikely(!skb_cb->vif)) { ++ dev_kfree_skb_any(msdu); ++ return; ++ } ++ + if (!skb_cb->vif) { + ieee80211_free_txskb(ar->hw, msdu); + return; +@@ -616,6 +649,7 @@ static void ath11k_dp_tx_complete_msdu(s + struct ath11k_peer *peer; + struct ath11k_sta *arsta; + struct rate_info rate; ++ u8 flags = 0; + + 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 + + dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); + ++ /* Free skb here if stats is disabled */ ++ if (ab->stats_disable && !(flags & ATH11K_SKB_TX_STATUS)) { ++ if (msdu->destructor) { ++ msdu->wifi_acked_valid = 1; ++ msdu->wifi_acked = ts->status == HAL_WBM_TQM_REL_REASON_FRAME_ACKED; ++ } ++ if (skb_has_frag_list(msdu)) { ++ kfree_skb_list(skb_shinfo(msdu)->frag_list); ++ skb_shinfo(msdu)->frag_list = NULL; ++ } ++ dev_kfree_skb(msdu); ++ return; ++ } ++ + 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 + + spin_lock_bh(&ab->base_lock); + peer = ath11k_peer_find_by_id(ab, ts->peer_id); +- if (!peer || !peer->sta) { ++ if (unlikely(!peer || !peer->sta)) { + 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 + ts->rate_stats = 0; + } + ++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; ++ ++ /* Dont consider HTT_TX_COMP_STATUS_MEC_NOTIFY */ ++ if (FIELD_GET(HTT_TX_WBM_COMP_INFO0_STATUS, status_desc->info0) == ++ HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY) ++ return false; ++ } ++ return true; ++} ++ + void ath11k_dp_tx_completion_handler(struct ath11k_base *ab, int ring_id) + { + struct ath11k *ar; + struct ath11k_dp *dp = &ab->dp; +- int hal_ring_id = dp->tx_ring[ring_id].tcl_comp_ring.ring_id; ++ 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; + struct hal_tx_status ts = { 0 }; + struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id]; + int valid_entries; + u32 *desc; +- u32 msdu_id; ++ u32 msdu_id, desc_id; + u8 mac_id; ++ struct hal_wbm_release_ring *tx_status; + + spin_lock_bh(&status_ring->lock); + +@@ -763,33 +828,27 @@ void ath11k_dp_tx_completion_handler(str + + ath11k_hal_srng_dst_invalidate_entry(ab, status_ring, valid_entries); + +- while ((ATH11K_TX_COMPL_NEXT(tx_ring->tx_status_head) != +- tx_ring->tx_status_tail) && +- (desc = ath11k_hal_srng_dst_get_next_cache_entry(ab, status_ring))) { +- memcpy(&tx_ring->tx_status[tx_ring->tx_status_head], +- desc, sizeof(struct hal_wbm_release_ring)); +- tx_ring->tx_status_head = +- 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)) ++ continue; + +- if (unlikely((ath11k_hal_srng_dst_peek(ab, status_ring) != NULL) && +- (ATH11K_TX_COMPL_NEXT(tx_ring->tx_status_head) == +- tx_ring->tx_status_tail))) { +- /* TODO: Process pending tx_status messages when kfifo_is_full() */ +- ath11k_warn(ab, "Unable to process some of the tx_status ring desc because status_fifo is full\n"); ++ memcpy(&tx_ring->tx_status[count], ++ desc, sizeof(struct hal_wbm_release_ring)); ++ count++; + } + + ath11k_hal_srng_access_end(ab, status_ring); + + spin_unlock_bh(&status_ring->lock); + +- while (ATH11K_TX_COMPL_NEXT(tx_ring->tx_status_tail) != tx_ring->tx_status_head) { +- struct hal_wbm_release_ring *tx_status; +- u32 desc_id; +- +- tx_ring->tx_status_tail = +- ATH11K_TX_COMPL_NEXT(tx_ring->tx_status_tail); +- tx_status = &tx_ring->tx_status[tx_ring->tx_status_tail]; ++ if (atomic_sub_return(count, &ab->num_max_allowed) < 0) { ++ ath11k_warn(ab, "tx completion mismatch count %d ring id %d max_num %d\n", ++ count, tx_ring->tcl_data_ring_id, ++ atomic_read(&ab->num_max_allowed)); ++ } ++ ++ while (count--) { ++ tx_status = &tx_ring->tx_status[i++]; + 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 + wake_up(&ar->dp.tx_empty_waitq); + + ath11k_dp_tx_complete_msdu(ar, msdu, &ts); +- atomic_dec(&ab->num_max_allowed); + } + } + +--- 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 + if (control->sta) + arsta = ath11k_sta_to_arsta(control->sta); + ++ /* Must call mac80211 tx status handler, else when stats is disabled we free ++ * the skb from driver. Own tx packets on monitor will also be disabled. ++ */ ++ if ((info->flags & (IEEE80211_TX_CTL_REQ_TX_STATUS | IEEE80211_TX_INTFL_NL80211_FRAME_TX)) || ++ info->ack_frame_id || vif->type == NL80211_IFTYPE_MESH_POINT || ++ test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags)) ++ skb_cb->flags |= ATH11K_SKB_TX_STATUS; ++ + if (ar->ab->nss.enabled) + ret = ath11k_nss_tx(arvif, skb); + else + ret = ath11k_dp_tx(ar, arvif, arsta, skb); ++ + if (unlikely(ret)) { +- ath11k_warn(ar->ab, "failed to transmit frame %d\n", ret); ++ if (!ar->ab->nss.enabled && ret != -ENOSPC && ret != -ENOMEM) ++ ath11k_warn(ar->ab, "failed to transmit frame %d\n", ret); + ieee80211_free_txskb(ar->hw, skb); + return; + } +@@ -7690,7 +7700,7 @@ err_vdev_del: + idr_for_each(&ar->txmgmt_idr, + ath11k_mac_vif_txmgmt_idr_remove, vif); + +- for (i = 0; i < ab->hw_params.max_tx_ring; i++) { ++ for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { + spin_lock_bh(&ab->dp.tx_ring[i].tx_idr_lock); + idr_for_each(&ab->dp.tx_ring[i].txbuf_idr, + ath11k_mac_vif_unref, vif); +--- a/drivers/net/wireless/ath/ath11k/debugfs.c ++++ b/drivers/net/wireless/ath/ath11k/debugfs.c +@@ -835,10 +835,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]); + ++ len += scnprintf(buf + len, size - len, "\nTCL Ring idr Failures:\n"); ++ for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) ++ len += scnprintf(buf + len, size - len, "ring%d: %u\n", ++ i, soc_stats->tx_err.idr_na[i]); ++ ++ len += scnprintf(buf + len, size - len, "\nMax Transmit Failures: %d\n", ++ atomic_read(&soc_stats->tx_err.max_fail)); ++ + len += scnprintf(buf + len, size - len, + "\nMisc Transmit Failures: %d\n", + atomic_read(&soc_stats->tx_err.misc_fail)); + ++ len += scnprintf(buf + len, size - len, ++ "\nNSS Transmit Failures: %d\n", ++ atomic_read(&soc_stats->tx_err.nss_tx_fail)); ++ + len += ath11k_debugfs_dump_soc_ring_bp_stats(ab, buf + len, size - len); + + if (len > size) +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -237,6 +237,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, ++ /* In addition to TCL ring use TCL_CMD ring also for tx */ ++ .max_tx_ring = DP_TCL_NUM_RING_MAX + 1, + }, + { + .name = "qca6390 hw2.0", +@@ -379,7 +381,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, +@@ -404,6 +405,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, ++ /* In addition to TCL ring use TCL_CMD ring also for tx */ ++ .max_tx_ring = DP_TCL_NUM_RING_MAX + 1, + }, + { + .name = "wcn6855 hw2.0", +@@ -2167,6 +2170,9 @@ int ath11k_core_pre_init(struct ath11k_b + + ab->enable_memory_stats = ATH11K_DEBUG_ENABLE_MEMORY_STATS; + ++ 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; ++ + return 0; + } + EXPORT_SYMBOL(ath11k_core_pre_init); +--- a/drivers/net/wireless/ath/ath11k/hal_tx.h ++++ b/drivers/net/wireless/ath/ath11k/hal_tx.h +@@ -18,7 +18,7 @@ + + struct hal_tx_info { + u16 meta_data_flags; /* %HAL_TCL_DATA_CMD_INFO0_META_ */ +- u8 ring_id; ++ u8 buf_id; + u32 desc_id; + enum hal_tcl_desc_type type; + enum hal_tcl_encap_type encap_type; +@@ -70,5 +70,5 @@ int ath11k_hal_reo_cmd_send(struct ath11 + enum hal_reo_cmd_type type, + struct ath11k_hal_reo_cmd *cmd); + void ath11k_hal_tx_init_data_ring(struct ath11k_base *ab, +- struct hal_srng *srng); ++ struct hal_srng *srng, enum hal_ring_type type); + #endif +--- a/drivers/net/wireless/ath/ath11k/hal_tx.c ++++ b/drivers/net/wireless/ath/ath11k/hal_tx.c +@@ -37,18 +37,18 @@ static const u8 dscp_tid_map[DSCP_TID_MA + void ath11k_hal_tx_cmd_desc_setup(struct ath11k_base *ab, void *cmd, + struct hal_tx_info *ti) + { +- struct hal_tcl_data_cmd *tcl_cmd = cmd; ++ struct hal_tcl_data_cmd tcl_cmd, *tcl_desc = cmd; + +- tcl_cmd->buf_addr_info.info0 = ++ tcl_cmd.buf_addr_info.info0 = + FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, ti->paddr); +- tcl_cmd->buf_addr_info.info1 = ++ tcl_cmd.buf_addr_info.info1 = + FIELD_PREP(BUFFER_ADDR_INFO1_ADDR, + ((uint64_t)ti->paddr >> HAL_ADDR_MSB_REG_SHIFT)); +- tcl_cmd->buf_addr_info.info1 |= +- FIELD_PREP(BUFFER_ADDR_INFO1_RET_BUF_MGR, ti->rbm_id) | ++ tcl_cmd.buf_addr_info.info1 |= ++ FIELD_PREP(BUFFER_ADDR_INFO1_RET_BUF_MGR, ti->buf_id) | + FIELD_PREP(BUFFER_ADDR_INFO1_SW_COOKIE, ti->desc_id); + +- tcl_cmd->info0 = ++ tcl_cmd.info0 = + 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 + FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_CMD_NUM, + ti->meta_data_flags); + +- tcl_cmd->info1 = ti->flags0 | ++ tcl_cmd.info1 = ti->flags0 | + FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_DATA_LEN, ti->data_len) | + 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_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, + ti->dscp_tid_tbl_idx) | + FIELD_PREP(HAL_TCL_DATA_CMD_INFO3_SEARCH_INDEX, + ti->bss_ast_idx) | + FIELD_PREP(HAL_TCL_DATA_CMD_INFO3_CACHE_SET_NUM, + ti->bss_ast_hash); +- tcl_cmd->info4 = 0; ++ tcl_cmd.info4 = 0; + + if (ti->enable_mesh) +- ab->hw_params.hw_ops->tx_mesh_enable(ab, tcl_cmd); ++ ab->hw_params.hw_ops->tx_mesh_enable(ab, &tcl_cmd); ++ ++ *tcl_desc = tcl_cmd; + } + + 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 + ctrl_reg_val); + } + +-void ath11k_hal_tx_init_data_ring(struct ath11k_base *ab, struct hal_srng *srng) ++void ath11k_hal_tx_init_data_ring(struct ath11k_base *ab, struct hal_srng *srng, ++ enum hal_ring_type type) ++ + { + struct hal_srng_params params; + struct hal_tlv_hdr *tlv; +@@ -145,7 +149,7 @@ void ath11k_hal_tx_init_data_ring(struct + + memset(¶ms, 0, sizeof(params)); + +- entry_size = ath11k_hal_srng_get_entrysize(ab, HAL_TCL_DATA); ++ entry_size = ath11k_hal_srng_get_entrysize(ab, type); + ath11k_hal_srng_get_params(ab, srng, ¶ms); + desc = (u8 *)params.ring_base_vaddr; + diff --git a/package/kernel/mac80211/patches/ath11k_nss/911-335-0001-ath11k-optimize-tx-completions.patch b/package/kernel/mac80211/patches/ath11k_nss/911-335-0001-ath11k-optimize-tx-completions.patch new file mode 100644 index 00000000000000..3cc13d1ba98543 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/911-335-0001-ath11k-optimize-tx-completions.patch @@ -0,0 +1,269 @@ +From 34b4e65248e7e1605448b06a006347354990bfba Mon Sep 17 00:00:00 2001 +From: Venkateswara Naralasetty +Date: Thu, 11 Nov 2021 10:30:35 +0530 +Subject: [PATCH] ath11k: optimize tx completions + +Process the required fields from tx completion status +in case of stats disabled. + +Signed-off-by: Venkateswara Naralasetty +--- + drivers/net/wireless/ath/ath11k/dp_tx.c | 114 ++++++++++++++++---------------- + 1 file changed, 58 insertions(+), 56 deletions(-) + +--- 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: + spin_unlock_bh(&ab->base_lock); + } + ++static inline void ath11k_dp_tx_status_parse(struct ath11k_base *ab, ++ struct hal_wbm_release_ring *desc, ++ struct hal_tx_status *ts) ++{ ++ ts->buf_rel_source = ++ FIELD_GET(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE, desc->info0); ++ if (unlikely(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_FW && ++ ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) ++ return; ++ ++ if (unlikely(ts->buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW)) ++ return; ++ ++ ts->status = FIELD_GET(HAL_WBM_RELEASE_INFO0_TQM_RELEASE_REASON, ++ desc->info0); ++ ts->ppdu_id = FIELD_GET(HAL_WBM_RELEASE_INFO1_TQM_STATUS_NUMBER, ++ desc->info1); ++ ts->try_cnt = FIELD_GET(HAL_WBM_RELEASE_INFO1_TRANSMIT_COUNT, ++ desc->info1); ++ ts->ack_rssi = FIELD_GET(HAL_WBM_RELEASE_INFO2_ACK_FRAME_RSSI, ++ desc->info2); ++ if (desc->info2 & HAL_WBM_RELEASE_INFO2_FIRST_MSDU) ++ ts->flags |= HAL_TX_STATUS_FLAGS_FIRST_MSDU; ++ ts->peer_id = FIELD_GET(HAL_WBM_RELEASE_INFO3_PEER_ID, desc->info3); ++ ts->tid = FIELD_GET(HAL_WBM_RELEASE_INFO3_TID, desc->info3); ++ if (desc->rate_stats.info0 & HAL_TX_RATE_STATS_INFO0_VALID) ++ ts->rate_stats = desc->rate_stats.info0; ++ else ++ ts->rate_stats = 0; ++} ++ + static void ath11k_dp_tx_complete_msdu(struct ath11k *ar, + struct sk_buff *msdu, +- struct hal_tx_status *ts) ++ struct hal_wbm_release_ring *tx_status, ++ enum hal_wbm_rel_src_module buf_rel_source) + { + 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 + 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; + +- if (WARN_ON_ONCE(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) { ++ if (unlikely(WARN_ON_ONCE(buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM))) { + /* Must not happen */ + return; + } +@@ -660,11 +696,14 @@ static void ath11k_dp_tx_complete_msdu(s + + dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); + +- /* Free skb here if stats is disabled */ ++ rel_status = FIELD_GET(HAL_WBM_RELEASE_INFO0_TQM_RELEASE_REASON, ++ tx_status->info0); ++ ++ /* Free skb here if stats is disabled */ + if (ab->stats_disable && !(flags & ATH11K_SKB_TX_STATUS)) { + if (msdu->destructor) { + msdu->wifi_acked_valid = 1; +- msdu->wifi_acked = ts->status == HAL_WBM_TQM_REL_REASON_FRAME_ACKED; ++ msdu->wifi_acked = rel_status == HAL_WBM_TQM_REL_REASON_FRAME_ACKED; + } + 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 + return; + } + ++ ath11k_dp_tx_status_parse(ab, tx_status, &ts); ++ + 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)); + + /* skip tx rate update from ieee80211_status*/ + info->status.rates[0].idx = -1; + +- if (ts->status == HAL_WBM_TQM_REL_REASON_FRAME_ACKED && ++ if (ts.status == HAL_WBM_TQM_REL_REASON_FRAME_ACKED && + !(info->flags & IEEE80211_TX_CTL_NO_ACK)) { + info->flags |= IEEE80211_TX_STAT_ACK; + info->status.ack_signal = ATH11K_DEFAULT_NOISE_FLOOR + +- ts->ack_rssi; ++ ts.ack_rssi; + info->status.flags |= IEEE80211_TX_STATUS_ACK_SIGNAL_VALID; + } + +- if (ts->status == HAL_WBM_TQM_REL_REASON_CMD_REMOVE_TX && ++ if (ts.status == HAL_WBM_TQM_REL_REASON_CMD_REMOVE_TX && + (info->flags & IEEE80211_TX_CTL_NO_ACK)) + info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; + + if (unlikely(ath11k_debugfs_is_extd_tx_stats_enabled(ar)) || + ab->hw_params.single_pdev_only) { +- if (ts->flags & HAL_TX_STATUS_FLAGS_FIRST_MSDU) { ++ if (ts.flags & HAL_TX_STATUS_FLAGS_FIRST_MSDU) { + if (ar->last_ppdu_id == 0) { +- ar->last_ppdu_id = ts->ppdu_id; +- } else if (ar->last_ppdu_id == ts->ppdu_id || ++ ar->last_ppdu_id = ts.ppdu_id; ++ } else if (ar->last_ppdu_id == ts.ppdu_id || + ar->cached_ppdu_id == ar->last_ppdu_id) { + ar->cached_ppdu_id = ar->last_ppdu_id; + ar->cached_stats.is_ampdu = true; +- ath11k_dp_tx_update_txcompl(ar, ts); ++ ath11k_dp_tx_update_txcompl(ar, &ts); + memset(&ar->cached_stats, 0, + sizeof(struct ath11k_per_peer_tx_stats)); + } else { + ar->cached_stats.is_ampdu = false; +- ath11k_dp_tx_update_txcompl(ar, ts); ++ ath11k_dp_tx_update_txcompl(ar, &ts); + memset(&ar->cached_stats, 0, + sizeof(struct ath11k_per_peer_tx_stats)); + } +- ar->last_ppdu_id = ts->ppdu_id; ++ ar->last_ppdu_id = ts.ppdu_id; + } + +- ath11k_dp_tx_cache_peer_stats(ar, msdu, ts); ++ ath11k_dp_tx_cache_peer_stats(ar, msdu, &ts); + } + + spin_lock_bh(&ab->base_lock); +- peer = ath11k_peer_find_by_id(ab, ts->peer_id); ++ peer = ath11k_peer_find_by_id(ab, ts.peer_id); + if (unlikely(!peer || !peer->sta)) { + ath11k_dbg(ab, ATH11K_DBG_DATA, + "dp_tx: failed to find the peer with peer_id %d\n", +- ts->peer_id); ++ ts.peer_id); + 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 + ieee80211_tx_status_ext(ar->hw, &status); + } + +-static inline void ath11k_dp_tx_status_parse(struct ath11k_base *ab, +- struct hal_wbm_release_ring *desc, +- struct hal_tx_status *ts) +-{ +- ts->buf_rel_source = +- FIELD_GET(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE, desc->info0); +- if (unlikely(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_FW && +- ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) +- return; +- +- if (unlikely(ts->buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW)) +- return; +- +- ts->status = FIELD_GET(HAL_WBM_RELEASE_INFO0_TQM_RELEASE_REASON, +- desc->info0); +- ts->ppdu_id = FIELD_GET(HAL_WBM_RELEASE_INFO1_TQM_STATUS_NUMBER, +- desc->info1); +- ts->try_cnt = FIELD_GET(HAL_WBM_RELEASE_INFO1_TRANSMIT_COUNT, +- desc->info1); +- ts->ack_rssi = FIELD_GET(HAL_WBM_RELEASE_INFO2_ACK_FRAME_RSSI, +- desc->info2); +- if (desc->info2 & HAL_WBM_RELEASE_INFO2_FIRST_MSDU) +- ts->flags |= HAL_TX_STATUS_FLAGS_FIRST_MSDU; +- ts->peer_id = FIELD_GET(HAL_WBM_RELEASE_INFO3_PEER_ID, desc->info3); +- ts->tid = FIELD_GET(HAL_WBM_RELEASE_INFO3_TID, desc->info3); +- if (desc->rate_stats.info0 & HAL_TX_RATE_STATS_INFO0_VALID) +- ts->rate_stats = desc->rate_stats.info0; +- else +- ts->rate_stats = 0; +-} +- + 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 + 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; +- struct hal_tx_status ts = { 0 }; + struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id]; + int valid_entries; ++ enum hal_wbm_rel_src_module buf_rel_source; + 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 + + while (count--) { + tx_status = &tx_ring->tx_status[i++]; +- ath11k_dp_tx_status_parse(ab, tx_status, &ts); + + desc_id = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, + tx_status->buf_addr_info.info1); + mac_id = FIELD_GET(DP_TX_DESC_ID_MAC_ID, desc_id); + msdu_id = FIELD_GET(DP_TX_DESC_ID_MSDU_ID, desc_id); + +- if (unlikely(ts.buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW)) { ++ buf_rel_source = FIELD_GET(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE, ++ tx_status->info0); ++ ++ if (unlikely(buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW)) { + 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 + if (atomic_dec_and_test(&ar->dp.num_tx_pending)) + wake_up(&ar->dp.tx_empty_waitq); + +- ath11k_dp_tx_complete_msdu(ar, msdu, &ts); ++ ath11k_dp_tx_complete_msdu(ar, msdu, tx_status, buf_rel_source); + } + } + 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/ath11k_nss/911-335-0002-ath11k-use-DECLARE_BITMAP-for-idr-operations.patch new file mode 100644 index 00000000000000..7b87edb0ae6baa --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/911-335-0002-ath11k-use-DECLARE_BITMAP-for-idr-operations.patch @@ -0,0 +1,288 @@ +From 6cd8cb301e431860e71b8d3453846a9ed0efea81 Mon Sep 17 00:00:00 2001 +From: Venkateswara Naralasetty +Date: Thu, 11 Nov 2021 10:38:26 +0530 +Subject: [PATCH] ath11k: use DECLARE_BITMAP for idr operations + +Use DECLARE_BITMAP for declaring bit map for idrs. And use APIs +find_first_zero_bit, set_bit and clear bit instead of idr_alloc +and idr_destroy. + +This helps in improving idle CPU and throughput. + +Signed-off-by: Venkateswara Naralasetty +--- + drivers/net/wireless/ath/ath11k/dp.c | 34 +++++++++++++----- + drivers/net/wireless/ath/ath11k/dp.h | 10 +++++- + drivers/net/wireless/ath/ath11k/dp_tx.c | 61 ++++++++++++++++++--------------- + 3 files changed, 69 insertions(+), 36 deletions(-) + +--- 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 + 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); ++ kfree(dp->tx_ring[i].idr_pool); ++ dp->tx_ring[i].idr_pool = NULL; + } + 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 + { + struct ath11k_dp *dp = &ab->dp; + struct hal_srng *srng; +- int i, ret; ++ int i, ret, j; + 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 + 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); ++ ++ dp->tx_ring[i].idr_pool = kcalloc(DP_TX_IDR_SIZE, ++ sizeof(struct idr_entry), GFP_KERNEL); ++ if (!dp->tx_ring[i].idr_pool) { ++ ath11k_warn(ab, "failed to allocate memory for idr pool ring(%d)\n", i); ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ /* Reset id to default */ ++ for (j = 0; j < DP_TX_IDR_SIZE; j++) ++ dp->tx_ring[i].idr_pool[j].id = -1; + } + + 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 + ath11k_dp_update_vdev_search(arvif); + } + +-static int ath11k_dp_tx_pending_cleanup(int buf_id, void *skb, void *ctx) ++static int ath11k_dp_tx_pending_cleanup(struct ath11k_base *ab, void *skb) + { +- struct ath11k_base *ab = ctx; + 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 * + { + 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); + ++ for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { ++ struct dp_tx_ring *tx_ring = &dp->tx_ring[i]; ++ spin_lock_bh(&tx_ring->tx_idr_lock); ++ for(j = 0; j < DP_TX_IDR_SIZE; j++) { ++ ++ if (test_and_clear_bit(j, tx_ring->idrs)) ++ ath11k_dp_tx_pending_cleanup(ab, tx_ring->idr_pool[j].buf); ++ } ++ ++ spin_unlock_bh(&tx_ring->tx_idr_lock); ++ } ++ + ath11k_dp_srng_common_cleanup(ab); + + ath11k_dp_reo_cmd_list_cleanup(ab); + + for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { +- 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); +- 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 @@ + #define ATH11K_DP_H + + #include "hal_rx.h" ++#include "hw.h" + + #define MAX_RXDMA_PER_PDEV 2 + +@@ -78,6 +79,13 @@ struct dp_rxdma_ring { + + #define ATH11K_TX_COMPL_NEXT(x) (((x) + 1) % DP_TX_COMP_RING_SIZE) + ++struct idr_entry { ++ int id; ++ void *buf; ++}; ++ ++#define DP_TX_IDR_SIZE ATH11K_DP_TX_COMP_RING_SIZE ++ + struct dp_tx_ring { + u8 tcl_data_ring_id; + struct dp_srng tcl_data_ring; +@@ -88,6 +96,8 @@ struct dp_tx_ring { + struct hal_wbm_release_ring *tx_status; + int tx_status_head; + int tx_status_tail; ++ DECLARE_BITMAP(idrs, DP_TX_IDR_SIZE); ++ struct idr_entry *idr_pool; + }; + + enum dp_mon_status_buf_state { +@@ -207,7 +217,6 @@ struct ath11k_pdev_dp { + #define DP_TCL_DATA_RING_SIZE 512 + #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_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 + 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; ++ u32 idr; + + if (unlikely(!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && + !ieee80211_is_data(hdr->frame_control))) +@@ -152,24 +153,28 @@ tcl_ring_sel: + 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, +- DP_TX_IDR_SIZE - 1, GFP_ATOMIC); +- spin_unlock_bh(&tx_ring->tx_idr_lock); +- +- if (unlikely(ret < 0)) { ++ idr = find_first_zero_bit(tx_ring->idrs, DP_TX_IDR_SIZE); ++ if (unlikely(idr >= DP_TX_IDR_SIZE)) { + if (ring_map == (BIT(max_tx_ring) - 1) || + !ab->hw_params.tcl_ring_retry) { ++ spin_unlock_bh(&tx_ring->tx_idr_lock); + ab->soc_stats.tx_err.idr_na[tcl_ring_id]++; + return -ENOSPC; + } + + /* Check if the next ring is available */ ++ spin_unlock_bh(&tx_ring->tx_idr_lock); + ring_selector++; + goto tcl_ring_sel; + } + ++ 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); ++ + ti.desc_id = FIELD_PREP(DP_TX_DESC_ID_MAC_ID, ar->pdev_idx) | +- FIELD_PREP(DP_TX_DESC_ID_MSDU_ID, ret) | ++ FIELD_PREP(DP_TX_DESC_ID_MSDU_ID, idr) | + 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: + fail_remove_idr: + if (ti.pkt_offset) + skb_pull(skb, ti.pkt_offset); +- spin_lock_bh(&tx_ring->tx_idr_lock); +- idr_remove(&tx_ring->txbuf_idr, +- FIELD_GET(DP_TX_DESC_ID_MSDU_ID, ti.desc_id)); +- spin_unlock_bh(&tx_ring->tx_idr_lock); ++ ++ tx_ring->idr_pool[idr].id = -1; ++ clear_bit(idr, tx_ring->idrs); + + if (tcl_ring_retry) + goto tcl_ring_sel; +@@ -353,16 +357,19 @@ fail_remove_idr: + } + + static void ath11k_dp_tx_free_txbuf(struct ath11k_base *ab, u8 mac_id, +- int msdu_id, ++ u32 msdu_id, + struct dp_tx_ring *tx_ring) + { + struct ath11k *ar; +- struct sk_buff *msdu; ++ struct sk_buff *msdu = NULL; + struct ath11k_skb_cb *skb_cb; + +- spin_lock(&tx_ring->tx_idr_lock); +- msdu = idr_remove(&tx_ring->txbuf_idr, msdu_id); +- spin_unlock(&tx_ring->tx_idr_lock); ++ if (msdu_id < DP_TX_IDR_SIZE && ++ tx_ring->idr_pool[msdu_id].id == msdu_id) { ++ msdu = tx_ring->idr_pool[msdu_id].buf; ++ tx_ring->idr_pool[msdu_id].id = -1; ++ clear_bit(msdu_id, tx_ring->idrs); ++ } + + 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 + struct ath11k_dp_htt_wbm_tx_status *ts) + { + struct ieee80211_tx_status status = { 0 }; +- struct sk_buff *msdu; ++ struct sk_buff *msdu = NULL; + struct ieee80211_tx_info *info; + struct ath11k_skb_cb *skb_cb; + struct ath11k *ar; + struct ath11k_peer *peer; ++ u32 msdu_id = ts->msdu_id; + u8 flags = 0; + +- spin_lock(&tx_ring->tx_idr_lock); +- msdu = idr_remove(&tx_ring->txbuf_idr, ts->msdu_id); +- spin_unlock(&tx_ring->tx_idr_lock); ++ if (msdu_id < DP_TX_IDR_SIZE && ++ tx_ring->idr_pool[msdu_id].id == msdu_id) { ++ msdu = tx_ring->idr_pool[msdu_id].buf; ++ tx_ring->idr_pool[msdu_id].id = -1; ++ clear_bit(msdu_id, tx_ring->idrs); ++ } + + 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 + } + + while (count--) { ++ msdu=NULL; + 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 + continue; + } + +- spin_lock(&tx_ring->tx_idr_lock); +- msdu = idr_remove(&tx_ring->txbuf_idr, msdu_id); ++ if (msdu_id < DP_TX_IDR_SIZE && ++ tx_ring->idr_pool[msdu_id].id == msdu_id) { ++ msdu = tx_ring->idr_pool[msdu_id].buf; ++ tx_ring->idr_pool[msdu_id].id = -1; ++ clear_bit(msdu_id, tx_ring->idrs); ++ } ++ + if (unlikely(!msdu)) { + ath11k_warn(ab, "tx completion for unknown msdu_id %d\n", + msdu_id); +- spin_unlock(&tx_ring->tx_idr_lock); + continue; + } + +- spin_unlock(&tx_ring->tx_idr_lock); +- + ar = ab->pdevs[mac_id].ar; + + if (atomic_dec_and_test(&ar->dp.num_tx_pending)) 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 new file mode 100644 index 00000000000000..c61c206c417de7 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/911-335-0006-ath11k-add-simple-tx-handler-for-AP-mode.patch @@ -0,0 +1,185 @@ +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 new file mode 100644 index 00000000000000..ffae27277d7316 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/911-335-ath11k-fix-ar-ops-crash.patch @@ -0,0 +1,71 @@ +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/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch b/package/kernel/mac80211/patches/ath11k_nss/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch new file mode 100644 index 00000000000000..90f335efbca6fb --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch @@ -0,0 +1,384 @@ +From 17d1895bad45ec2ef4c8c430ac0fbaff2ff1cf39 Mon Sep 17 00:00:00 2001 +From: Manish Dharanenthiran +Date: Tue, 18 Apr 2023 15:01:42 +0530 +Subject: [PATCH 2/3] CHROMIUM: ath11k: Add retry mechanism for update_rx_queue + reo cmd + +While reo_cmd ring is full, peer delete update rx queue +will be failed as there is no space to send the command +in ring. During the failure scenario, host will do +dma_unmap and free the allocated address but the HW +still have that particular vaddr. So, on next alloc +cycle kernel will allocated the freed addr but HW will +still have the address. This will result in memory +corruption as the host will try to access/write that +memory which is already in-use. + +To avoid this corruption, added new retry mechanism +for HAL_REO_CMD_UPDATE_RX_QUEUE by adding new list to +dp struct and protecting with new lock for access. +This avoids the host free in failure case and will +be freed only when HW freed that particular vaddr. + +Also, updated below changes +1) reo_flush command for sending 1K desc in one +command instead of sending 11 command for single +TID. + +2) Set FWD_MPDU and valid bit flag so that reo +flush will happen soon instead of waiting to +flush the queue. + +Signed-off-by: Manish Dharanenthiran +Signed-off-by: Tamizh Chelvam Raja +--- + drivers/net/wireless/ath/ath11k/core.h | 3 + + drivers/net/wireless/ath/ath11k/debugfs.c | 12 ++ + drivers/net/wireless/ath/ath11k/dp.c | 2 + + drivers/net/wireless/ath/ath11k/dp.h | 15 ++ + drivers/net/wireless/ath/ath11k/dp_rx.c | 167 +++++++++++++++++----- + 5 files changed, 161 insertions(+), 38 deletions(-) + +--- 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 { + 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]; ++ u32 hal_reo_cmd_drain; ++ u32 reo_cmd_cache_error; ++ u32 reo_cmd_update_rx_queue_error; + struct ath11k_soc_dp_tx_err_stats tx_err; + struct ath11k_dp_ring_bp_stats bp_stats; + }; +--- 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 + "\nNSS Transmit Failures: %d\n", + atomic_read(&soc_stats->tx_err.nss_tx_fail)); + ++ len += scnprintf(buf + len, size - len, ++ "\nHAL_REO_CMD_DRAIN Counter: %u\n", ++ soc_stats->hal_reo_cmd_drain); ++ ++ len += scnprintf(buf + len, size - len, ++ "\nREO_CMD_CACHE_FLUSH Failure: %u\n", ++ soc_stats->reo_cmd_cache_error); ++ ++ len += scnprintf(buf + len, size - len, ++ "\nREO_CMD_UPDATE_RX_QUEUE Failure: %u\n", ++ soc_stats->reo_cmd_update_rx_queue_error); ++ + len += ath11k_debugfs_dump_soc_ring_bp_stats(ab, buf + len, size - len); + + 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 * + + INIT_LIST_HEAD(&dp->reo_cmd_list); + INIT_LIST_HEAD(&dp->reo_cmd_cache_flush_list); ++ INIT_LIST_HEAD(&dp->reo_cmd_update_rx_queue_list); + INIT_LIST_HEAD(&dp->dp_full_mon_mpdu_list); + spin_lock_init(&dp->reo_cmd_lock); ++ spin_lock_init(&dp->reo_cmd_update_queue_lock); + + dp->reo_cmd_cache_flush_count = 0; + +--- a/drivers/net/wireless/ath/ath11k/dp.h ++++ b/drivers/net/wireless/ath/ath11k/dp.h +@@ -24,6 +24,7 @@ struct dp_rx_tid { + u32 *vaddr; + dma_addr_t paddr; + u32 size; ++ u32 pending_desc_size; + u32 ba_win_sz; + bool active; + +@@ -51,6 +52,14 @@ struct dp_reo_cache_flush_elem { + unsigned long ts; + }; + ++struct dp_reo_update_rx_queue_elem { ++ struct list_head list; ++ struct dp_rx_tid data; ++ int peer_id; ++ u8 tid; ++ bool reo_cmd_update_rx_queue_resend_flag; ++}; ++ + struct dp_reo_cmd { + struct list_head list; + struct dp_rx_tid data; +@@ -296,6 +305,12 @@ struct ath11k_dp { + * - reo_cmd_cache_flush_count + */ + spinlock_t reo_cmd_lock; ++ struct list_head reo_cmd_update_rx_queue_list; ++ /** ++ * protects access to below field, ++ * - reo_cmd_update_rx_queue_list ++ */ ++ spinlock_t reo_cmd_update_queue_lock; + struct ath11k_hp_update_timer reo_cmd_timer; + struct ath11k_hp_update_timer tx_ring_timer[DP_TCL_NUM_RING_MAX]; + }; +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -21,6 +21,9 @@ + + #define ATH11K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ) + ++static void ath11k_dp_rx_tid_del_func(struct ath11k_dp *dp, void *ctx, ++ enum hal_reo_cmd_status status); ++ + 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( + return 0; + } + ++static int ath11k_peer_rx_tid_delete_handler(struct ath11k_base *ab, ++ struct dp_rx_tid *rx_tid, u8 tid) ++{ ++ struct ath11k_hal_reo_cmd cmd = {0}; ++ struct ath11k_dp *dp = &ab->dp; ++ ++ lockdep_assert_held(&dp->reo_cmd_update_queue_lock); ++ ++ rx_tid->active = false; ++ cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; ++ cmd.addr_lo = lower_32_bits(rx_tid->paddr); ++ cmd.addr_hi = upper_32_bits(rx_tid->paddr); ++ cmd.upd0 |= HAL_REO_CMD_UPD0_VLD; ++ ++ return ath11k_dp_tx_send_reo_cmd(ab, rx_tid, ++ HAL_REO_CMD_UPDATE_RX_QUEUE, ++ &cmd, ++ ath11k_dp_rx_tid_del_func); ++} ++ + void ath11k_dp_reo_cmd_list_cleanup(struct ath11k_base *ab) + { + struct ath11k_dp *dp = &ab->dp; + struct dp_reo_cmd *cmd, *tmp; + struct dp_reo_cache_flush_elem *cmd_cache, *tmp_cache; ++ struct dp_reo_update_rx_queue_elem *cmd_queue, *tmp_queue; + struct dp_rx_tid *rx_tid; + ++ spin_lock_bh(&dp->reo_cmd_update_queue_lock); ++ list_for_each_entry_safe(cmd_queue, tmp_queue, ++ &dp->reo_cmd_update_rx_queue_list, ++ list) { ++ list_del(&cmd_queue->list); ++ rx_tid = &cmd_queue->data; ++ if (rx_tid->vaddr) { ++ dma_unmap_single(ab->dev, rx_tid->paddr, ++ rx_tid->size, DMA_BIDIRECTIONAL); ++ kfree(rx_tid->vaddr); ++ rx_tid->vaddr = NULL; ++ } ++ kfree(cmd_queue); ++ } ++ spin_unlock_bh(&dp->reo_cmd_update_queue_lock); ++ + 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 + } + } + +-static void ath11k_dp_reo_cache_flush(struct ath11k_base *ab, ++static int ath11k_dp_reo_cache_flush(struct ath11k_base *ab, + struct dp_rx_tid *rx_tid) + { + struct ath11k_hal_reo_cmd cmd = {0}; + unsigned long tot_desc_sz, desc_sz; + int ret; + +- tot_desc_sz = rx_tid->size; ++ if (rx_tid->pending_desc_size) ++ tot_desc_sz = rx_tid->pending_desc_size; ++ else ++ tot_desc_sz = rx_tid->size; ++ + 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 + HAL_REO_CMD_FLUSH_CACHE, &cmd, + NULL); + if (ret) +- ath11k_warn(ab, +- "failed to send HAL_REO_CMD_FLUSH_CACHE, tid %d (%d)\n", +- rx_tid->tid, ret); ++ rx_tid->pending_desc_size = tot_desc_sz + desc_sz; ++ ++ /* If this fails with ring full condition, then ++ * no need to retry below as it is expected to ++ * fail within short time ++ */ ++ if (ret == -ENOBUFS) ++ goto exit; + } + ++ rx_tid->pending_desc_size = desc_sz; + 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 + ret = ath11k_dp_tx_send_reo_cmd(ab, rx_tid, + HAL_REO_CMD_FLUSH_CACHE, + &cmd, ath11k_dp_reo_cmd_free); +- if (ret) { +- ath11k_err(ab, "failed to send HAL_REO_CMD_FLUSH_CACHE cmd, tid %d (%d)\n", +- rx_tid->tid, ret); +- dma_unmap_single(ab->dev, rx_tid->paddr, rx_tid->size, +- DMA_BIDIRECTIONAL); +- kfree(rx_tid->vaddr); +- rx_tid->vaddr = NULL; +- } ++ ++exit: ++ return ret; + } + + static void ath11k_dp_rx_tid_del_func(struct ath11k_dp *dp, void *ctx, + enum hal_reo_cmd_status status) + { + struct ath11k_base *ab = dp->ab; +- struct dp_rx_tid *rx_tid = ctx; ++ struct dp_rx_tid *rx_tid = ctx, *update_rx_tid; + struct dp_reo_cache_flush_elem *elem, *tmp; ++ struct dp_reo_update_rx_queue_elem *qelem, *qtmp; + + if (status == HAL_REO_CMD_DRAIN) { ++ ab->soc_stats.hal_reo_cmd_drain++; + 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 + return; + } + ++ /* Check if there is any pending rx_queue, if yes then update it */ ++ spin_lock_bh(&dp->reo_cmd_update_queue_lock); ++ list_for_each_entry_safe(qelem, qtmp, &dp->reo_cmd_update_rx_queue_list, ++ list) { ++ if (qelem->reo_cmd_update_rx_queue_resend_flag && ++ qelem->data.active) { ++ update_rx_tid = &qelem->data; ++ ++ if (ath11k_peer_rx_tid_delete_handler(ab, update_rx_tid, qelem->tid)) { ++ update_rx_tid->active = true; ++ break; ++ } ++ update_rx_tid->vaddr = NULL; ++ update_rx_tid->paddr = 0; ++ update_rx_tid->size = 0; ++ update_rx_tid->pending_desc_size = 0; ++ ++ list_del(&qelem->list); ++ kfree(qelem); ++ } ++ } ++ spin_unlock_bh(&dp->reo_cmd_update_queue_lock); ++ + elem = kzalloc(sizeof(*elem), GFP_ATOMIC); + if (!elem) + goto free_desc; +@@ -832,13 +902,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))) { ++ spin_unlock_bh(&dp->reo_cmd_lock); ++ if (ath11k_dp_reo_cache_flush(ab, &elem->data)) { ++ ab->soc_stats.reo_cmd_cache_error++; ++ /* In failure case, just update the timestamp ++ * for flush cache elem and continue ++ */ ++ spin_lock_bh(&dp->reo_cmd_lock); ++ elem->ts = jiffies; ++ break; ++ } ++ spin_lock_bh(&dp->reo_cmd_lock); + list_del(&elem->list); + dp->reo_cmd_cache_flush_count--; +- spin_unlock_bh(&dp->reo_cmd_lock); +- +- ath11k_dp_reo_cache_flush(ab, &elem->data); + kfree(elem); +- spin_lock_bh(&dp->reo_cmd_lock); + } + } + spin_unlock_bh(&dp->reo_cmd_lock); +@@ -854,34 +931,48 @@ free_desc: + void ath11k_peer_rx_tid_delete(struct ath11k *ar, + struct ath11k_peer *peer, u8 tid) + { +- struct ath11k_hal_reo_cmd cmd = {0}; + struct dp_rx_tid *rx_tid = &peer->rx_tid[tid]; +- int ret; ++ struct dp_reo_update_rx_queue_elem *elem, *tmp; ++ struct ath11k_base *ab = ar->ab; ++ struct ath11k_dp *dp = &ab->dp; + + if (!rx_tid->active) + return; + +- rx_tid->active = false; ++ elem = kzalloc(sizeof(*elem), GFP_ATOMIC); ++ if (!elem) { ++ ath11k_warn(ar->ab, "failed to alloc reo_update_rx_queue_elem, rx tid %d\n", ++ rx_tid->tid); ++ return; ++ } ++ elem->reo_cmd_update_rx_queue_resend_flag = false; ++ elem->peer_id = peer->peer_id; ++ elem->tid = tid; ++ memcpy(&elem->data, rx_tid, sizeof(*rx_tid)); ++ spin_lock_bh(&dp->reo_cmd_update_queue_lock); ++ list_add_tail(&elem->list, &dp->reo_cmd_update_rx_queue_list); + +- cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; +- cmd.addr_lo = lower_32_bits(rx_tid->paddr); +- cmd.addr_hi = upper_32_bits(rx_tid->paddr); +- cmd.upd0 |= HAL_REO_CMD_UPD0_VLD; +- ret = ath11k_dp_tx_send_reo_cmd(ar->ab, rx_tid, +- HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, +- ath11k_dp_rx_tid_del_func); +- if (ret) { +- if (ret != -ESHUTDOWN) +- ath11k_err(ar->ab, "failed to send HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n", +- tid, ret); +- dma_unmap_single(ar->ab->dev, rx_tid->paddr, rx_tid->size, +- DMA_BIDIRECTIONAL); +- kfree(rx_tid->vaddr); ++ list_for_each_entry_safe(elem, tmp, &dp->reo_cmd_update_rx_queue_list, ++ list) { ++ rx_tid = &elem->data; ++ ++ if (ath11k_peer_rx_tid_delete_handler(ab, rx_tid, elem->tid)) { ++ rx_tid->active = true; ++ ab->soc_stats.reo_cmd_update_rx_queue_error++; ++ elem->reo_cmd_update_rx_queue_resend_flag = true; ++ break; ++ } + rx_tid->vaddr = NULL; ++ rx_tid->paddr = 0; ++ rx_tid->size = 0; ++ rx_tid->pending_desc_size = 0; ++ ++ list_del(&elem->list); ++ kfree(elem); + } ++ spin_unlock_bh(&dp->reo_cmd_update_queue_lock); + +- rx_tid->paddr = 0; +- rx_tid->size = 0; ++ return; + } + + static int ath11k_dp_rx_link_desc_return(struct ath11k_base *ab, 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/ath11k_nss/913-341-ath11k-fix-support-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch new file mode 100644 index 00000000000000..a1b885c8b50e5a --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/913-341-ath11k-fix-support-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch @@ -0,0 +1,52 @@ +From 516c1d2faf4480c355ec5000d6d4ad4fc287d0e8 Mon Sep 17 00:00:00 2001 +From: Aditya Kumar Singh +Date: Thu, 30 Dec 2021 17:44:40 +0530 +Subject: [PATCH] ath11k: fix support for ext vdev in NSS for AP_VLAN vif + during recovery + +When driver is recovering, it tears down nss connection and sets +ab->nss.enabled as false. However, this is not set back to its original +state post recovery and hence when ext vdev is added again, warning +trace appears since ath11k_mac_op_add_interface() does not handle +NL80211_IFTYPE_AP_VLAN vif with nss disabled and throws a WARN_ON(1). + +[ 2777.201255] ------------[ cut here ]------------ +[ 2777.209669] WARNING: CPU: 0 PID: 77 at drivers/net/wireless/ath/ath11k/mac.c:7298 ath11k_mac_op_add_interface+0x314/0xa98 [ath11k] +[----- Trimmed -----] +[ 2777.499054] CPU: 0 PID: 77 Comm: kworker/0:2 Tainted: G W 5.4.89 #0 +[ 2777.515132] Hardware name: Generic DT based system +[ 2777.522658] Workqueue: events_freezable ieee80211_restart_work [mac80211] +[ 2777.527305] [<8030f3a4>] (unwind_backtrace) from [<8030b700>] (show_stack+0x10/0x14) +[ 2777.534153] [<8030b700>] (show_stack) from [<808da410>] (dump_stack+0x88/0xa8) +[ 2777.541964] [<808da410>] (dump_stack) from [<8031bf20>] (__warn+0xa4/0xd0) +[ 2777.548994] [<8031bf20>] (__warn) from [<8031bfbc>] (warn_slowpath_fmt+0x70/0x9c) +[ 2777.555972] [<8031bfbc>] (warn_slowpath_fmt) from [] (ath11k_mac_op_add_interface+0x314/0xa98 [ath11k]) +[ 2777.563664] [] (ath11k_mac_op_add_interface [ath11k]) from [<7fd34720>] (drv_add_interface+0x68/0x78 [mac80211]) +[ 2777.573928] [<7fd34720>] (drv_add_interface [mac80211]) from [<7fd679bc>] (ieee80211_reconfig+0x240/0xce8 [mac80211]) +[ 2777.584843] [<7fd679bc>] (ieee80211_reconfig [mac80211]) from [<7fd311ec>] (ieee80211_restart_work+0xd4/0xf4 [mac80211]) +[ 2777.595401] [<7fd311ec>] (ieee80211_restart_work [mac80211]) from [<80331968>] (process_one_work+0x1dc/0x310) +[ 2777.606205] [<80331968>] (process_one_work) from [<80332cf8>] (worker_thread+0x2bc/0x40c) +[ 2777.616009] [<80332cf8>] (worker_thread) from [<803373ac>] (kthread+0x164/0x180) +[ 2777.624167] [<803373ac>] (kthread) from [<803010e0>] (ret_from_fork+0x14/0x34) + +Added logic to enable nss as per MODULE_PARM_DESC parameter. + +Signed-off-by: Aditya Kumar Singh +--- + drivers/net/wireless/ath/ath11k/core.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- 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 + + clear_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags); + ++ /* We have disabled NSS Offload support in the starting. ++ * Re-enabling it if it was originally enabled in the MODULE_PARM_DESC. ++ */ ++ ab->nss.enabled = nss_offload; ++ + ret = ath11k_core_qmi_firmware_ready(ab); + if (ret) + goto err_hal_srng_deinit; 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/ath11k_nss/913-353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch new file mode 100644 index 00000000000000..e8ac589acfc8ec --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/913-353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch @@ -0,0 +1,74 @@ +From 0ab84604de1db0f589f7303507f38148ba8f3f04 Mon Sep 17 00:00:00 2001 +From: Nagarajan Maran +Date: Tue, 28 Jun 2022 11:31:50 +0530 +Subject: [PATCH] ath11k: Ignore frags from uninitialized peer in dp + +In certain scenario, fragmented packet is received for self peer, +for which rx_tid and rx_frags are not initialized in datapath. +While handling this fragment, crash is observed as the +rx_frag list is uninitialised and when we walk in +ath11k_dp_rx_h_sort_frags, skb null leads to exception. + +To address this, before processing received fragments we +check dp_setup_done flag is set to ensure that peer +has completed its dp peer setup for fragment queue, +else ignore processing the fragments. + +Also, __fls would have an undefined behavior if the argument +is passed as "0". Hence, added changes to handle the same. + +Below is the call trace of the crash: + + CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.4.164 #0 + Hardware name: Qualcomm Technologies, Inc. IPQ6018/AP-CP01-C1 (DT) + pstate: a0400005 (NzCv daif +PAN -UAO) + pc : ath11k_dp_process_rx_err+0x550/0x1084 [ath11k] + lr : ath11k_dp_process_rx_err+0x4e0/0x1084 [ath11k] + + Call trace: + ath11k_dp_process_rx_err+0x550/0x1084 [ath11k] + ath11k_dp_service_srng+0x70/0x370 [ath11k] + 0xffffffc009693a04 + __napi_poll+0x30/0xa4 + net_rx_action+0x118/0x270 + __do_softirq+0x10c/0x244 + irq_exit+0x64/0xb4 + __handle_domain_irq+0x88/0xac + gic_handle_irq+0x74/0xbc + el1_irq+0xf0/0x1c0 + arch_cpu_idle+0x10/0x18 + do_idle+0x104/0x248 + cpu_startup_entry+0x20/0x64 + rest_init+0xd0/0xdc + arch_call_rest_init+0xc/0x14 + start_kernel+0x480/0x4b8 + Code: f9400281 f94066a2 91405021 b94a0023 (f9406401) + +Signed-off-by: Harshitha Prem +Signed-off-by: Nagarajan Maran +--- + drivers/net/wireless/ath/ath11k/dp.c | 3 ++- + drivers/net/wireless/ath/ath11k/dp_rx.c | 11 ++++++++++- + drivers/net/wireless/ath/ath11k/peer.h | 2 ++ + 3 files changed, 14 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/dp.c ++++ b/drivers/net/wireless/ath/ath11k/dp.c +@@ -38,6 +38,7 @@ void ath11k_dp_peer_cleanup(struct ath11 + ath11k_peer_rx_tid_cleanup(ar, peer); + peer->dp_setup_done = false; + crypto_free_shash(peer->tfm_mmic); ++ peer->dp_setup_done = false; + spin_unlock_bh(&ab->base_lock); + } + +--- a/drivers/net/wireless/ath/ath11k/peer.h ++++ b/drivers/net/wireless/ath/ath11k/peer.h +@@ -93,6 +93,7 @@ struct ath11k_peer { + u16 sec_type; + u16 sec_type_grp; + bool is_authorized; ++ /* Peer's datapath set flag */ + bool dp_setup_done; + struct ppdu_user_delayba ppdu_stats_delayba; + bool delayba_flag; diff --git a/package/kernel/mac80211/patches/ath11k_nss/913-356-ath11k-invalid-desc-sanity-check.patch b/package/kernel/mac80211/patches/ath11k_nss/913-356-ath11k-invalid-desc-sanity-check.patch new file mode 100644 index 00000000000000..4e7e37957b1f31 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/913-356-ath11k-invalid-desc-sanity-check.patch @@ -0,0 +1,74 @@ +From c7e37aebbe19056eb7b61299e75c863263acf2b9 Mon Sep 17 00:00:00 2001 +From: Nagarajan Maran +Date: Tue, 9 Aug 2022 13:22:43 +0530 +Subject: [PATCH] Fix SKB corruption in REO destination ring + +In the traffic cases, randomly, invalid RX descriptor +from REO destination ring is received. This +invalid descriptor causes wrong SKB to be fetched +which in turn causes SKB memory corruption issue. + +Introduced Sanity check to validate the descriptor, +before processing the SKB. + +During the failure scenario, invalid RX descriptor +filled with values "0" is received which in-turn +corrupts the SKB stored in the ldr lookup +with buffer id "0". Changed the start id for +idr allocation to "1" and the buffer id "0" is +reserved for error validation. + + +Crash Signature : + +Unable to handle kernel paging request at virtual address 3f004900 +During the crash, +PC points to "b15_dma_inv_range+0x30/0x50" +LR points to "dma_cache_maint_page+0x8c/0x128". +The Backtrace obtained is as follows: +[<8031716c>] (b15_dma_inv_range) from [<80313a4c>] (dma_cache_maint_page+0x8c/0x128) +[<80313a4c>] (dma_cache_maint_page) from [<80313b90>] (__dma_page_dev_to_cpu+0x28/0xcc) +[<80313b90>] (__dma_page_dev_to_cpu) from [<7fb5dd68>] (ath11k_dp_process_rx+0x1e8/0x4a4 [ath11k]) +[<7fb5dd68>] (ath11k_dp_process_rx [ath11k]) from [<7fb53c20>] (ath11k_dp_service_srng+0xb0/0x2ac [ath11k]) +[<7fb53c20>] (ath11k_dp_service_srng [ath11k]) from [<7f67bba4>] (ath11k_pci_ext_grp_napi_poll+0x1c/0x78 [ath11k_pci]) +[<7f67bba4>] (ath11k_pci_ext_grp_napi_poll [ath11k_pci]) from [<807d5cf4>] (__napi_poll+0x28/0xb8) +[<807d5cf4>] (__napi_poll) from [<807d5f28>] (net_rx_action+0xf0/0x280) +[<807d5f28>] (net_rx_action) from [<80302148>] (__do_softirq+0xd0/0x280) +[<80302148>] (__do_softirq) from [<80320408>] (irq_exit+0x74/0xd4) +[<80320408>] (irq_exit) from [<803638a4>] (__handle_domain_irq+0x90/0xb4) +[<803638a4>] (__handle_domain_irq) from [<805bedec>] (gic_handle_irq+0x58/0x90) +[<805bedec>] (gic_handle_irq) from [<80301a78>] (__irq_svc+0x58/0x8c) + +Signed-off-by: Nagarajan Maran +--- + drivers/net/wireless/ath/ath11k/dp_rx.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -3228,6 +3228,16 @@ try_again: + while (likely(desc = + (struct hal_reo_dest_ring *)ath11k_hal_srng_dst_get_next_entry(ab, + srng))) { ++ ++ push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON, ++ desc->info0); ++ if (unlikely(push_reason == ++ HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED)) { ++ ath11k_warn(ab,"Received invalid desc\n"); ++ ab->soc_stats.hal_reo_error[dp->reo_dst_ring[ring_id].ring_id]++; ++ continue; ++ } ++ + 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: + + num_buffs_reaped[mac_id]++; + +- push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON, +- desc->info0); + if (unlikely(push_reason != + HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION)) { + dev_kfree_skb_any(msdu); 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/ath11k_nss/913-374-ath11k-Check-skb_headroom-before-using-skb_push.patch new file mode 100644 index 00000000000000..1bbbdd6c7446da --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/913-374-ath11k-Check-skb_headroom-before-using-skb_push.patch @@ -0,0 +1,209 @@ +From efecc6e8355d02aeac7bf1a43397551440a8d0d8 Mon Sep 17 00:00:00 2001 +From: Tamizh Chelvam Raja +Date: Thu, 30 Mar 2023 22:12:56 +0530 +Subject: [PATCH] ath11k: Check skb_headroom before using skb_push + +Below kernel panic may occur if there is no +skb_headroom available for performing skb_push. + +<4>[67506.565072] CPU: 1 PID: 1741 Comm: ap-wireless-opt Not tainted 5.4.89+ #0 +<4>[67506.578860] Hardware name: Generic DT based system +<4>[67506.585728] PC is at fortify_panic+0x10/0x18 +<4>[67506.590406] LR is at fortify_panic+0x10/0x18 + +(fortify_panic) from [<7f2cd3cc>] (ath11k_dp_rx_crypto_icv_len+0x1e0/0x161c [ath11k]) +(ath11k_dp_rx_crypto_icv_len [ath11k]) from [<7f2cdbac>] (ath11k_dp_rx_crypto_icv_len+0x9c0/0x161c [ath11k]) +(ath11k_dp_rx_crypto_icv_len [ath11k]) from [<7f2ce0e8>] (ath11k_dp_rx_crypto_icv_len+0xefc/0x161c [ath11k]) +(ath11k_dp_rx_crypto_icv_len [ath11k]) from [<7f2cedb0>] (ath11k_dp_process_rx+0x4ec/0x544 [ath11k]) +(ath11k_dp_process_rx [ath11k]) from [<7f2c417c>] (ath11k_dp_service_srng+0xdc/0x2a0 [ath11k]) +(ath11k_dp_service_srng [ath11k]) from [<7f0d78c8>] (ath11k_pci_ext_grp_napi_poll+0x20/0x50 [ath11k_pci]) +(ath11k_pci_ext_grp_napi_poll [ath11k_pci]) from [<806a6a74>] (__napi_poll+0x28/0xb8) +(__napi_poll) from [<806a6c9c>] (net_rx_action+0xec/0x280) +(net_rx_action) from [<8010226c>] (__do_softirq+0xc4/0x248) +(__do_softirq) from [<8011f230>] (irq_exit+0x6c/0xcc) +(irq_exit) from [<80162a08>] (__handle_domain_irq+0x8c/0xb0) +(__handle_domain_irq) from [<803f0188>] (gic_handle_irq+0x54/0x8c) +(gic_handle_irq) from [<80101a8c>] (__irq_svc+0x6c/0xa8) + +Fix this by checking skb_headroom and expand the +headroom if required size is not available. + +Signed-off-by: Tamizh Chelvam Raja +--- + drivers/net/wireless/ath/ath11k/dp_rx.c | 70 +++++++++++++++++++++++++ + 1 file changed, 70 insertions(+) + +--- 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 + size_t hdr_len, crypto_len; + struct ieee80211_hdr *hdr; + u16 fc, qos_ctl = 0; ++ int expand_by; + u8 *crypto_hdr; + + if (!(status->flag & RX_FLAG_IV_STRIPPED)) { + crypto_len = ath11k_dp_rx_crypto_param_len(ar, enctype); ++ if (skb_headroom(msdu) < crypto_len) { ++ expand_by = crypto_len - skb_headroom(msdu); ++ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) ++ return; ++ } + crypto_hdr = skb_push(msdu, crypto_len); + ath11k_dp_rx_desc_get_crypto_header(ab, rx_desc, crypto_hdr, enctype); + } + + fc = ath11k_dp_rxdesc_get_mpdu_frame_ctrl(ab, rx_desc); + hdr_len = ieee80211_hdrlen(fc); ++ 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; ++ } + 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 + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + u16 qos_ctl = 0; ++ int expand_by = 0; + u8 *qos, *crypto_hdr; + bool add_qos_ctrl = false; + +@@ -2359,26 +2371,46 @@ static void ath11k_dp_rx_h_undecap_nwifi + } + + if (!(status->flag & RX_FLAG_IV_STRIPPED)) { ++ 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; ++ } + if (first_hdr) { +- memcpy(skb_push(msdu, +- ath11k_dp_rx_crypto_param_len(ar, enctype)), +- (void *)hdr + hdr_len, +- ath11k_dp_rx_crypto_param_len(ar, enctype)); ++ memcpy(skb_push(msdu, crypto_param_len), ++ (void *)hdr + hdr_len, crypto_param_len); + } else { +- crypto_hdr = skb_push(msdu, ath11k_dp_rx_crypto_param_len(ar, enctype)); ++ crypto_hdr = skb_push(msdu, crypto_param_len); + ath11k_dp_rx_desc_get_crypto_header(ar->ab, + rxcb->rx_desc, crypto_hdr, enctype); + } + } + + if (!rxcb->is_first_msdu || add_qos_ctrl) { ++ if (skb_headroom(msdu) < IEEE80211_QOS_CTL_LEN) { ++ expand_by = IEEE80211_QOS_CTL_LEN - skb_headroom(msdu); ++ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) ++ return; ++ } + memcpy(skb_push(msdu, + IEEE80211_QOS_CTL_LEN), &qos_ctl, + IEEE80211_QOS_CTL_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), decap_hdr, hdr_len); + return; + } + ++ 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); + + /* original 802.11 header has a different DA and in +@@ -2487,6 +2519,7 @@ static void ath11k_dp_rx_h_undecap_eth(s + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + void *rfc1042; ++ int expand_by; + 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 + ether_addr_copy(sa, eth->h_source); + rfc.snap_type = eth->h_proto; + skb_pull(msdu, sizeof(struct ethhdr)); ++ if (skb_headroom(msdu) < sizeof(struct ath11k_dp_rfc1042_hdr)) { ++ expand_by = sizeof(struct ath11k_dp_rfc1042_hdr) - skb_headroom(msdu); ++ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) ++ return; ++ } + 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 + skb_pull(msdu, sizeof(struct ethhdr)); + + /* push rfc1042/llc/snap */ ++ if (skb_headroom(msdu) < sizeof(struct ath11k_dp_rfc1042_hdr)) { ++ expand_by = sizeof(struct ath11k_dp_rfc1042_hdr) - skb_headroom(msdu); ++ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) ++ return; ++ } + 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 + 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); + + exit: +@@ -2954,10 +3007,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; ++ int expand_by; + + if (status->encoding == RX_ENC_HE && + !(status->flag & RX_FLAG_RADIOTAP_HE) && + !(status->flag & RX_FLAG_SKIP_MONITOR)) { ++ if (skb_headroom(msdu) < sizeof(known)) { ++ expand_by = sizeof(known) - skb_headroom(msdu); ++ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) ++ goto exit; ++ } + 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 + !(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/ath11k_nss/913-686-mac80211-fix-RCU-stall-in-mesh-fast-xmit-path.patch b/package/kernel/mac80211/patches/ath11k_nss/913-686-mac80211-fix-RCU-stall-in-mesh-fast-xmit-path.patch new file mode 100644 index 00000000000000..6614d8d496b354 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/913-686-mac80211-fix-RCU-stall-in-mesh-fast-xmit-path.patch @@ -0,0 +1,120 @@ +From 331198f889cef552e4644abf1f2ebfcaa2cc41e9 Mon Sep 17 00:00:00 2001 +From: P Praneesh +Date: Wed, 23 Nov 2022 18:50:47 +0530 +Subject: [PATCH] mac80211: fix RCU stall in mesh fast xmit path + +In mesh fast xmit, mesh_fill_cached_hdr tries to acquire spinlock +which is already acquired by the same core for updating mesh path +table. Fix it by using atomic variable instead of using spinlock. + +[100466.097939] rcu: INFO: rcu_preempt self-detected stall on CPU +[100466.097962] rcu: 0-....: (8381 ticks this GP) idle=e86/0/0x3 softirq=2648463/2648463 fqs=4184 +[100466.102651] (t=8403 jiffies g=5521597 q=620) +[100466.111586] Task dump for CPU 0: +[100466.115839] swapper/0 R running task 0 0 0 0x0000000a +[100466.119228] Call trace: +[100466.126348] dump_backtrace+0x0/0x15c +[100466.128949] show_stack+0x14/0x1c +[100466.132508] sched_show_task+0x104/0x134 +[100466.135893] dump_cpu_task+0x40/0x274 +[100466.139974] rcu_dump_cpu_stacks+0x7c/0xd4 +[100466.143620] rcu_sched_clock_irq+0x350/0x824 +[100466.147699] update_process_times+0x2c/0x50 +[100466.152213] tick_sched_handle.isra.4+0x3c/0x44 +[100466.156553] tick_sched_timer+0x48/0x88 +[100466.161153] __hrtimer_run_queues+0xa0/0x140 +[100466.165059] hrtimer_interrupt+0xe4/0x214 +[100466.169315] arch_timer_handler_virt+0x28/0x3c +[100466.173308] handle_percpu_devid_irq+0x84/0x12c +[100466.177733] generic_handle_irq+0x18/0x2c +[100466.182593] __handle_domain_irq+0x84/0xac +[100466.186500] gic_handle_irq+0x74/0xbc +[100466.190579] el1_irq+0xf0/0x1c0 +[100466.194398] queued_spin_lock_slowpath+0x98/0x2c0 +[100466.197800] mesh_fill_cached_hdr+0x15c/0x2d0 [mac80211] +[100466.202397] __ieee80211_subif_start_xmit+0xf4/0xf3c [mac80211] +[100466.207865] ieee80211_subif_start_xmit+0x274/0x2ac [mac80211] +[100466.213933] dev_hard_start_xmit+0x1b0/0x230 +[100466.219574] sch_direct_xmit+0xbc/0x300 +[100466.224086] __dev_queue_xmit+0x5b0/0x8cc +[100466.228079] dev_queue_xmit+0x10/0x18 +[100466.231990] sfe_ipv4_recv_udp+0x1014/0x1050 [qca_nss_sfe] +[100466.235722] sfe_ipv4_recv+0x394/0x5a4 [qca_nss_sfe] +[100466.241190] sfe_recv+0xf0/0x47c [qca_nss_sfe] +[100466.246397] __netif_receive_skb_core+0x1ac/0xa3c +[100466.250736] __netif_receive_skb_list_core+0x84/0x1ec +[100466.255598] netif_receive_skb_list_internal+0x250/0x29c +[100466.260720] gro_normal_list+0x24/0x40 +[100466.266186] gro_normal_one+0x3c/0x48 +[100466.269832] napi_gro_receive+0xc0/0x104 +[100466.273655] edma_rx_napi_poll+0x820/0xdb4 [qca_nss_dp] +[100466.277734] __napi_poll+0x30/0xa4 +[100466.283113] net_rx_action+0x118/0x270 +[100466.286325] __do_softirq+0x10c/0x244 +[100466.290145] irq_exit+0x64/0xb4 +[100466.293965] __handle_domain_irq+0x88/0xac +[100466.297350] gic_handle_irq+0x74/0xbc +[100466.301256] el1_irq+0xf0/0x1c0 +[100466.305076] arch_cpu_idle+0x10/0x18 +[100466.308461] do_idle+0x104/0x248 +[100466.312019] cpu_startup_entry+0x20/0x64 +[100466.315320] rest_init+0xd0/0xdc +[100466.319311] arch_call_rest_init+0xc/0x14 +[100466.322610] start_kernel+0x480/0x4b8 + +Signed-off-by: P Praneesh +--- + net/mac80211/cfg.c | 2 +- + net/mac80211/mesh.h | 4 ++-- + net/mac80211/mesh_hwmp.c | 4 ++-- + net/mac80211/mesh_pathtbl.c | 9 ++++----- + 4 files changed, 9 insertions(+), 10 deletions(-) + +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -2347,7 +2347,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; +- pinfo->path_change_count = mpath->path_change_count; ++ pinfo->path_change_count = atomic_read(&mpath->path_change_count); + } + + static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev, +--- a/net/mac80211/mesh.h ++++ b/net/mac80211/mesh.h +@@ -126,7 +126,7 @@ struct mesh_path { + unsigned long fast_tx_check; + bool is_root; + bool is_gate; +- u32 path_change_count; ++ atomic_t path_change_count; + }; + + #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 + 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 + 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/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 new file mode 100644 index 00000000000000..8e60a5f6b255f7 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/913-726-mac80211-fix-crash-when-accessing-null-pointer.patch @@ -0,0 +1,87 @@ +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/ath11k_nss/913-830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch b/package/kernel/mac80211/patches/ath11k_nss/913-830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch new file mode 100644 index 00000000000000..28b4fdf6468337 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/913-830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch @@ -0,0 +1,87 @@ +From 5b4a0de1356558f58df9c6a1f46c7c0ce2fadb03 Mon Sep 17 00:00:00 2001 +From: Yuvasree Sivasankaran +Date: Mon, 28 Aug 2023 14:48:41 +0530 +Subject: [PATCH] ath11k: Avoiding memset of ppdu-info for next skb + +While parsing mon status from skb, ppdu_info got memset with zero during +next skb fetch from queue or mon ring in case a single PPDU is more than +RX_BUFFER_SIZE. Because of this nss value got override for respective +ppdu and leads to warn_on in mac80211.Removed memset from next skb fetch +and added flag to track discontinued skb in case of fetch from skb. + +WARN_ON Reason: + +Rate marked as an HE rate but data is invalid: MCS: 0, NSS: 0 + +Below the call trace observed: + + Call trace: + ieee80211_rx_list+0x1d4/0xcc4 [mac80211] + ieee80211_rx_napi+0x58/0xcc [mac80211] + ath11k_dp_rx_deliver_msdu+0x358/0x3e4 [ath11k] + ath11k_dp_rx_mon_deliver.isra.27+0x470/0x4cc [ath11k] + ath11k_dp_rx_mon_dest_process+0x1cc/0x2bc [ath11k] + ath11k_dp_rx_process_mon_status+0x5ec/0xf90 [ath11k] + ath11k_dp_rx_process_mon_rings+0x40c/0x44c [ath11k] + ath11k_dp_service_srng+0x114/0x2c0 [ath11k] + ath11k_ahb_ext_grp_napi_poll+0x30/0xa0 [ath11k_ahb] + __napi_poll+0x30/0xa4 + net_rx_action+0x118/0x270 + __do_softirq+0x10c/0x244 + irq_exit+0x64/0xb4 + __handle_domain_irq+0x88/0xac + gic_handle_irq+0x74/0xbc + el1_irq+0xf0/0x1c0 + arch_cpu_idle+0x10/0x18 + do_idle+0x104/0x248 + cpu_startup_entry+0x20/0x64 + rest_init+0xd0/0xdc + arch_call_rest_init+0xc/0x14 + start_kernel+0x46c/0x4a4 + --[ end trace e754e9088a240857 ]--- + +Signed-off-by: Yuvasree Sivasankaran +--- + drivers/net/wireless/ath/ath11k/dp_rx.c | 6 ++++-- + drivers/net/wireless/ath/ath11k/hal_rx.h | 1 + + 2 files changed, 5 insertions(+), 2 deletions(-) + +--- 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 + if (!num_buffs_reaped) + goto exit; + +- memset(ppdu_info, 0, sizeof(*ppdu_info)); ++ if (!ppdu_info->ppdu_continuation) ++ memset(ppdu_info, 0, sizeof(*ppdu_info)); ++ + 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 + if (log_type != ATH11K_PKTLOG_TYPE_INVALID) + trace_ath11k_htt_rxdesc(ar, skb->data, log_type, rx_buf_sz); + +- memset(ppdu_info, 0, sizeof(*ppdu_info)); + 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) { + dev_kfree_skb_any(skb); ++ ppdu_info->ppdu_continuation = true; + continue; + } + +--- 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]; + 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]; + }; + From 6e204eccfb14cd44825c1abff64b0344a01c5e8b Mon Sep 17 00:00:00 2001 From: Qosmio Date: Tue, 16 Jan 2024 19:12:13 -0500 Subject: [PATCH 089/225] ath11k_nss: remove unused symbol --- package/kernel/mac80211/ath.mk | 1 - 1 file changed, 1 deletion(-) diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk index c10c326d6a3084..6b8fac507d2894 100644 --- a/package/kernel/mac80211/ath.mk +++ b/package/kernel/mac80211/ath.mk @@ -342,7 +342,6 @@ define KernelPackage/ath11k/config 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 choice From 929a86bae2318d467c075b3b16f0694e3d7a29cf Mon Sep 17 00:00:00 2001 From: Qosmio Date: Tue, 16 Jan 2024 20:34:26 -0500 Subject: [PATCH 090/225] ath11k_nss: fix up patches --- .../ath11k_nss/199-001-mac80211-add-nss-support.patch | 8 -------- .../ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch | 8 +------- .../300-mac80211-nss-mesh-offload-support.patch | 2 +- 3 files changed, 2 insertions(+), 16 deletions(-) diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch b/package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch index f25def295537ca..a06ef7652df538 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch @@ -451,11 +451,3 @@ Signed-off-by: Sriram R QCOM_AOSS_QMP= QCOM_COMMAND_DB= QCOM_CPR= -@@ -174,6 +175,7 @@ ATH11K_DEBUGFS= - ATH11K_TRACING= - ATH11K_SPECTRAL= - ATH11K_THERMAL= -+ATH11K_MEM_PROFILE_512M= - ATH12K= - ATH12K_DEBUG= - ATH12K_TRACING= diff --git a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch index eaf14c700dd4c8..060beac8b7c568 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch @@ -138,7 +138,7 @@ Signed-off-by: Ramya Gnanasekar #endif --- a/local-symbols +++ b/local-symbols -@@ -171,12 +171,13 @@ ATH11K= +@@ -171,6 +171,8 @@ ATH11K= ATH11K_AHB= ATH11K_PCI= ATH11K_NSS_SUPPORT= @@ -147,12 +147,6 @@ Signed-off-by: Ramya Gnanasekar ATH11K_DEBUG= ATH11K_DEBUGFS= ATH11K_TRACING= - ATH11K_SPECTRAL= - ATH11K_THERMAL= --ATH11K_MEM_PROFILE_512M= - ATH12K= - ATH12K_DEBUG= - ATH12K_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 { diff --git a/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch b/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch index 7233913ee6f0f7..d3e6b9850b620f 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch @@ -187,7 +187,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran + u32 metric; + unsigned long exp_time; + u8 hop_count; -+ u16 flags; /* See &enum ieee80211_mesh_path_flags */ ++ u8 flags; /* See &enum ieee80211_mesh_path_flags */ + u8 mesh_gate; + u8 block_mesh_fwd; + u8 metadata_type; From 7f13c3857ef552e058b2f0e1a71cd37a3640f9fb Mon Sep 17 00:00:00 2001 From: Qosmio Date: Wed, 17 Jan 2024 01:51:20 -0500 Subject: [PATCH 091/225] ath11k_nss: revert m3, fix coredump when rebooting M3 SSR dump logic makes the router coredump. Just putting dummy case to skip warning. [12394.072384] Hardware name: Dynalink DL-WRX36 (DT) [12394.079758] Call trace: [12394.084354] dump_backtrace.part.0+0xbc/0xd0 [12394.086614] show_stack+0x18/0x30 [12394.091127] dump_stack_lvl+0x6c/0x88 [12394.094339] dump_stack+0x18/0x34 [12394.097985] bad_page+0xe0/0x110 [12394.101282] __free_pages_ok+0x33c/0x360 [12394.104582] __free_pages+0xbc/0xe0 [12394.108487] dma_direct_free+0xd0/0x140 [12394.111701] dma_free_attrs+0x90/0xb0 [12394.115519] ath11k_qmi_fwreset_from_cold_boot+0x9e0/0xa10 [ath11k] [12394.119343] ath11k_qmi_deinit_service+0x64/0x21d0 [ath11k] [12394.125419] ath11k_core_deinit+0xa4/0xc0 [ath11k] [12394.130974] 0xffffffc000fb3600 [12394.135831] platform_shutdown+0x24/0x40 [12394.138871] device_shutdown+0x14c/0x240 [12394.143037] kernel_restart+0x40/0xb0 [12394.146944] __do_sys_reboot+0xcc/0x200 [12394.150502] __arm64_sys_reboot+0x24/0x30 [12394.154148] invoke_syscall.constprop.0+0x5c/0x110 [12394.158317] do_el0_svc+0x58/0x170 [12394.163001] el0_svc+0x18/0x60 [12394.166386] el0t_64_sync_handler+0x114/0x120 [12394.169426] el0t_64_sync+0x174/0x178 --- ...207-ath11k-Enable-256_512MB-profiles.patch | 5 +- .../906-ath11k-m3-ssr-dump-collection.patch | 739 +----------------- .../911-244-ath11k-dp-tx-perf.patch | 26 +- 3 files changed, 16 insertions(+), 754 deletions(-) diff --git a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch index 060beac8b7c568..4d7af8641311dc 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch @@ -276,17 +276,16 @@ Signed-off-by: Ramya Gnanasekar .hal_params = &ath11k_hw_hal_params_ipq8074, .supports_dynamic_smps_6ghz = false, .alloc_cacheable_memory = true, -@@ -127,7 +131,9 @@ static struct ath11k_hw_params ath11k_hw +@@ -127,6 +131,9 @@ 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, - .name = "ipq6018 hw1.0", @@ -177,7 +183,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = true, .coldboot_cal_ftm = true, diff --git a/package/kernel/mac80211/patches/ath11k_nss/906-ath11k-m3-ssr-dump-collection.patch b/package/kernel/mac80211/patches/ath11k_nss/906-ath11k-m3-ssr-dump-collection.patch index d65d230fa10984..47b29fd19e19bb 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/906-ath11k-m3-ssr-dump-collection.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/906-ath11k-m3-ssr-dump-collection.patch @@ -1,749 +1,12 @@ --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - - #define SLEEP_CLOCK_SELECT_INTERNAL_BIT 0x02 - #define HOST_CSTATE_BIT 0x04 -@@ -292,6 +293,24 @@ static const struct qmi_elem_info qmi_wl - .ei_array = qmi_response_type_v01_ei, - }, - { -+ .data_type = QMI_OPT_FLAG, -+ .elem_len = 1, -+ .elem_size = sizeof(u8), -+ .array_type = NO_ARRAY, -+ .tlv_type = 0x20, -+ .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, -+ m3_dump_upload_req_enable_valid), -+ }, -+ { -+ .data_type = QMI_UNSIGNED_1_BYTE, -+ .elem_len = 1, -+ .elem_size = sizeof(u8), -+ .array_type = NO_ARRAY, -+ .tlv_type = 0x20, -+ .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, -+ m3_dump_upload_req_enable), -+ }, -+ { - .data_type = QMI_EOTI, - .array_type = NO_ARRAY, - .tlv_type = QMI_COMMON_TLV_TYPE, -@@ -517,6 +536,24 @@ static const struct qmi_elem_info qmi_wl - cal_done_enable), - }, - { -+ .data_type = QMI_OPT_FLAG, -+ .elem_len = 1, -+ .elem_size = sizeof(u8), -+ .array_type = NO_ARRAY, -+ .tlv_type = 0x20, -+ .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, -+ m3_dump_upload_req_enable_valid), -+ }, -+ { -+ .data_type = QMI_UNSIGNED_1_BYTE, -+ .elem_len = 1, -+ .elem_size = sizeof(u8), -+ .array_type = NO_ARRAY, -+ .tlv_type = 0x20, -+ .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, -+ m3_dump_upload_req_enable), -+ }, -+ { - .data_type = QMI_EOTI, - .array_type = NO_ARRAY, - .tlv_type = QMI_COMMON_TLV_TYPE, -@@ -1705,6 +1742,87 @@ static const struct qmi_elem_info qmi_wl - }, - }; - -+static struct qmi_elem_info qmi_wlanfw_m3_dump_upload_req_ind_msg_v01_ei[] = { -+ { -+ .data_type = QMI_UNSIGNED_4_BYTE, -+ .elem_len = 1, -+ .elem_size = sizeof(u32), -+ .array_type = NO_ARRAY, -+ .tlv_type = 0x01, -+ .offset = offsetof(struct qmi_wlanfw_m3_dump_upload_req_ind_msg_v01, -+ pdev_id), -+ }, -+ { -+ .data_type = QMI_UNSIGNED_8_BYTE, -+ .elem_len = 1, -+ .elem_size = sizeof(u64), -+ .array_type = NO_ARRAY, -+ .tlv_type = 0x02, -+ .offset = offsetof(struct qmi_wlanfw_m3_dump_upload_req_ind_msg_v01, -+ addr), -+ }, -+ { -+ .data_type = QMI_UNSIGNED_8_BYTE, -+ .elem_len = 1, -+ .elem_size = sizeof(u64), -+ .array_type = NO_ARRAY, -+ .tlv_type = 0x03, -+ .offset = offsetof(struct qmi_wlanfw_m3_dump_upload_req_ind_msg_v01, -+ size), -+ }, -+ { -+ .data_type = QMI_EOTI, -+ .array_type = NO_ARRAY, -+ .tlv_type = QMI_COMMON_TLV_TYPE, -+ }, -+}; -+ -+static struct qmi_elem_info qmi_wlanfw_m3_dump_upload_done_req_msg_v01_ei[] = { -+ { -+ .data_type = QMI_UNSIGNED_4_BYTE, -+ .elem_len = 1, -+ .elem_size = sizeof(u32), -+ .array_type = NO_ARRAY, -+ .tlv_type = 0x01, -+ .offset = offsetof(struct -+ qmi_wlanfw_m3_dump_upload_done_req_msg_v01, -+ pdev_id), -+ }, -+ { -+ .data_type = QMI_UNSIGNED_4_BYTE, -+ .elem_len = 1, -+ .elem_size = sizeof(u32), -+ .array_type = NO_ARRAY, -+ .tlv_type = 0x02, -+ .offset = offsetof(struct -+ qmi_wlanfw_m3_dump_upload_done_req_msg_v01, -+ status), -+ }, -+ { -+ .data_type = QMI_EOTI, -+ .array_type = NO_ARRAY, -+ .tlv_type = QMI_COMMON_TLV_TYPE, -+ }, -+}; -+ -+static struct qmi_elem_info qmi_wlanfw_m3_dump_upload_done_resp_msg_v01_ei[] = { -+ { -+ .data_type = QMI_STRUCT, -+ .elem_len = 1, -+ .elem_size = sizeof(struct qmi_response_type_v01), -+ .array_type = NO_ARRAY, -+ .tlv_type = 0x02, -+ .offset = offsetof(struct qmi_wlanfw_m3_dump_upload_done_resp_msg_v01, -+ resp), -+ .ei_array = qmi_response_type_v01_ei, -+ }, -+ { -+ .data_type = QMI_EOTI, -+ .array_type = NO_ARRAY, -+ .tlv_type = QMI_COMMON_TLV_TYPE, -+ }, -+}; -+ - static int ath11k_qmi_host_cap_send(struct ath11k_base *ab) - { - struct qmi_wlanfw_host_cap_req_msg_v01 req; -@@ -1817,6 +1935,8 @@ static int ath11k_qmi_fw_ind_register_se - - req->pin_connect_result_enable_valid = 0; - req->pin_connect_result_enable = 0; -+ req->m3_dump_upload_req_enable_valid = 1; -+ req->m3_dump_upload_req_enable = 1; - - /* WCN6750 doesn't request for DDR memory via QMI, - * instead it uses a fixed 12MB reserved memory -@@ -2101,6 +2221,33 @@ static int ath11k_qmi_assign_target_mem_ +@@ -2101,6 +2101,9 @@ static int ath11k_qmi_assign_target_mem_ ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type; idx++; break; + case M3_DUMP_REGION_TYPE: -+ if (!ab->qmi.target_mem[i].size) { -+ ath11k_info(ab, "qmi mem size is zero\n"); -+ return -EINVAL; -+ } -+ if (ab->qmi.target_mem[i].size > ATH11K_QMI_M3_DUMP_SIZE) { -+ ath11k_warn(ab, "qmi mem size is low to dump m3 ssr\n"); -+ return -EINVAL; -+ } -+ -+ ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size; -+ ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type; -+ if (hremote_node) { -+ ab->qmi.target_mem[idx].paddr = -+ res.start + ATH11K_HOST_DDR_M3_OFFSET; -+ } else if (ath11k_host_ddr_addr) { -+ ab->qmi.target_mem[idx].paddr = -+ ath11k_host_ddr_addr + ATH11K_HOST_DDR_M3_OFFSET; -+ } else { -+ ab->qmi.target_mem[idx].paddr = ab->hw_params.m3_addr; -+ } -+ -+ ab->qmi.target_mem[idx].vaddr = -+ ioremap(ab->qmi.target_mem[idx].paddr, -+ ab->qmi.target_mem[i].size); + idx++; + break; default: ath11k_warn(ab, "qmi ignore invalid mem req type %d\n", ab->qmi.target_mem[i].type); -@@ -2893,6 +3040,114 @@ static int ath11k_qmi_process_coldboot_c - return 0; - } - -+static int ath11k_qmi_m3_dump_upload_done_ind_send(struct ath11k_base *ab, -+ u32 pdev_id, int status) -+{ -+ struct qmi_wlanfw_m3_dump_upload_done_req_msg_v01 *req; -+ struct qmi_wlanfw_m3_dump_upload_done_resp_msg_v01 *resp; -+ struct qmi_txn txn = {}; -+ int ret = 0; -+ -+ req = kzalloc(sizeof(*req), GFP_KERNEL); -+ if (!req) -+ return -ENOMEM; -+ -+ resp = kzalloc(sizeof(*resp), GFP_KERNEL); -+ if (!resp) { -+ kfree(req); -+ return -ENOMEM; -+ } -+ -+ req->pdev_id = pdev_id; -+ req->status = status; -+ -+ ret = qmi_txn_init(&ab->qmi.handle, &txn, -+ qmi_wlanfw_m3_dump_upload_done_resp_msg_v01_ei, resp); -+ if (ret < 0) -+ goto out; -+ -+ ret = -+ qmi_send_request(&ab->qmi.handle, NULL, &txn, -+ QMI_WLFW_M3_DUMP_UPLOAD_DONE_REQ_V01, -+ QMI_WLANFW_M3_DUMP_UPLOAD_DONE_REQ_MSG_V01_MAX_MSG_LEN, -+ qmi_wlanfw_m3_dump_upload_done_req_msg_v01_ei, req); -+ if (ret < 0) { -+ qmi_txn_cancel(&txn); -+ ath11k_warn(ab, "Failed to send M3 dump upload done request, err %d\n", -+ ret); -+ goto out; -+ } -+ -+ ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS)); -+ if (ret < 0) -+ goto out; -+ -+ if (resp->resp.result != QMI_RESULT_SUCCESS_V01) { -+ ath11k_warn(ab, "qmi M3 upload done req failed, result: %d, err: %d\n", -+ resp->resp.result, resp->resp.error); -+ ret = -EINVAL; -+ goto out; -+ } -+ ath11k_info(ab, "qmi m3 dump uploaded\n"); -+ -+out: -+ kfree(req); -+ kfree(resp); -+ return ret; -+} -+ -+static void ath11k_qmi_event_m3_dump_upload_req(struct ath11k_qmi *qmi, -+ void *data) -+{ -+ struct ath11k_base *ab = qmi->ab; -+ struct target_mem_chunk *target_mem = ab->qmi.target_mem; -+ struct ath11k_qmi_m3_dump_upload_req_data *event_data = data; -+ struct ath11k_qmi_m3_dump_data *m3_dump_data; -+ void *dump; -+ int i, ret = 0; -+ -+ m3_dump_data = kzalloc(sizeof(*m3_dump_data), GFP_KERNEL); -+ if (!m3_dump_data) -+ return; -+ -+ dump = vzalloc(event_data->size); -+ if (!dump) { -+ kfree(m3_dump_data); -+ return; -+ } -+ -+ for (i = 0; i < ab->qmi.mem_seg_count; i++) { -+ if (target_mem[i].paddr == event_data->addr && -+ event_data->size <= target_mem[i].size) -+ break; -+ } -+ -+ if (i == ab->qmi.mem_seg_count) { -+ ath11k_warn(ab, "qmi invalid paddr from firmware for M3 dump\n"); -+ ret = -EINVAL; -+ vfree(dump); -+ goto send_resp; -+ } -+ -+ m3_dump_data->addr = target_mem[i].vaddr; -+ m3_dump_data->size = event_data->size; -+ m3_dump_data->pdev_id = event_data->pdev_id; -+ m3_dump_data->timestamp = ktime_to_ms(ktime_get()); -+ -+ memcpy(dump, m3_dump_data->addr, m3_dump_data->size); -+ -+ dev_coredumpv(ab->dev, dump, le32_to_cpu(m3_dump_data->size), -+ GFP_KERNEL); -+ -+send_resp: -+ ret = ath11k_qmi_m3_dump_upload_done_ind_send(ab, event_data->pdev_id, ret); -+ if (ret < 0) -+ ath11k_warn(ab, "qmi M3 dump upload done failed\n"); -+ -+ kfree(m3_dump_data); -+ return; -+} -+ - static int - ath11k_qmi_driver_event_post(struct ath11k_qmi *qmi, - enum ath11k_qmi_event_type type, -@@ -3093,6 +3348,30 @@ static void ath11k_qmi_msg_fw_init_done_ - ath11k_dbg(ab, ATH11K_DBG_QMI, "firmware init done\n"); - } - -+static void ath11k_qmi_m3_dump_upload_req_ind_cb(struct qmi_handle *qmi_hdl, -+ struct sockaddr_qrtr *sq, -+ struct qmi_txn *txn, -+ const void *data) -+{ -+ struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle); -+ struct ath11k_base *ab = qmi->ab; -+ const struct qmi_wlanfw_m3_dump_upload_req_ind_msg_v01 *msg = data; -+ struct ath11k_qmi_m3_dump_upload_req_data *event_data; -+ -+ ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi m3 dump memory request\n"); -+ -+ event_data = kzalloc(sizeof(*event_data), GFP_KERNEL); -+ if (!event_data) -+ return; -+ -+ event_data->pdev_id = msg->pdev_id; -+ event_data->addr = msg->addr; -+ event_data->size = msg->size; -+ -+ ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_M3_DUMP_UPLOAD_REQ, -+ event_data); -+} -+ - static const struct qmi_msg_handler ath11k_qmi_msg_handlers[] = { - { - .type = QMI_INDICATION, -@@ -3125,13 +3404,20 @@ static const struct qmi_msg_handler ath1 - }, - { - .type = QMI_INDICATION, -+ .msg_id = QMI_WLFW_M3_DUMP_UPLOAD_REQ_IND_V01, -+ .ei = qmi_wlanfw_m3_dump_upload_req_ind_msg_v01_ei, -+ .decoded_size = -+ sizeof(struct qmi_wlanfw_m3_dump_upload_req_ind_msg_v01), -+ .fn = ath11k_qmi_m3_dump_upload_req_ind_cb, -+ }, -+ { -+ .type = QMI_INDICATION, - .msg_id = QMI_WLFW_FW_INIT_DONE_IND_V01, - .ei = qmi_wlfw_fw_init_done_ind_msg_v01_ei, - .decoded_size = - sizeof(struct qmi_wlfw_fw_init_done_ind_msg_v01), - .fn = ath11k_qmi_msg_fw_init_done_cb, - }, -- - /* end of list */ - {}, - }; -@@ -3271,6 +3557,9 @@ static void ath11k_qmi_driver_event_work - break; - case ATH11K_QMI_EVENT_COLD_BOOT_CAL_DONE: - break; -+ case ATH11K_QMI_EVENT_M3_DUMP_UPLOAD_REQ: -+ ath11k_qmi_event_m3_dump_upload_req(qmi, event->data); -+ break; - default: - ath11k_warn(ab, "invalid qmi event type: %d", event->type); - break; ---- a/drivers/net/wireless/ath/ath11k/qmi.h -+++ b/drivers/net/wireless/ath/ath11k/qmi.h -@@ -31,15 +31,21 @@ - - #ifdef CPTCFG_ATH11K_MEM_PROFILE_512M - #define ATH11K_QMI_IPQ8074_M3_DUMP_ADDRESS 0x4E800000 -+#define ATH11K_QMI_IPQ8074_M3_DUMP_OFFSET 0x3800000 - #else - #define ATH11K_QMI_IPQ8074_M3_DUMP_ADDRESS 0x51000000 -+#define ATH11K_QMI_IPQ8074_M3_DUMP_OFFSET 0x6000000 - #endif - -+#define ATH11K_QMI_M3_DUMP_SIZE 0x100000 -+ - #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 - #define QMI_WLFW_FW_READY_IND_V01 0x0021 - #define QMI_WLFW_FW_INIT_DONE_IND_V01 0x0038 -+#define QMI_WLFW_M3_DUMP_UPLOAD_DONE_REQ_V01 0x004E -+#define QMI_WLFW_M3_DUMP_UPLOAD_REQ_IND_V01 0x004D - - #define QMI_WLANFW_MAX_DATA_SIZE_V01 6144 - #define ATH11K_FIRMWARE_MODE_OFF 4 -@@ -47,7 +53,16 @@ - - #define ATH11K_QMI_DEVICE_BAR_SIZE 0x200000 - -+#define ATH11K_HOST_DDR_M3_OFFSET 0x2300000 -+ - struct ath11k_base; -+extern unsigned int ath11k_host_ddr_addr; -+ -+enum ath11k_target_mem_mode { -+ ATH11K_QMI_TARGET_MEM_MODE_DEFAULT = 0, -+ ATH11K_QMI_TARGET_MEM_MODE_512M, -+ ATH11K_QMI_TARGET_MEM_MODE_256M, -+}; - - enum ath11k_qmi_file_type { - ATH11K_QMI_FILE_TYPE_BDF_GOLDEN, -@@ -76,6 +91,7 @@ enum ath11k_qmi_event_type { - ATH11K_QMI_EVENT_FORCE_FW_ASSERT, - ATH11K_QMI_EVENT_POWER_UP, - ATH11K_QMI_EVENT_POWER_DOWN, -+ ATH11K_QMI_EVENT_M3_DUMP_UPLOAD_REQ, - ATH11K_QMI_EVENT_FW_INIT_DONE, - ATH11K_QMI_EVENT_MAX, - }; -@@ -86,6 +102,13 @@ struct ath11k_qmi_driver_event { - void *data; - }; - -+struct ath11k_qmi_m3_dump_data { -+ u32 pdev_id; -+ u32 size; -+ u64 timestamp; -+ u32 *addr; -+}; -+ - struct ath11k_qmi_ce_cfg { - const struct ce_pipe_config *tgt_ce; - int tgt_ce_len; -@@ -150,7 +173,22 @@ struct ath11k_qmi { - wait_queue_head_t cold_boot_waitq; - }; - --#define QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN 261 -+struct ath11k_qmi_m3_dump_upload_req_data { -+ u32 pdev_id; -+ u64 addr; -+ u64 size; -+}; -+ -+struct qmi_wlanfw_m3_dump_upload_done_req_msg_v01 { -+ u32 pdev_id; -+ u32 status; -+}; -+ -+struct qmi_wlanfw_m3_dump_upload_done_resp_msg_v01 { -+ struct qmi_response_type_v01 resp; -+}; -+ -+#define QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN 194 - #define QMI_WLANFW_HOST_CAP_REQ_V01 0x0034 - #define QMI_WLANFW_HOST_CAP_RESP_MSG_V01_MAX_LEN 7 - #define QMI_WLFW_HOST_CAP_RESP_V01 0x0034 -@@ -226,6 +264,10 @@ struct qmi_wlanfw_ind_register_req_msg_v - u8 xo_cal_enable; - u8 cal_done_enable_valid; - u8 cal_done_enable; -+ u8 respond_get_info_enable_valid; -+ u8 respond_get_info_enable; -+ u8 m3_dump_upload_req_enable_valid; -+ u8 m3_dump_upload_req_enable; - }; - - struct qmi_wlanfw_ind_register_resp_msg_v01 { -@@ -303,6 +345,12 @@ struct qmi_wlfw_fw_init_done_ind_msg_v01 - char placeholder; - }; - -+struct qmi_wlanfw_m3_dump_upload_req_ind_msg_v01 { -+ u32 pdev_id; -+ u64 addr; -+ u64 size; -+}; -+ - #define QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN 0 - #define QMI_WLANFW_CAP_RESP_MSG_V01_MAX_LEN 235 - #define QMI_WLANFW_CAP_REQ_V01 0x0024 -@@ -447,6 +495,8 @@ struct qmi_wlanfw_bdf_download_resp_msg_ - #define QMI_WLANFW_M3_INFO_RESP_V01 0x003C - #define QMI_WLANFW_M3_INFO_REQ_V01 0x003C - -+#define QMI_WLANFW_M3_DUMP_UPLOAD_DONE_REQ_MSG_V01_MAX_MSG_LEN 14 -+ - struct qmi_wlanfw_m3_info_req_msg_v01 { - u64 addr; - u32 size; -@@ -525,10 +575,4 @@ 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); - --enum ath11k_target_mem_mode { -- ATH11K_QMI_TARGET_MEM_MODE_DEFAULT = 0, -- ATH11K_QMI_TARGET_MEM_MODE_512M, -- ATH11K_QMI_TARGET_MEM_MODE_256M, --}; -- - #endif ---- a/drivers/net/wireless/ath/ath11k/core.h -+++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -638,6 +638,7 @@ struct ath11k_debug { - u32 mem_offset; - u32 module_id_bitmap[MAX_MODULE_ID_BITMAP_WORDS]; - struct ath11k_debug_dbr *dbr_debug[WMI_DIRECT_BUF_MAX]; -+ bool enable_m3_dump; - }; - - struct ath11k_per_peer_tx_stats { ---- a/drivers/net/wireless/ath/ath11k/debugfs.c -+++ b/drivers/net/wireless/ath/ath11k/debugfs.c -@@ -2226,6 +2226,68 @@ static const struct file_operations fops - .llseek = default_llseek, - }; - -+static ssize_t ath11k_write_enable_m3_dump(struct file *file, -+ const char __user *ubuf, -+ size_t count, loff_t *ppos) -+{ -+ struct ath11k *ar = file->private_data; -+ bool enable; -+ int ret; -+ -+ if (kstrtobool_from_user(ubuf, count, &enable)) -+ return -EINVAL; -+ -+ mutex_lock(&ar->conf_mutex); -+ -+ if (ar->state != ATH11K_STATE_ON) { -+ ret = -ENETDOWN; -+ goto exit; -+ } -+ -+ if (enable == ar->debug.enable_m3_dump) { -+ ret = count; -+ goto exit; -+ } -+ -+ ret = ath11k_wmi_pdev_m3_dump_enable(ar, enable); -+ if (ret) { -+ ath11k_warn(ar->ab, -+ "failed to enable m3 ssr dump %d\n", -+ ret); -+ goto exit; -+ } -+ -+ ar->debug.enable_m3_dump = enable; -+ ret = count; -+ -+exit: -+ mutex_unlock(&ar->conf_mutex); -+ return ret; -+} -+ -+static ssize_t ath11k_read_enable_m3_dump(struct file *file, -+ char __user *ubuf, -+ size_t count, loff_t *ppos) -+{ -+ struct ath11k *ar = file->private_data; -+ char buf[32]; -+ size_t len = 0; -+ -+ mutex_lock(&ar->conf_mutex); -+ len = scnprintf(buf, sizeof(buf) - len, "%d\n", -+ ar->debug.enable_m3_dump); -+ mutex_unlock(&ar->conf_mutex); -+ -+ return simple_read_from_buffer(ubuf, count, ppos, buf, len); -+ -+} -+ -+static const struct file_operations fops_enable_m3_dump = { -+ .read = ath11k_read_enable_m3_dump, -+ .write = ath11k_write_enable_m3_dump, -+ .open = simple_open -+}; -+ - int ath11k_debugfs_register(struct ath11k *ar) - { - struct ath11k_base *ab = ar->ab; -@@ -2293,6 +2355,10 @@ int ath11k_debugfs_register(struct ath11 - debugfs_create_file("nss_peer_stats_config", 0644, - ar->debug.debugfs_pdev, ar, &fops_nss_stats); - -+ debugfs_create_file("enable_m3_dump", 0644, -+ ar->debug.debugfs_pdev, ar, -+ &fops_enable_m3_dump); -+ - return 0; - } - void ath11k_debugfs_add_interface(struct ath11k_vif *arvif) ---- a/drivers/net/wireless/ath/ath11k/wmi.c -+++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -9301,6 +9301,36 @@ int ath11k_wmi_fw_dbglog_cfg(struct ath1 - return ret; - } - -+int ath11k_wmi_pdev_m3_dump_enable(struct ath11k *ar, u32 enable) { -+ struct ath11k_vif *arvif; -+ u32 m3_args[WMI_M3_MAX_TEST_ARGS]; -+ struct wmi_unit_test_cmd wmi_ut; -+ bool arvif_found = false; -+ -+ list_for_each_entry(arvif, &ar->arvifs, list) { -+ if (arvif->is_started) { -+ arvif_found = true; -+ break; -+ } -+ } -+ -+ if (!arvif_found) -+ return -EINVAL; -+ -+ m3_args[WMI_M3_TEST_CMDID] = WMI_DBG_ENABLE_M3_SSR; -+ m3_args[WMI_M3_TEST_ENABLE] = enable; -+ -+ wmi_ut.vdev_id = arvif->vdev_id; -+ wmi_ut.module_id = WMI_M3_UNIT_TEST_MODULE; -+ wmi_ut.num_args = WMI_M3_MAX_TEST_ARGS; -+ wmi_ut.diag_token = WMI_M3_UNIT_TEST_TOKEN; -+ -+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "%s M3 SSR dump\n", -+ enable ? "Enabling" : "Disabling"); -+ -+ return ath11k_wmi_send_unit_test_cmd(ar, wmi_ut, m3_args); -+} -+ - int ath11k_wmi_connect(struct ath11k_base *ab) - { - u32 i; ---- a/drivers/net/wireless/ath/ath11k/wmi.h -+++ b/drivers/net/wireless/ath/ath11k/wmi.h -@@ -2136,6 +2136,11 @@ enum wmi_tlv_service { - WMI_MAX_EXT2_SERVICE = 384 - }; - -+enum wmi_unit_test_cmdid { -+ /* TODO: Add the remaining cmd ids if needed */ -+ WMI_DBG_ENABLE_M3_SSR = 36, -+}; -+ - enum { - WMI_SMPS_FORCED_MODE_NONE = 0, - WMI_SMPS_FORCED_MODE_DISABLED, -@@ -4116,6 +4121,15 @@ struct wmi_dfs_unit_test_arg { - u32 radar_param; - }; - -+#define WMI_M3_UNIT_TEST_MODULE 0x22 -+#define WMI_M3_UNIT_TEST_TOKEN 0 -+ -+enum wmi_m3_test_args_idx { -+ WMI_M3_TEST_CMDID, -+ WMI_M3_TEST_ENABLE, -+ WMI_M3_MAX_TEST_ARGS, -+}; -+ - struct wmi_unit_test_cmd { - u32 tlv_header; - u32 vdev_id; -@@ -6654,6 +6668,7 @@ int ath11k_wmi_set_hw_mode(struct ath11k - enum wmi_host_hw_mode_config_type mode); - int ath11k_wmi_wow_host_wakeup_ind(struct ath11k *ar); - int ath11k_wmi_wow_enable(struct ath11k *ar); -+int ath11k_wmi_pdev_m3_dump_enable(struct ath11k *ar, u32 enable); - int ath11k_wmi_scan_prob_req_oui(struct ath11k *ar, - const u8 mac_addr[ETH_ALEN]); - int ath11k_wmi_fw_dbglog_cfg(struct ath11k *ar, u32 *module_id_bitmap, ---- a/drivers/net/wireless/ath/ath11k/core.c -+++ b/drivers/net/wireless/ath/ath11k/core.c -@@ -44,6 +44,25 @@ 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"); - -+#ifdef CONFIG_QCOM_QMI_HELPERS -+wait_queue_head_t ath11k_ssr_dump_wq; -+EXPORT_SYMBOL(ath11k_ssr_dump_wq); -+ -+bool ath11k_collect_dump = false; -+EXPORT_SYMBOL(ath11k_collect_dump); -+#endif -+ -+unsigned int ath11k_host_ddr_addr; -+EXPORT_SYMBOL(ath11k_host_ddr_addr); -+module_param_named(host_ddr_addr, ath11k_host_ddr_addr, uint, 0644); -+MODULE_PARM_DESC(host_ddr_addr, "host ddr addr for FW"); -+ -+bool dev_init_progress = false; -+EXPORT_SYMBOL(dev_init_progress); -+ -+struct mutex dev_init_lock; -+EXPORT_SYMBOL(dev_init_lock); -+ - static const struct ath11k_num_vdevs_peers ath11k_vdevs_peers[]; - - static struct ath11k_hw_params ath11k_hw_params[] = { -@@ -58,6 +77,7 @@ static struct ath11k_hw_params ath11k_hw - .max_radios = 3, - .bdf_addr = 0x4B0C0000, - .hw_ops = &ipq8074_ops, -+ .m3_addr = ATH11K_QMI_IPQ8074_M3_DUMP_ADDRESS, - .ring_mask = &ath11k_hw_ring_mask_ipq8074, - .internal_sleep_clock = false, - .regs = &ipq8074_regs, -@@ -134,6 +154,8 @@ static struct ath11k_hw_params ath11k_hw - /* 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, -+ .m3_offset = ATH11K_QMI_IPQ8074_M3_DUMP_OFFSET, -+ }, - { - .hw_rev = ATH11K_HW_IPQ6018_HW10, - .name = "ipq6018 hw1.0", -@@ -191,7 +213,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 = false, - .alloc_cacheable_memory = true, -@@ -350,7 +371,7 @@ static struct ath11k_hw_params ath11k_hw - .coldboot_cal_mm = false, - .coldboot_cal_ftm = false, - .cbcal_restart_fw = true, -- .fw_mem_mode = 2, -+ .fw_mem_mode = ATH11K_QMI_TARGET_MEM_MODE, - .num_vdevs = 8, - .num_peers = 128, - .supports_suspend = false, ---- a/drivers/net/wireless/ath/ath11k/hw.h -+++ b/drivers/net/wireless/ath/ath11k/hw.h -@@ -243,6 +243,7 @@ struct ath11k_hw_params { - const struct ath11k_hw_hal_params *hal_params; - bool supports_dynamic_smps_6ghz; - bool alloc_cacheable_memory; -+ u32 m3_addr; - u8 reo_dest_ring_map_shift; - bool supports_rssi_stats; - bool fw_wmi_diag_event; -@@ -269,6 +270,7 @@ struct ath11k_hw_params { - bool smp2p_wow_exit; - bool support_fw_mac_sequence; - const struct ath11k_num_vdevs_peers *num_vdevs_peers; -+ u32 m3_offset; - }; - - struct ath11k_hw_ops { diff --git a/package/kernel/mac80211/patches/ath11k_nss/911-244-ath11k-dp-tx-perf.patch b/package/kernel/mac80211/patches/ath11k_nss/911-244-ath11k-dp-tx-perf.patch index d338b0a49972ea..79906c8d3a4ab3 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/911-244-ath11k-dp-tx-perf.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/911-244-ath11k-dp-tx-perf.patch @@ -34,7 +34,7 @@ Signed-off-by: P Praneesh }; struct ath11k_skb_cb { -@@ -920,7 +921,12 @@ struct ath11k_soc_dp_tx_err_stats { +@@ -919,7 +920,12 @@ struct ath11k_soc_dp_tx_err_stats { /* Other failures during dp_tx due to mem allocation failure * idr unavailable etc. */ @@ -464,7 +464,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 -@@ -835,10 +835,22 @@ static ssize_t ath11k_debugfs_dump_soc_d +@@ -833,10 +833,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 +489,15 @@ Signed-off-by: P Praneesh if (len > size) --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c -@@ -237,6 +237,8 @@ static struct ath11k_hw_params ath11k_hw +@@ -192,7 +192,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 = false, + .alloc_cacheable_memory = true, +@@ -217,6 +216,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, @@ -498,15 +506,7 @@ Signed-off-by: P Praneesh }, { .name = "qca6390 hw2.0", -@@ -379,7 +381,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, -@@ -404,6 +405,8 @@ static struct ath11k_hw_params ath11k_hw +@@ -384,6 +384,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,7 +515,7 @@ Signed-off-by: P Praneesh }, { .name = "wcn6855 hw2.0", -@@ -2167,6 +2170,9 @@ int ath11k_core_pre_init(struct ath11k_b +@@ -2147,6 +2149,9 @@ int ath11k_core_pre_init(struct ath11k_b ab->enable_memory_stats = ATH11K_DEBUG_ENABLE_MEMORY_STATS; From 32c19b75368a749fd818dd93d39c5404f1566efd Mon Sep 17 00:00:00 2001 From: Qosmio Date: Wed, 17 Jan 2024 05:04:28 -0500 Subject: [PATCH 092/225] ath11k_nss: set pbuf script off by default uci option pbuf.opt.memory_profile must be explicity set to auto, 1gb, 512m, 256m to run. --- package/kernel/mac80211/Makefile | 2 +- .../mac80211/files/etc/init.d/qca-nss-pbuf | 16 +++++++++++----- package/kernel/mac80211/files/pbuf.uci | 3 ++- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index fe3350ab593faa..654aebd069640e 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 PKG_VERSION:=6.5 -PKG_RELEASE:=6 +PKG_RELEASE:=7 # PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.15.58/ PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/ PKG_HASH:=908c22dceba185eab83caa5a1e58ce6b3ebdc58f099c3fd3e11c7352ebfab2d7 diff --git a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf index be89de061ce8b1..02afd5f6c3d380 100755 --- a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf +++ b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf @@ -50,15 +50,21 @@ apply_nss_config() { board=$memory_profile logger -t ath11k_nss "Using custom memory profile - $board" ;; - *) - logger -s -t ath11k_nss -p user.error "Unknown profile $memory_profile. Choose 1gb, 512mb, or 256mb" + off*|false*|disable*|0) + logger -s -t ath11k_nss -p user.warn "NSS pbuf option 'memory_profile=off'. Not running. Enable if you have issues connecting more than 65 clients" + exit 0 + ;; + auto) board=$(board_name) - logger -s -t ath11k_nss -p user.warn "Falling back to: $board" + logger -t ath11k_nss "Setting n2hcfg values for board: $board" + ;; + *) + logger -s -t ath11k_nss -p user.error "Unknown profile $memory_profile. Choose auto, 1gb, 512mb, or 256mb" + exit 1 ;; esac else - board=$(board_name) - logger -t ath11k_nss "Setting n2hcfg values for board: $board" + exi 0 fi case "$board" in diff --git a/package/kernel/mac80211/files/pbuf.uci b/package/kernel/mac80211/files/pbuf.uci index ac4fadbc4f5e63..2b277e11f02f4d 100644 --- a/package/kernel/mac80211/files/pbuf.uci +++ b/package/kernel/mac80211/files/pbuf.uci @@ -1,5 +1,6 @@ config general opt - # to bypass board autodetection, uncomment ONE of the options below + option memory_profile 'off' + # option memory_profile 'auto' # option memory_profile '1gb' # option memory_profile '512mb' # option memory_profile '256mb' From 0d49e85763268db0a2ba0f999ddfb41a776f57f1 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Wed, 17 Jan 2024 15:45:10 -0500 Subject: [PATCH 093/225] ath11k_nss: Refresh patches --- .../199-003-ath11k-add-nss-support.patch | 22 +++--- ...-ath11k-Add-support-for-dynamic-vlan.patch | 2 +- ...207-ath11k-Enable-256_512MB-profiles.patch | 26 +++---- ...11k-Disable-rx_header-tlv-for-2K-SKB.patch | 10 +-- ...01-ath11k-account-tx-rx-packets-flow.patch | 6 +- ...dd-provision-to-configure-rx-hashmap.patch | 2 +- ...dst-ring-descriptors-from-cacheable-.patch | 4 +- ...ow-fast-rx-by-bypassing-stats-update.patch | 4 +- ...00-mac80211-nss-mesh-offload-support.patch | 2 +- ...TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch | 2 +- ...-0005-mac80211-simple-tx-for-AP-mode.patch | 4 +- ...mac80211-fix-unconditional-sta-usage.patch | 2 +- ...unused-RX_FLAGS-from-mac80211_rx_fla.patch | 4 +- .../640-006-mac80211-add-eht-radiotap.patch | 8 +-- ...ncapsulation-of-EAPOL-frames-if-OFFL.patch | 24 +++---- ...-the-frame-to-driver-tx-ops-directly.patch | 4 +- ...se-HW-checksum-offload-only-for-ethm.patch | 18 ++--- .../829-mac80211-fix-mesh-ping-issue.patch | 8 +-- .../patches/ath11k_nss/900-fix-build.patch | 12 ++-- ...N-iftype-support-on-NSS-offload-case.patch | 10 +-- ...load-changes-to-NSS-driver-interface.patch | 20 +++--- ...-dynamic-VLAN-support-on-NSS-offload.patch | 4 +- ...-support-on-NSS-offload-for-STA-mode.patch | 6 +- .../902-020-ath11k-add-btcoex-config.patch | 10 +-- .../902-022-ath11k-add-ap-ps-support.patch | 8 +-- ...69-ath11k-add-HE-stats-in-peer-stats.patch | 8 +-- ...vdev-in-NSS-for-AP_VLAN-vif-handling.patch | 34 ++++----- ...pport-for-WDS-offload-in-NSS-offload.patch | 32 ++++----- ...dev-in-NSS-for-dynamic-VLAN-handling.patch | 12 ++-- ...-dynamic-VLAN-support-in-NSS-offload.patch | 38 +++++----- ...04-300-ath11k-nss_get_arvif_from_dev.patch | 8 +-- .../905-ath11k-add-support-memory-stats.patch | 70 +++++++++---------- ...07-068-ath11k-add-rx-histogram-stats.patch | 12 ++-- ...11k-remove-error-on-soc-debugfs-fail.patch | 6 +- .../908-301-ath11k-nss-mcbc-exception.patch | 20 +++--- ...30-ath11k-sync-wds_ast_entry-updates.patch | 22 +++--- ...ct-ast-index-assignment-for-wds-peer.patch | 6 +- .../911-244-ath11k-dp-tx-perf.patch | 6 +- ...Add-retry-mechanism-for-update_rx_qu.patch | 2 +- ...rt-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch | 2 +- 40 files changed, 250 insertions(+), 250 deletions(-) diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch b/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch index 34b30984ca76d2..1e6941e26f96b0 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch @@ -573,7 +573,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 +582,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 +591,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 +600,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 +609,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 +645,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 +653,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 +664,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 +673,7 @@ Signed-off-by: Sriram R } #if IS_ENABLED(CONFIG_IPV6) -@@ -9136,6 +9245,7 @@ static const struct ieee80211_ops ath11k +@@ -9136,6 +9243,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 +681,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 +@@ -9521,7 +9629,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 +691,7 @@ Signed-off-by: Sriram R } ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; -@@ -9636,6 +9747,9 @@ static int __ath11k_mac_register(struct +@@ -9636,6 +9745,9 @@ static int __ath11k_mac_register(struct ab->hw_params.bios_sar_capa) ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa; diff --git a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch index a937ffba79961c..2fd5374354ca61 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch @@ -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 +@@ -9762,6 +9762,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/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch index 4d7af8641311dc..f4ee9048669956 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch @@ -149,7 +149,7 @@ 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 { +@@ -864,6 +864,11 @@ struct ath11k_msi_config { u16 hw_rev; }; @@ -161,7 +161,7 @@ Signed-off-by: Ramya Gnanasekar /* 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 { +@@ -1017,6 +1022,9 @@ struct ath11k_base { } testmode; #endif @@ -199,7 +199,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 +207,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 +215,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 +223,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); @@ -286,7 +286,7 @@ Signed-off-by: Ramya Gnanasekar }, { .hw_rev = ATH11K_HW_IPQ6018_HW10, -@@ -177,7 +183,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -177,7 +184,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = true, .coldboot_cal_ftm = true, .cbcal_restart_fw = true, @@ -295,7 +295,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = false, -@@ -259,7 +265,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -259,7 +266,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -304,7 +304,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 +433,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -313,7 +313,7 @@ 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 +@@ -509,7 +516,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -322,7 +322,7 @@ 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 +@@ -593,7 +600,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = true, .coldboot_cal_ftm = true, .cbcal_restart_fw = false, @@ -331,7 +331,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 +679,7 @@ static struct ath11k_hw_params ath11k_hw .supports_monitor = false, .supports_sta_ps = false, .supports_shadow_regs = false, @@ -340,7 +340,7 @@ 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 +@@ -710,7 +717,23 @@ static struct ath11k_hw_params ath11k_hw }, }; diff --git a/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch b/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch index 87314bc425d3d1..67b84c10946199 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch @@ -499,7 +499,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 +@@ -1183,6 +1183,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 +508,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 +@@ -1192,6 +1194,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 +535,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 +@@ -1270,6 +1292,7 @@ int ath11k_dp_tx_htt_monitor_mode_ring_c } ring_id = dp->rxdma_mon_buf_ring.refill_buf_ring.ring_id; @@ -834,7 +834,7 @@ Signed-off-by: Ramya Gnanasekar { 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_ +@@ -6338,6 +6338,7 @@ static int ath11k_mac_config_mon_status_ tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar); } @@ -842,7 +842,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; ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, -@@ -9716,8 +9717,6 @@ static int __ath11k_mac_register(struct +@@ -9714,8 +9715,6 @@ static int __ath11k_mac_register(struct wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); 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 index 08e158a407ca8f..d7d2b3bab12076 100644 --- 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 @@ -79,7 +79,7 @@ Signed-off-by: Maharaja Kennadyrajan --- 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 { +@@ -495,6 +495,17 @@ struct ath11k_per_ppdu_tx_stats { DECLARE_EWMA(avg_rssi, 10, 8) @@ -97,7 +97,7 @@ Signed-off-by: Maharaja Kennadyrajan struct ath11k_sta { struct ath11k_vif *arvif; -@@ -527,6 +538,8 @@ struct ath11k_sta { +@@ -528,6 +539,8 @@ struct ath11k_sta { #ifdef CPTCFG_ATH11K_NSS_SUPPORT struct ath11k_nss_sta_stats *nss_stats; #endif @@ -476,7 +476,7 @@ Signed-off-by: Maharaja Kennadyrajan bool is_prb_rsp; u16 frm_type = 0; int ret; -@@ -6314,6 +6315,15 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6312,6 +6313,15 @@ static void ath11k_mac_op_tx(struct ieee ieee80211_free_txskb(ar->hw, skb); return; } 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 index 83c019b871e81b..f0347b3bde6046 100644 --- 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 @@ -33,7 +33,7 @@ Signed-off-by: P Praneesh enum ath11k_supported_bw { ATH11K_BW_20 = 0, ATH11K_BW_40 = 1, -@@ -1037,6 +1038,8 @@ struct ath11k_base { +@@ -1038,6 +1039,8 @@ struct ath11k_base { atomic_t num_max_allowed; struct ath11k_num_vdevs_peers *num_vdevs_peers; diff --git a/package/kernel/mac80211/patches/ath11k_nss/237-003-ath11k-allocate-dst-ring-descriptors-from-cacheable-.patch b/package/kernel/mac80211/patches/ath11k_nss/237-003-ath11k-allocate-dst-ring-descriptors-from-cacheable-.patch index c054ee146f748a..a102c8c5cc6c56 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/237-003-ath11k-allocate-dst-ring-descriptors-from-cacheable-.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/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); 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/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch index 9bc2b50f7cbd45..04b8b1d01e47fa 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/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 { +@@ -136,6 +136,7 @@ struct ath11k_skb_rxcb { u8 tid; u16 peer_id; u16 seq_no; @@ -31,7 +31,7 @@ Signed-off-by: P Praneesh }; enum ath11k_hw_rev { -@@ -1039,6 +1040,7 @@ struct ath11k_base { +@@ -1040,6 +1041,7 @@ struct ath11k_base { struct ath11k_num_vdevs_peers *num_vdevs_peers; u32 rx_hash; diff --git a/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch b/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch index d3e6b9850b620f..c07f9ef9fa94e4 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch @@ -1220,7 +1220,7 @@ 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 +@@ -4358,9 +4369,15 @@ void __ieee80211_subif_start_xmit(struct goto out; } 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/ath11k_nss/335-0003-ath11k-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch index 1bfbd0ebdbb27e..641f45b094a598 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/ath11k_nss/335-0003-ath11k-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch @@ -69,7 +69,7 @@ Signed-off-by: Venkateswara Naralasetty 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 +@@ -9680,6 +9680,8 @@ static int __ath11k_mac_register(struct ieee80211_hw_set(ar->hw, USES_RSS); } diff --git a/package/kernel/mac80211/patches/ath11k_nss/335-0005-mac80211-simple-tx-for-AP-mode.patch b/package/kernel/mac80211/patches/ath11k_nss/335-0005-mac80211-simple-tx-for-AP-mode.patch index d859d038003196..4935be7bf106b2 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/335-0005-mac80211-simple-tx-for-AP-mode.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/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: +@@ -4765,6 +4765,70 @@ out_free: kfree_skb(skb); } @@ -85,7 +85,7 @@ Signed-off-by: Aloka Dixit 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 +@@ -4804,6 +4868,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/342-mac80211-fix-unconditional-sta-usage.patch b/package/kernel/mac80211/patches/ath11k_nss/342-mac80211-fix-unconditional-sta-usage.patch index e4890a3654c3b3..3efff7ea87bebc 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/342-mac80211-fix-unconditional-sta-usage.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/342-mac80211-fix-unconditional-sta-usage.patch @@ -33,7 +33,7 @@ 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 +@@ -4742,12 +4742,12 @@ static void ieee80211_8023_xmit(struct i if (unlikely(skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS && 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/ath11k_nss/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch index 14fd82cbeaa853..c86330c9b21b57 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/ath11k_nss/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 +@@ -1405,8 +1405,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 { +@@ -1478,22 +1476,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), 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 index 79146df5447b8b..5d45089546e492 100644 --- 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 @@ -321,7 +321,7 @@ Signed-off-by: P Praneesh */ --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -1441,7 +1441,11 @@ ieee80211_tx_info_clear_status(struct ie +@@ -1459,7 +1459,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) @@ -333,7 +333,7 @@ Signed-off-by: P Praneesh enum mac80211_rx_flags { RX_FLAG_MMIC_ERROR = BIT(0), RX_FLAG_DECRYPTED = BIT(1), -@@ -1473,6 +1477,8 @@ enum mac80211_rx_flags { +@@ -1491,6 +1495,8 @@ enum mac80211_rx_flags { RX_FLAG_RADIOTAP_LSIG = BIT(27), RX_FLAG_NO_PSDU = BIT(28), RX_FLAG_8023 = BIT(29), @@ -342,7 +342,7 @@ Signed-off-by: P Praneesh }; /** -@@ -1540,6 +1546,7 @@ enum mac80211_rx_encoding { +@@ -1558,6 +1564,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_\* @@ -350,7 +350,7 @@ Signed-off-by: P Praneesh * @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 { +@@ -1611,6 +1618,7 @@ struct ieee80211_rx_status { u8 ampdu_delimiter_crc; u8 zero_length_psdu_type; u8 link_valid:1, link_id:4; diff --git a/package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch b/package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch index 70e2603c8cc02b..b2bc7e750b51eb 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch @@ -44,7 +44,7 @@ Signed-off-by: Aaradhana Sahu static inline void ieee80211_tx_stats(struct net_device *dev, u32 len) { -@@ -4310,13 +4311,18 @@ void __ieee80211_subif_start_xmit(struct +@@ -4321,13 +4322,18 @@ void __ieee80211_subif_start_xmit(struct atomic_inc(&sta->tx_netif_pkts); if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { @@ -66,7 +66,7 @@ Signed-off-by: Aaradhana Sahu rcu_read_unlock(); return; } -@@ -4374,7 +4378,7 @@ void __ieee80211_subif_start_xmit(struct +@@ -4373,7 +4379,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]); @@ -75,7 +75,7 @@ Signed-off-by: Aaradhana Sahu } else { ieee80211_tx_stats(dev, skb->len); ieee80211_xmit(sdata, sta, skb); -@@ -4657,19 +4663,29 @@ static bool ieee80211_tx_8023(struct iee +@@ -4674,19 +4680,29 @@ 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, @@ -106,7 +106,7 @@ Signed-off-by: Aaradhana Sahu 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 +@@ -4721,6 +4737,7 @@ static void ieee80211_8023_xmit(struct i info = IEEE80211_SKB_CB(skb); memset(info, 0, sizeof(*info)); @@ -114,7 +114,7 @@ Signed-off-by: Aaradhana Sahu 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 +@@ -4740,9 +4757,10 @@ static void ieee80211_8023_xmit(struct i memcpy(IEEE80211_SKB_CB(seg), info, sizeof(*info)); } @@ -128,7 +128,7 @@ Signed-off-by: Aaradhana Sahu info->ack_frame_id = ieee80211_store_ack_skb(local, skb, &info->flags, NULL); -@@ -4750,7 +4768,8 @@ out_free: +@@ -4767,7 +4785,8 @@ out_free: void ieee80211_8023_xmit_ap(struct ieee80211_sub_if_data *sdata, struct net_device *dev, struct sta_info *sta, @@ -138,7 +138,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 +@@ -4776,6 +4795,9 @@ void ieee80211_8023_xmit_ap(struct ieee8 unsigned long flags; int q; u16 q_map; @@ -148,7 +148,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 +@@ -4787,11 +4809,13 @@ void ieee80211_8023_xmit_ap(struct ieee8 info = IEEE80211_SKB_CB(skb); memset(info, 0, sizeof(*info)); @@ -165,7 +165,7 @@ 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 +@@ -4828,14 +4852,23 @@ void ieee80211_8023_xmit_ap(struct ieee8 if (sta) atomic_inc(&sta->tx_drv_pkts); } @@ -190,7 +190,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 +@@ -4851,14 +4884,15 @@ netdev_tx_t ieee80211_subif_start_xmit_8 kfree_skb(skb); goto out; } @@ -208,7 +208,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 +@@ -4869,13 +4903,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 goto skip_offload; if (sdata->vif.type == NL80211_IFTYPE_AP) { @@ -224,7 +224,7 @@ Signed-off-by: Aaradhana Sahu goto out; skip_offload: -@@ -6364,13 +6398,10 @@ start_xmit: +@@ -6381,13 +6415,10 @@ start_xmit: mutex_lock(&local->mtx); local_bh_disable(); 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 index 31db236d5fd4ef..1548ede8c6e660 100644 --- 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 @@ -19,7 +19,7 @@ Signed-off-by: Ramanathan Choodamani --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4567,6 +4567,7 @@ netdev_tx_t ieee80211_subif_start_xmit(s +@@ -4584,6 +4584,7 @@ netdev_tx_t ieee80211_subif_start_xmit(s #ifdef CPTCFG_MAC80211_NSS_SUPPORT ieee80211_xmit_nss_fixup(skb, dev); #endif @@ -27,7 +27,7 @@ Signed-off-by: Ramanathan Choodamani if (likely(!is_multicast_ether_addr(eth->h_dest))) goto normal; -@@ -4838,7 +4839,43 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4855,7 +4856,43 @@ void ieee80211_8023_xmit_ap(struct ieee8 netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, struct net_device *dev) { diff --git a/package/kernel/mac80211/patches/ath11k_nss/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch b/package/kernel/mac80211/patches/ath11k_nss/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch index e5b4d7d9e7ef4e..cc77cf8d4be1a6 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/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 +@@ -3643,7 +3645,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 +@@ -3661,7 +3663,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 +@@ -3807,7 +3809,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 +@@ -4356,7 +4358,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,7 +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 +@@ -4584,7 +4586,6 @@ netdev_tx_t ieee80211_subif_start_xmit(s #ifdef CPTCFG_MAC80211_NSS_SUPPORT ieee80211_xmit_nss_fixup(skb, dev); #endif @@ -75,7 +75,7 @@ Signed-off-by: Tamizh Chelvam Raja if (likely(!is_multicast_ether_addr(eth->h_dest))) goto normal; -@@ -4714,7 +4715,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4731,7 +4732,7 @@ static void ieee80211_8023_xmit(struct i } } @@ -84,7 +84,7 @@ Signed-off-by: Tamizh Chelvam Raja if (!skb) return; -@@ -4839,6 +4840,7 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4856,6 +4857,7 @@ void ieee80211_8023_xmit_ap(struct ieee8 netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, struct net_device *dev) { @@ -92,7 +92,7 @@ Signed-off-by: Tamizh Chelvam Raja 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: +@@ -4890,9 +4892,10 @@ out: } return NETDEV_TX_OK; @@ -107,7 +107,7 @@ Signed-off-by: Tamizh Chelvam Raja 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 +@@ -2251,6 +2251,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/ath11k_nss/829-mac80211-fix-mesh-ping-issue.patch b/package/kernel/mac80211/patches/ath11k_nss/829-mac80211-fix-mesh-ping-issue.patch index 7043ecb079061a..535b5d1833757b 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/829-mac80211-fix-mesh-ping-issue.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/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_ +@@ -4746,16 +4746,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 +@@ -4978,10 +4976,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 +@@ -5031,37 +5026,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 +@@ -5099,30 +5063,6 @@ static bool ieee80211_invoke_fast_rx(str return true; } diff --git a/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch b/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch index 12feacda8555f7..d6d0af9c6245de 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch @@ -56,7 +56,7 @@ 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 +@@ -9412,7 +9412,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 +65,7 @@ enum nl80211_commands cmd, u8 count, u64 color_bitmap); -@@ -9238,9 +9238,9 @@ int cfg80211_bss_color_notify(struct net +@@ -9422,9 +9422,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 +77,7 @@ 0, color_bitmap); } -@@ -9254,7 +9254,7 @@ static inline int cfg80211_obss_color_co +@@ -9438,7 +9438,7 @@ static inline int cfg80211_obss_color_co static inline int cfg80211_color_change_started_notify(struct net_device *dev, u8 count) { @@ -86,7 +86,7 @@ count, 0); } -@@ -9266,7 +9266,7 @@ static inline int cfg80211_color_change_ +@@ -9450,7 +9450,7 @@ static inline int cfg80211_color_change_ */ static inline int cfg80211_color_change_aborted_notify(struct net_device *dev) { @@ -95,7 +95,7 @@ 0, 0); } -@@ -9278,7 +9278,7 @@ static inline int cfg80211_color_change_ +@@ -9462,7 +9462,7 @@ static inline int cfg80211_color_change_ */ static inline int cfg80211_color_change_notify(struct net_device *dev) { @@ -106,7 +106,7 @@ } --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -4777,7 +4777,7 @@ void ieee80211_color_collision_detection +@@ -4793,7 +4793,7 @@ void ieee80211_color_collision_detection struct ieee80211_sub_if_data *sdata = link->sdata; sdata_lock(sdata); 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/ath11k_nss/902-000-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch index 7dc88faed71f9f..7bf1937047e98b 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/ath11k_nss/902-000-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 +@@ -5134,6 +5134,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); @@ -91,7 +91,7 @@ Signed-off-by: Sathishkumar Muruganandam case NL80211_IFTYPE_STATION: return true; default: -@@ -1014,7 +1018,8 @@ static void ieee80211_set_vif_encap_ops( +@@ -1015,7 +1019,8 @@ static void ieee80211_set_vif_encap_ops( struct ieee80211_sub_if_data *bss = sdata; bool enabled; @@ -101,7 +101,7 @@ Signed-off-by: Sathishkumar Muruganandam if (!sdata->bss) return; -@@ -1359,10 +1364,17 @@ int ieee80211_do_open(struct wireless_de +@@ -1360,10 +1365,17 @@ int ieee80211_do_open(struct wireless_de switch (sdata->vif.type) { case NL80211_IFTYPE_AP_VLAN: @@ -137,7 +137,7 @@ 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 +@@ -4742,7 +4742,8 @@ static void ieee80211_8023_xmit(struct i info->flags |= info_flags; info->hw_queue = sdata->vif.hw_queue[queue]; 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/ath11k_nss/902-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch index 47146c459e796e..cb04a47e0a0409 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/ath11k_nss/902-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch @@ -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 +@@ -458,13 +474,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 +@@ -588,11 +597,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_ +@@ -632,28 +869,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 +@@ -1362,7 +1587,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 +@@ -1376,9 +1601,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: +@@ -1451,8 +1677,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 +@@ -1509,17 +1736,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: +@@ -1538,6 +1771,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 +@@ -1931,7 +2357,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 +@@ -1985,7 +2411,8 @@ static int ath11k_nss_stats_cfg(struct a status = nss_wifili_tx_msg(ar->nss.ctx, wlmsg); if (status != NSS_TX_SUCCESS) { 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/ath11k_nss/902-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch index 33eb5d2001db91..9f51d50ad2e289 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/902-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/902-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 { +@@ -2111,6 +2111,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 { +@@ -2130,6 +2132,7 @@ struct ieee80211_key_conf { u8 hw_key_idx; s8 keyidx; u16 flags; 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/ath11k_nss/902-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch index 0e6c0d92d2abde..8149cd4027d907 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/ath11k_nss/902-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 { +@@ -635,6 +635,7 @@ struct ath11k { struct ath11k_pdev_wmi *wmi; #ifdef CPTCFG_ATH11K_NSS_SUPPORT struct ath11k_nss nss; @@ -34,7 +34,7 @@ Signed-off-by: Sathishkumar Muruganandam #endif struct ath11k_pdev_dp dp; u8 mac_addr[ETH_ALEN]; -@@ -1042,6 +1043,8 @@ struct ath11k_base { +@@ -1043,6 +1044,8 @@ struct ath11k_base { u32 rx_hash; bool stats_disable; @@ -110,7 +110,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 +@@ -477,7 +477,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 diff --git a/package/kernel/mac80211/patches/ath11k_nss/902-020-ath11k-add-btcoex-config.patch b/package/kernel/mac80211/patches/ath11k_nss/902-020-ath11k-add-btcoex-config.patch index 495245f9662462..5b8b6a8799002e 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/902-020-ath11k-add-btcoex-config.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/902-020-ath11k-add-btcoex-config.patch @@ -12,7 +12,7 @@ ath11k-$(CPTCFG_NL80211_TESTMODE) += testmode.o --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -637,6 +637,16 @@ struct ath11k_per_peer_tx_stats { +@@ -627,6 +627,16 @@ struct ath11k_per_peer_tx_stats { #define ATH11K_FLUSH_TIMEOUT (5 * HZ) #define ATH11K_VDEV_DELETE_TIMEOUT_HZ (5 * HZ) @@ -29,7 +29,7 @@ struct ath11k { struct ath11k_base *ab; struct ath11k_pdev *pdev; -@@ -760,6 +770,8 @@ struct ath11k { +@@ -750,6 +760,8 @@ struct ath11k { struct ath11k_per_peer_tx_stats cached_stats; u32 last_ppdu_id; u32 cached_ppdu_id; @@ -56,7 +56,7 @@ #include "nss.h" #define CHAN2G(_channel, _freq, _flags) { \ -@@ -9286,6 +9288,91 @@ err_fallback: +@@ -9284,6 +9286,91 @@ err_fallback: return 0; } @@ -148,7 +148,7 @@ static const struct ieee80211_ops ath11k_ops = { .tx = ath11k_mac_op_tx, .wake_tx_queue = ieee80211_handle_wake_tx_queue, -@@ -9525,6 +9612,56 @@ static int ath11k_mac_setup_iface_combin +@@ -9523,6 +9610,56 @@ static int ath11k_mac_setup_iface_combin return 0; } @@ -213,7 +213,7 @@ if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) { ar->hw->netdev_features = NETIF_F_HW_CSUM; -@@ -9948,6 +10086,7 @@ int ath11k_mac_allocate(struct ath11k_ba +@@ -9951,6 +10089,7 @@ int ath11k_mac_allocate(struct ath11k_ba */ ath11k_wmi_pdev_attach(ab, i); 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 index 52037816a113b1..88c6d85aff1e02 100644 --- 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 @@ -88,7 +88,7 @@ kfree(arsta->rx_stats); arsta->rx_stats = NULL; -@@ -6566,6 +6602,7 @@ static void ath11k_mac_op_stop(struct ie +@@ -6564,6 +6600,7 @@ static void ath11k_mac_op_stop(struct ie clear_bit(ATH11K_CAC_RUNNING, &ar->dev_flags); ar->state = ATH11K_STATE_OFF; @@ -96,7 +96,7 @@ mutex_unlock(&ar->conf_mutex); cancel_delayed_work_sync(&ar->scan.timeout); -@@ -6973,7 +7010,6 @@ static int ath11k_mac_op_add_interface(s +@@ -6971,7 +7008,6 @@ static int ath11k_mac_op_add_interface(s arvif->vdev_id, ret); goto err; } @@ -104,7 +104,7 @@ 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 +@@ -7118,6 +7154,10 @@ static int ath11k_mac_op_add_interface(s ret); } @@ -115,7 +115,7 @@ mutex_unlock(&ar->conf_mutex); return 0; -@@ -7227,6 +7267,7 @@ err_vdev_del: +@@ -7225,6 +7265,7 @@ err_vdev_del: /* Recalc txpower for remaining vdev */ ath11k_mac_txpower_recalc(ar); diff --git a/package/kernel/mac80211/patches/ath11k_nss/902-069-ath11k-add-HE-stats-in-peer-stats.patch b/package/kernel/mac80211/patches/ath11k_nss/902-069-ath11k-add-HE-stats-in-peer-stats.patch index 4831424fa40810..7bdd430721203f 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/902-069-ath11k-add-HE-stats-in-peer-stats.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/902-069-ath11k-add-HE-stats-in-peer-stats.patch @@ -21,9 +21,9 @@ Signed-off-by: Miles Hu #include "wow.h" +#include "rx_desc.h" #include "nss.h" + #include "vendor.h" - #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) -@@ -476,6 +477,8 @@ struct ath11k_htt_data_stats { +@@ -478,6 +479,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 { +@@ -485,6 +488,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 { +@@ -617,11 +623,16 @@ struct ath11k_per_peer_tx_stats { u32 succ_bytes; u32 retry_bytes; u32 failed_bytes; 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/ath11k_nss/903-002-ath11k-add-support-for-ext-vdev-in-NSS-for-AP_VLAN-vif-handling.patch index 6f5fffe596172b..9fe0a189558564 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/ath11k_nss/903-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 +@@ -364,6 +364,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 +@@ -597,8 +601,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 +@@ -620,19 +625,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 +@@ -676,7 +684,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_ +@@ -697,8 +706,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 +@@ -765,6 +774,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 +@@ -820,10 +830,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_ +@@ -886,6 +897,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 +@@ -908,10 +981,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 +@@ -1252,6 +1331,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 +@@ -1283,6 +1363,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 +@@ -1292,6 +1378,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 +@@ -1319,11 +1406,362 @@ int ath11k_nss_vdev_down(struct ath11k_v } ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss vdev down tx msg success\n"); @@ -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: +@@ -1417,22 +1855,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 +@@ -1504,13 +1942,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 +@@ -1814,8 +2252,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 +@@ -1860,8 +2298,8 @@ int ath11k_nss_update_wds_peer(struct at } ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, 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/ath11k_nss/903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch index de7bc77ef53456..bfc938986e149b 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/ath11k_nss/903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch @@ -33,7 +33,7 @@ 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 { +@@ -387,9 +387,8 @@ struct ath11k_vif { #endif /* CPTCFG_ATH11K_DEBUGFS */ struct ath11k_mgmt_frame_stats mgmt_stats; @@ -184,7 +184,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( +@@ -5314,9 +5415,32 @@ static void ath11k_mac_op_sta_set_4addr( struct ieee80211_sta *sta, bool enabled) { struct ath11k *ar = hw->priv; @@ -217,7 +217,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 +@@ -6708,6 +6832,9 @@ static int ath11k_mac_op_update_vif_offl u32 param_id, param_value; int ret; @@ -227,7 +227,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 +@@ -6928,7 +7055,8 @@ static int ath11k_mac_op_add_interface(s goto err; } @@ -237,7 +237,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 +@@ -6948,6 +7076,28 @@ static int ath11k_mac_op_add_interface(s arvif->vif = vif; INIT_LIST_HEAD(&arvif->list); @@ -266,7 +266,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 +@@ -6977,6 +7127,7 @@ static int ath11k_mac_op_add_interface(s fallthrough; case NL80211_IFTYPE_AP: arvif->vdev_type = WMI_VDEV_TYPE_AP; @@ -274,7 +274,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 +@@ -7202,13 +7353,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 +307,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 +@@ -7225,6 +7393,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 +322,7 @@ Signed-off-by: Sathishkumar Muruganandam } ret = ath11k_mac_vdev_delete(ar, arvif); -@@ -7230,8 +7406,7 @@ err_vdev_del: +@@ -7269,8 +7445,7 @@ err_vdev_del: ath11k_debugfs_remove_interface(arvif); @@ -332,7 +332,7 @@ Signed-off-by: Sathishkumar Muruganandam mutex_unlock(&ar->conf_mutex); } -@@ -7291,16 +7466,17 @@ static int ath11k_mac_op_ampdu_action(st +@@ -7330,16 +7505,17 @@ static int ath11k_mac_op_ampdu_action(st struct ieee80211_ampdu_params *params) { struct ath11k *ar = hw->priv; @@ -352,7 +352,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 +@@ -8862,6 +9038,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 +360,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 +@@ -8918,7 +9095,8 @@ static void ath11k_mac_op_sta_statistics ATH11K_DEFAULT_NOISE_FLOOR; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); @@ -372,7 +372,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 { +@@ -5075,6 +5075,8 @@ enum wmi_vdev_subtype { WMI_VDEV_SUBTYPE_MESH_11S, }; @@ -521,7 +521,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 +@@ -162,7 +162,10 @@ static void ath11k_nss_get_peer_stats(st peer->nss.nss_stats->tx_failed += tx_dropped; @@ -533,7 +533,7 @@ 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 +@@ -172,7 +175,10 @@ static void ath11k_nss_get_peer_stats(st pstats->rx.err.decrypt_err; peer->nss.nss_stats->rx_dropped += rx_dropped; @@ -545,7 +545,7 @@ Signed-off-by: Sathishkumar Muruganandam spin_unlock_bh(&ab->base_lock); rcu_read_unlock(); -@@ -1040,6 +1046,9 @@ int ath11k_nss_vdev_set_cmd(struct ath11 +@@ -1038,6 +1044,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; 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/ath11k_nss/904-002-ath11k-extend-ext-vdev-in-NSS-for-dynamic-VLAN-handling.patch index 14274b6a72680a..93adefacb0de44 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/ath11k_nss/904-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( +@@ -1568,14 +1568,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 +@@ -1603,7 +1600,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 +@@ -1612,14 +1610,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 +@@ -1628,8 +1631,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 +@@ -1658,7 +1661,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: +@@ -1771,6 +1774,86 @@ free: return ret; } 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/ath11k_nss/904-003-ath11k-add-dynamic-VLAN-support-in-NSS-offload.patch index 2361523d394ac4..850bf770d3bd1e 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/904-003-ath11k-add-dynamic-VLAN-support-in-NSS-offload.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/904-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 { +@@ -327,6 +332,20 @@ struct ath11k_mgmt_frame_stats { u32 tx_compl_fail[ATH11K_STATS_MGMT_FRM_TYPE_MAX]; }; @@ -69,7 +69,7 @@ Signed-off-by: Sathishkumar Muruganandam struct ath11k_vif { u32 vdev_id; enum wmi_vdev_type vdev_type; -@@ -387,6 +406,11 @@ struct ath11k_vif { +@@ -389,6 +408,11 @@ struct ath11k_vif { struct ath11k_mgmt_frame_stats mgmt_stats; struct arvif_nss nss; struct list_head ap_vlan_arvifs; @@ -354,7 +354,7 @@ Signed-off-by: Sathishkumar Muruganandam switch (key->cipher) { case WLAN_CIPHER_SUITE_TKIP: -@@ -5186,6 +5360,33 @@ static u32 ath11k_mac_ieee80211_sta_bw_t +@@ -5219,6 +5393,33 @@ static u32 ath11k_mac_ieee80211_sta_bw_t return bw; } @@ -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 +@@ -5342,6 +5543,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 +@@ -7080,7 +7309,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 +@@ -7093,6 +7322,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 +@@ -7117,6 +7347,20 @@ static int ath11k_mac_op_add_interface(s arvif->vdev_id = bit; arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE; @@ -461,16 +461,16 @@ 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 +@@ -7157,7 +7401,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); - goto err; + goto err_keyid; } - ar->num_created_vdevs++; -@@ -7281,7 +7525,7 @@ err_peer_del: + ath11k_dbg(ab, ATH11K_DBG_MAC, "vdev %pM created, vdev_id %d\n", +@@ -7319,7 +7563,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: +@@ -7330,6 +7574,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: +@@ -7427,6 +7673,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 +@@ -10154,8 +10401,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 +@@ -2033,6 +2033,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 +@@ -4307,6 +4308,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 +@@ -4529,6 +4531,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 { +@@ -3707,6 +3707,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 { +@@ -5852,6 +5853,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/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 index 86812a1830d817..fe2c45973cf6b0 100644 --- 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 @@ -25,7 +25,7 @@ Signed-off-by: Vasanthakumar Thiagarajan --- 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 +@@ -33,6 +33,30 @@ ath11k_nss_get_vdev_opmode(struct ath11k return ATH11K_NSS_OPMODE_UNKNOWN; } @@ -56,7 +56,7 @@ Signed-off-by: Vasanthakumar Thiagarajan 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 +@@ -292,6 +316,9 @@ void ath11k_nss_wifili_event_receive(str switch (msg_type) { case NSS_WIFILI_INIT_MSG: @@ -66,7 +66,7 @@ Signed-off-by: Vasanthakumar Thiagarajan 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 +@@ -300,7 +327,6 @@ void ath11k_nss_wifili_event_receive(str ab->nss.response = response; complete(&ab->nss.complete); break; @@ -74,7 +74,7 @@ Signed-off-by: Vasanthakumar Thiagarajan case NSS_WIFILI_PEER_CREATE_MSG: if (response != NSS_CMN_RESPONSE_EMSG) break; -@@ -463,7 +489,9 @@ ath11k_nss_wifili_ext_callback_fn(struct +@@ -461,7 +487,9 @@ ath11k_nss_wifili_ext_callback_fn(struct ath11k_nss_process_mic_error(ab, skb); break; default: 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 index 734b6fb8c4b160..fc64af54958996 100644 --- 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 @@ -141,7 +141,7 @@ Signed-off-by: Maharaja Kennadyrajan } --- 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 +@@ -2145,6 +2145,8 @@ int ath11k_core_pre_init(struct ath11k_b if (nss_offload) ab->nss.stats_enabled = 1; @@ -152,7 +152,7 @@ Signed-off-by: Maharaja Kennadyrajan 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 { +@@ -939,6 +939,23 @@ struct ath11k_num_vdevs_peers { u32 num_peers; }; @@ -176,7 +176,7 @@ Signed-off-by: Maharaja Kennadyrajan /* 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 { +@@ -1028,6 +1045,7 @@ struct ath11k_base { enum ath11k_dfs_region dfs_region; #ifdef CPTCFG_ATH11K_DEBUGFS struct dentry *debugfs_soc; @@ -184,7 +184,7 @@ Signed-off-by: Maharaja Kennadyrajan #endif struct ath11k_soc_dp_stats soc_stats; -@@ -1085,6 +1103,7 @@ struct ath11k_base { +@@ -1094,6 +1112,7 @@ struct ath11k_base { atomic_t num_max_allowed; struct ath11k_num_vdevs_peers *num_vdevs_peers; @@ -351,7 +351,7 @@ Signed-off-by: Maharaja Kennadyrajan return 0; } -@@ -1742,6 +1852,8 @@ static ssize_t ath11k_dump_mgmt_stats(st +@@ -1739,6 +1849,8 @@ static ssize_t ath11k_dump_mgmt_stats(st if (!buf) return -ENOMEM; @@ -360,7 +360,7 @@ Signed-off-by: Maharaja Kennadyrajan mutex_lock(&ar->conf_mutex); spin_lock_bh(&ar->data_lock); -@@ -1792,6 +1904,9 @@ static ssize_t ath11k_dump_mgmt_stats(st +@@ -1789,6 +1901,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); @@ -654,7 +654,7 @@ Signed-off-by: Maharaja Kennadyrajan mutex_unlock(&ar->conf_mutex); -@@ -8113,6 +8124,8 @@ ath11k_mac_update_active_vif_chan(struct +@@ -8152,6 +8163,8 @@ ath11k_mac_update_active_vif_chan(struct if (!arg.vifs) return; @@ -663,7 +663,7 @@ Signed-off-by: Maharaja Kennadyrajan 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 +@@ -8159,6 +8172,8 @@ ath11k_mac_update_active_vif_chan(struct ath11k_mac_update_vif_chan(ar, arg.vifs, arg.n_vifs); @@ -674,7 +674,7 @@ Signed-off-by: Maharaja Kennadyrajan --- 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 +@@ -1061,6 +1061,9 @@ int ath11k_nss_vdev_set_cmd(struct ath11 default: return -EINVAL; } @@ -684,7 +684,7 @@ Signed-off-by: Maharaja Kennadyrajan /* TODO: Convert to function for conversion in case of many * such commands */ -@@ -1082,6 +1085,7 @@ int ath11k_nss_vdev_set_cmd(struct ath11 +@@ -1091,6 +1094,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: @@ -692,7 +692,7 @@ Signed-off-by: Maharaja Kennadyrajan kfree(vdev_msg); return status; } -@@ -1098,6 +1102,9 @@ static int ath11k_nss_vdev_configure(str +@@ -1107,6 +1111,9 @@ static int ath11k_nss_vdev_configure(str if (!vdev_msg) return -ENOMEM; @@ -702,7 +702,7 @@ Signed-off-by: Maharaja Kennadyrajan 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 +@@ -1142,6 +1149,8 @@ static int ath11k_nss_vdev_configure(str ret = 0; free: @@ -711,7 +711,7 @@ Signed-off-by: Maharaja Kennadyrajan kfree(vdev_msg); return ret; -@@ -1357,6 +1366,9 @@ int ath11k_nss_vdev_up(struct ath11k_vif +@@ -1366,6 +1375,9 @@ int ath11k_nss_vdev_up(struct ath11k_vif if (!vdev_msg) return -ENOMEM; @@ -721,7 +721,7 @@ Signed-off-by: Maharaja Kennadyrajan 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 +@@ -1390,6 +1402,8 @@ int ath11k_nss_vdev_up(struct ath11k_vif if (ap_vlan_arvif->nss.added) ath11k_nss_ext_vdev_up(ap_vlan_arvif); free: @@ -730,7 +730,7 @@ Signed-off-by: Maharaja Kennadyrajan kfree(vdev_msg); return ret; } -@@ -1404,6 +1418,8 @@ int ath11k_nss_vdev_down(struct ath11k_v +@@ -1413,6 +1427,8 @@ int ath11k_nss_vdev_down(struct ath11k_v if (!vdev_msg) return -ENOMEM; @@ -739,7 +739,7 @@ Signed-off-by: Maharaja Kennadyrajan 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 +@@ -1432,6 +1448,8 @@ int ath11k_nss_vdev_down(struct ath11k_v list) ath11k_nss_ext_vdev_down(ap_vlan_arvif); free: @@ -748,7 +748,7 @@ Signed-off-by: Maharaja Kennadyrajan kfree(vdev_msg); return ret; } -@@ -1875,6 +1893,9 @@ int ath11k_nss_set_peer_sec_type(struct +@@ -1884,6 +1902,9 @@ int ath11k_nss_set_peer_sec_type(struct if (!wlmsg) return -ENOMEM; @@ -758,7 +758,7 @@ Signed-off-by: Maharaja Kennadyrajan sec_msg = &wlmsg->msg.securitymsg; sec_msg->peer_id = peer->peer_id; -@@ -1906,6 +1927,8 @@ int ath11k_nss_set_peer_sec_type(struct +@@ -1915,6 +1936,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: @@ -767,7 +767,7 @@ Signed-off-by: Maharaja Kennadyrajan kfree(wlmsg); return status; } -@@ -2593,6 +2616,7 @@ static void ath11k_nss_tx_desc_mem_free( +@@ -2602,6 +2625,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; @@ -775,7 +775,7 @@ Signed-off-by: Maharaja Kennadyrajan } ath11k_dbg(ab, ATH11K_DBG_NSS, "allocated tx desc mem freed\n"); -@@ -2624,6 +2648,8 @@ static int ath11k_nss_tx_desc_mem_alloc( +@@ -2633,6 +2657,8 @@ static int ath11k_nss_tx_desc_mem_alloc( ab->nss.tx_desc_size[curr_page_idx] = alloc_size; curr_page_idx++; @@ -784,7 +784,7 @@ Signed-off-by: Maharaja Kennadyrajan 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 +@@ -2804,6 +2830,8 @@ static int ath11k_nss_init(struct ath11k if (!wlmsg) return -ENOMEM; @@ -793,7 +793,7 @@ Signed-off-by: Maharaja Kennadyrajan wim = &wlmsg->msg.init; wim->target_type = target_type; -@@ -2914,6 +2942,7 @@ unregister: +@@ -2923,6 +2951,7 @@ unregister: nss_unregister_wifili_if(ab->nss.if_num); free: ath11k_nss_tx_desc_mem_free(ab); @@ -801,7 +801,7 @@ Signed-off-by: Maharaja Kennadyrajan kfree(wlmsg); return -EINVAL; } -@@ -3031,6 +3060,8 @@ int ath11k_nss_pdev_init(struct ath11k_b +@@ -3040,6 +3069,8 @@ int ath11k_nss_pdev_init(struct ath11k_b goto unregister; } @@ -810,7 +810,7 @@ Signed-off-by: Maharaja Kennadyrajan pdevmsg = &wlmsg->msg.pdevmsg; pdevmsg->radio_id = radio_id; -@@ -3077,6 +3108,8 @@ int ath11k_nss_pdev_init(struct ath11k_b +@@ -3086,6 +3117,8 @@ int ath11k_nss_pdev_init(struct ath11k_b goto free; } @@ -819,7 +819,7 @@ Signed-off-by: Maharaja Kennadyrajan kfree(wlmsg); /* Disable nss sojourn stats by default */ -@@ -3095,6 +3128,7 @@ int ath11k_nss_pdev_init(struct ath11k_b +@@ -3104,6 +3137,7 @@ int ath11k_nss_pdev_init(struct ath11k_b return 0; free: @@ -827,7 +827,7 @@ Signed-off-by: Maharaja Kennadyrajan kfree(wlmsg); unregister: nss_unregister_wifili_radio_if(ar->nss.if_num); -@@ -3117,6 +3151,8 @@ int ath11k_nss_start(struct ath11k_base +@@ -3126,6 +3160,8 @@ int ath11k_nss_start(struct ath11k_base if (!wlmsg) return -ENOMEM; @@ -836,7 +836,7 @@ Signed-off-by: Maharaja Kennadyrajan 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 +@@ -3166,6 +3202,7 @@ int ath11k_nss_start(struct ath11k_base ath11k_dbg(ab, ATH11K_DBG_NSS, "nss start success\n"); free: @@ -844,7 +844,7 @@ Signed-off-by: Maharaja Kennadyrajan kfree(wlmsg); return ret; } -@@ -3175,6 +3212,8 @@ static void ath11k_nss_reset(struct ath1 +@@ -3184,6 +3221,8 @@ static void ath11k_nss_reset(struct ath1 return; } @@ -853,7 +853,7 @@ Signed-off-by: Maharaja Kennadyrajan 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 +@@ -3222,6 +3261,7 @@ static void ath11k_nss_reset(struct ath1 nss_unregister_wifili_if(ab->nss.if_num); free: @@ -861,7 +861,7 @@ Signed-off-by: Maharaja Kennadyrajan kfree(wlmsg); } -@@ -3228,6 +3268,8 @@ static int ath11k_nss_stop(struct ath11k +@@ -3237,6 +3277,8 @@ static int ath11k_nss_stop(struct ath11k if (!wlmsg) return -ENOMEM; @@ -870,7 +870,7 @@ Signed-off-by: Maharaja Kennadyrajan 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 +@@ -3276,6 +3318,8 @@ static int ath11k_nss_stop(struct ath11k /* NSS Stop success */ ret = 0; free: @@ -879,7 +879,7 @@ Signed-off-by: Maharaja Kennadyrajan kfree(wlmsg); return ret; } -@@ -3292,6 +3336,8 @@ int ath11k_nss_pdev_deinit(struct ath11k +@@ -3301,6 +3345,8 @@ int ath11k_nss_pdev_deinit(struct ath11k if (!wlmsg) return -ENOMEM; @@ -888,7 +888,7 @@ Signed-off-by: Maharaja Kennadyrajan deinit = &wlmsg->msg.pdevdeinit; deinit->ifnum = radio_id; -@@ -3337,6 +3383,7 @@ int ath11k_nss_pdev_deinit(struct ath11k +@@ -3346,6 +3392,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: @@ -928,7 +928,7 @@ Signed-off-by: Maharaja Kennadyrajan 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 +@@ -7346,6 +7348,7 @@ static void ath11k_wmi_htc_tx_complete(s u8 eid; eid = ATH11K_SKB_CB(skb)->eid; @@ -936,7 +936,7 @@ Signed-off-by: Maharaja Kennadyrajan dev_kfree_skb(skb); if (eid >= ATH11K_HTC_EP_COUNT) -@@ -9107,6 +9110,7 @@ static void ath11k_wmi_tlv_op_rx(struct +@@ -9139,6 +9142,7 @@ static void ath11k_wmi_tlv_op_rx(struct } out: diff --git a/package/kernel/mac80211/patches/ath11k_nss/907-068-ath11k-add-rx-histogram-stats.patch b/package/kernel/mac80211/patches/ath11k_nss/907-068-ath11k-add-rx-histogram-stats.patch index d3ffa5bd8da8e7..c90cde7eef6619 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/907-068-ath11k-add-rx-histogram-stats.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/907-068-ath11k-add-rx-histogram-stats.patch @@ -214,7 +214,7 @@ Signed-off-by: Manikanta Pubbisetty rx_stats->dcm_count, rx_stats->ru_alloc_cnt[0], --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -3400,10 +3400,43 @@ exit: +@@ -3233,10 +3233,43 @@ exit: return total_msdu_reaped; } @@ -258,7 +258,7 @@ Signed-off-by: Manikanta Pubbisetty u32 num_msdu; int i; -@@ -3413,6 +3446,8 @@ static void ath11k_dp_rx_update_peer_sta +@@ -3246,6 +3279,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 +267,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 +@@ -3262,18 +3297,6 @@ static void ath11k_dp_rx_update_peer_sta ppdu_info->tid = IEEE80211_NUM_TIDS; } @@ -286,7 +286,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 +@@ -3302,8 +3325,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 +295,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 +@@ -3312,6 +3333,52 @@ static void ath11k_dp_rx_update_peer_sta rx_stats->rx_duration += ppdu_info->rx_duration; arsta->rx_duration = rx_stats->rx_duration; @@ -598,7 +598,7 @@ 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 { +@@ -313,6 +313,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); diff --git a/package/kernel/mac80211/patches/ath11k_nss/907-ath11k-remove-error-on-soc-debugfs-fail.patch b/package/kernel/mac80211/patches/ath11k_nss/907-ath11k-remove-error-on-soc-debugfs-fail.patch index b47785828a2bd9..1533203bec17d5 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/907-ath11k-remove-error-on-soc-debugfs-fail.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/907-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: +@@ -2240,5 +2240,17 @@ err_sc_free: } EXPORT_SYMBOL(ath11k_core_alloc); @@ -97,7 +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 +@@ -1929,6 +1947,9 @@ void ath11k_debugfs_unregister(struct at kfree(dbr_debug); ar->debug.dbr_debug[i] = NULL; } @@ -107,7 +107,7 @@ Signed-off-by: Anilkumar Kolli } static ssize_t ath11k_write_twt_add_dialog(struct file *file, -@@ -2294,6 +2315,9 @@ int ath11k_debugfs_register(struct ath11 +@@ -2229,6 +2250,9 @@ int ath11k_debugfs_register(struct ath11 char pdev_name[10]; char buf[100] = {0}; diff --git a/package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch b/package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch index 47c6b7ec3e5ae2..c058eeaad29a65 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/908-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 +@@ -637,7 +637,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 +@@ -673,8 +673,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 +@@ -718,8 +716,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_ +@@ -741,7 +738,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,7 +53,7 @@ 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 +@@ -804,14 +801,16 @@ 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; @@ -130,7 +130,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 } static void -@@ -1049,6 +1083,9 @@ int ath11k_nss_vdev_set_cmd(struct ath11 +@@ -1058,6 +1092,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 +140,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 default: return -EINVAL; } -@@ -1299,12 +1336,31 @@ int ath11k_nss_vdev_create(struct ath11k +@@ -1308,12 +1345,31 @@ int ath11k_nss_vdev_create(struct ath11k goto free_vdev; switch (arvif->vif->type) { @@ -173,7 +173,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 break; default: ret = -ENOTSUPP; -@@ -1463,7 +1519,7 @@ int ath11k_nss_ext_vdev_cfg_wds_peer(str +@@ -1472,7 +1528,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; @@ -182,7 +182,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 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( +@@ -1596,7 +1652,6 @@ static int ath11k_nss_ext_vdev_register( { struct ath11k *ar = arvif->ar; struct ath11k_base *ab = ar->ab; @@ -190,7 +190,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( +@@ -1610,7 +1665,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", diff --git a/package/kernel/mac80211/patches/ath11k_nss/908-330-ath11k-sync-wds_ast_entry-updates.patch b/package/kernel/mac80211/patches/ath11k_nss/908-330-ath11k-sync-wds_ast_entry-updates.patch index 6ebd709e7d3298..f1cbcfc9321e6b 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/908-330-ath11k-sync-wds_ast_entry-updates.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/908-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 +@@ -2210,6 +2210,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 +@@ -2223,6 +2224,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); @@ -83,7 +83,7 @@ Signed-off-by: Rameshkumar Sundaram #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) -@@ -1131,6 +1132,11 @@ struct ath11k_base { +@@ -1130,6 +1131,11 @@ struct ath11k_base { u32 max_ast_index; u32 num_ast_entries; @@ -97,7 +97,7 @@ Signed-off-by: Rameshkumar Sundaram }; --- 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 +@@ -678,8 +678,9 @@ static void ath11k_nss_wds_type_rx(struc spin_unlock_bh(&ab->base_lock); } @@ -108,7 +108,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 +@@ -706,7 +707,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 +117,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_ +@@ -741,7 +742,7 @@ static void ath11k_nss_vdev_spl_receive_ addr4_valid, peer_id); break; case NSS_WIFI_VDEV_WDS_TYPE_MEC: @@ -126,7 +126,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 +@@ -2410,11 +2411,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 +139,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: +@@ -2537,7 +2534,7 @@ msg_free: return ret; } @@ -148,7 +148,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 +@@ -2555,8 +2552,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 +161,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 +@@ -242,8 +242,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 +172,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 +@@ -342,8 +342,8 @@ static inline int ath11k_nss_map_wds_pee return 0; } 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/ath11k_nss/908-362-ath11k-fix-incorrect-ast-index-assignment-for-wds-peer.patch index f734c5aea8d876..9111724a8344be 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/ath11k_nss/908-362-ath11k-fix-incorrect-ast-index-assignment-for-wds-peer.patch @@ -19,7 +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 +@@ -803,8 +803,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; @@ -28,7 +28,7 @@ Signed-off-by: Raj Kumar Bhagat struct ath11k_vif *arvif; struct ath11k_base *ab; struct ath11k_skb_rxcb *rxcb; -@@ -2487,13 +2485,14 @@ msg_free: +@@ -2485,13 +2483,14 @@ msg_free: } int ath11k_nss_map_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, @@ -44,7 +44,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 +@@ -2501,7 +2500,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; diff --git a/package/kernel/mac80211/patches/ath11k_nss/911-244-ath11k-dp-tx-perf.patch b/package/kernel/mac80211/patches/ath11k_nss/911-244-ath11k-dp-tx-perf.patch index 79906c8d3a4ab3..e5a9c7a59b76cd 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/911-244-ath11k-dp-tx-perf.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/911-244-ath11k-dp-tx-perf.patch @@ -464,7 +464,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 +@@ -835,10 +835,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]); @@ -506,7 +506,7 @@ Signed-off-by: P Praneesh }, { .name = "qca6390 hw2.0", -@@ -384,6 +384,8 @@ static struct ath11k_hw_params ath11k_hw +@@ -384,6 +385,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,7 +515,7 @@ Signed-off-by: P Praneesh }, { .name = "wcn6855 hw2.0", -@@ -2147,6 +2149,9 @@ int ath11k_core_pre_init(struct ath11k_b +@@ -2147,6 +2150,9 @@ int ath11k_core_pre_init(struct ath11k_b ab->enable_memory_stats = ATH11K_DEBUG_ENABLE_MEMORY_STATS; 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/ath11k_nss/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch index 90f335efbca6fb..fcf9930f222fbd 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/911-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 { +@@ -935,6 +935,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]; 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/ath11k_nss/913-341-ath11k-fix-support-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch index a1b885c8b50e5a..425bb3c70e9693 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/ath11k_nss/913-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 +@@ -1840,6 +1840,11 @@ static int ath11k_core_reconfigure_on_cr clear_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags); From 948f30390f7b4288191633a9152148d3047954ae Mon Sep 17 00:00:00 2001 From: Qosmio Date: Wed, 17 Jan 2024 16:42:17 -0500 Subject: [PATCH 094/225] ath11k_nss: fix build for 256/1G mem, and ath10k --- .../199-004-ath10k-fixup-nss-compile.patch | 19 + ...207-ath11k-Enable-256_512MB-profiles.patch | 2 +- .../245-revert-dev-sw-netstats-txrx-add.patch | 145 -- ...00-mac80211-nss-mesh-offload-support.patch | 16 +- ...-0005-mac80211-simple-tx-for-AP-mode.patch | 4 +- .../336-mac80211-Mesh-Fast-rx-support.patch | 10 +- ...mac80211-fix-unconditional-sta-usage.patch | 4 +- ...unused-RX_FLAGS-from-mac80211_rx_fla.patch | 85 - .../640-006-mac80211-add-eht-radiotap.patch | 506 ------ ...ncapsulation-of-EAPOL-frames-if-OFFL.patch | 30 +- ...interface-combination-advertisement-.patch | 1594 ----------------- ...-the-frame-to-driver-tx-ops-directly.patch | 4 +- ...se-HW-checksum-offload-only-for-ethm.patch | 16 +- .../829-mac80211-fix-mesh-ping-issue.patch | 8 +- .../patches/ath11k_nss/900-fix-build.patch | 10 +- ...N-iftype-support-on-NSS-offload-case.patch | 6 +- ...-dynamic-VLAN-support-on-NSS-offload.patch | 4 +- 17 files changed, 76 insertions(+), 2387 deletions(-) create mode 100644 package/kernel/mac80211/patches/ath11k_nss/199-004-ath10k-fixup-nss-compile.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/245-revert-dev-sw-netstats-txrx-add.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/640-006-mac80211-add-eht-radiotap.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/675-01-cfg80211-Extend-interface-combination-advertisement-.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-004-ath10k-fixup-nss-compile.patch b/package/kernel/mac80211/patches/ath11k_nss/199-004-ath10k-fixup-nss-compile.patch new file mode 100644 index 00000000000000..d413514144f161 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/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/207-ath11k-Enable-256_512MB-profiles.patch b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch index f4ee9048669956..3d88021c7c8e40 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch @@ -372,7 +372,7 @@ Signed-off-by: Ramya Gnanasekar 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; ++ 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", 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 6f7c1aadd95b64..00000000000000 --- 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/300-mac80211-nss-mesh-offload-support.patch b/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch index c07f9ef9fa94e4..e0b275fc5af664 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch @@ -1173,7 +1173,7 @@ 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 +@@ -2621,6 +2621,9 @@ static struct sk_buff *ieee80211_build_h info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; #endif @@ -1183,7 +1183,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 +@@ -2691,6 +2694,13 @@ static struct sk_buff *ieee80211_build_h break; #ifdef CPTCFG_MAC80211_MESH case NL80211_IFTYPE_MESH_POINT: @@ -1197,7 +1197,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 +@@ -2954,10 +2964,10 @@ static struct sk_buff *ieee80211_build_h skb_reset_mac_header(skb); @@ -1212,7 +1212,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 +@@ -4272,6 +4282,7 @@ void __ieee80211_subif_start_xmit(struct struct sk_buff *next; int len = skb->len; struct ieee80211_key *key = NULL; @@ -1220,20 +1220,20 @@ Signed-off-by: Gautham Kumar Senthilkumaran struct ieee80211_sub_if_data *ap_sdata; if (unlikely(!ieee80211_sdata_running(sdata) || skb->len < ETH_HLEN)) { -@@ -4358,9 +4369,15 @@ void __ieee80211_subif_start_xmit(struct +@@ -4346,9 +4357,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); + if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { -+ if (sta) ++ if (sta) + 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-0005-mac80211-simple-tx-for-AP-mode.patch b/package/kernel/mac80211/patches/ath11k_nss/335-0005-mac80211-simple-tx-for-AP-mode.patch index 4935be7bf106b2..0fbdc2a7d7cdd1 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/335-0005-mac80211-simple-tx-for-AP-mode.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/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 -@@ -4765,6 +4765,70 @@ out_free: +@@ -4753,6 +4753,70 @@ out_free: kfree_skb(skb); } @@ -85,7 +85,7 @@ Signed-off-by: Aloka Dixit netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, struct net_device *dev) { -@@ -4804,6 +4868,11 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4792,6 +4856,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/ath11k_nss/336-mac80211-Mesh-Fast-rx-support.patch index d29a05f13943bf..70bbee69332044 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/336-mac80211-Mesh-Fast-rx-support.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/336-mac80211-Mesh-Fast-rx-support.patch @@ -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_ +@@ -4643,10 +4643,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_ +@@ -4687,7 +4692,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 +@@ -4870,6 +4875,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 +@@ -4919,6 +4928,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 +@@ -4956,9 +4996,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/ath11k_nss/342-mac80211-fix-unconditional-sta-usage.patch index 3efff7ea87bebc..bc7a55273daf58 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/342-mac80211-fix-unconditional-sta-usage.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/342-mac80211-fix-unconditional-sta-usage.patch @@ -33,7 +33,7 @@ Signed-off-by: Tamizh Chelvam --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4742,12 +4742,12 @@ static void ieee80211_8023_xmit(struct i +@@ -4730,12 +4730,12 @@ static void ieee80211_8023_xmit(struct i if (unlikely(skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS && @@ -42,7 +42,7 @@ Signed-off-by: Tamizh Chelvam info->ack_frame_id = ieee80211_store_ack_skb(local, skb, &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/ath11k_nss/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch b/package/kernel/mac80211/patches/ath11k_nss/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch deleted file mode 100644 index c86330c9b21b57..00000000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 11d0cce62afc157468e1d97ea80a2510091ea2c2 Mon Sep 17 00:00:00 2001 -From: P Praneesh -Date: Fri, 1 Jul 2022 11:57:00 +0530 -Subject: [PATCH] mac80211: Remove unused RX_FLAGS from mac80211_rx_flags - -Remove unused RX_FLAG_AMPDU_DELIM_CRC_KNOWN flag from -mac80211_rx_flags to provide space for new EHT flags. - -Signed-off-by: P Praneesh ---- - include/net/mac80211.h | 33 +++++++++++++++------------------ - net/mac80211/rx.c | 7 +------ - 2 files changed, 16 insertions(+), 24 deletions(-) - ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -1405,8 +1405,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 -- * @RX_FLAG_AMPDU_DELIM_CRC_KNOWN: The delimiter CRC field is known (the CRC -- * is stored in the @ampdu_delimiter_crc field) - * @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 -@@ -1478,22 +1476,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), -- RX_FLAG_AMPDU_DELIM_CRC_KNOWN = BIT(15), -- RX_FLAG_MACTIME_END = BIT(16), -- RX_FLAG_ONLY_MONITOR = BIT(17), -- RX_FLAG_SKIP_MONITOR = BIT(18), -- RX_FLAG_AMSDU_MORE = BIT(19), -- RX_FLAG_RADIOTAP_TLV_AT_END = BIT(20), -- RX_FLAG_MIC_STRIPPED = BIT(21), -- RX_FLAG_ALLOW_SAME_PN = BIT(22), -- RX_FLAG_ICV_STRIPPED = BIT(23), -- RX_FLAG_AMPDU_EOF_BIT = BIT(24), -- RX_FLAG_AMPDU_EOF_BIT_KNOWN = BIT(25), -- RX_FLAG_RADIOTAP_HE = BIT(26), -- RX_FLAG_RADIOTAP_HE_MU = BIT(27), -- RX_FLAG_RADIOTAP_LSIG = BIT(28), -- RX_FLAG_NO_PSDU = BIT(29), -- RX_FLAG_8023 = BIT(30), -+ RX_FLAG_MACTIME_END = BIT(15), -+ RX_FLAG_ONLY_MONITOR = BIT(16), -+ RX_FLAG_SKIP_MONITOR = BIT(17), -+ RX_FLAG_AMSDU_MORE = BIT(18), -+ RX_FLAG_RADIOTAP_TLV_AT_END = BIT(19), -+ RX_FLAG_MIC_STRIPPED = BIT(20), -+ RX_FLAG_ALLOW_SAME_PN = BIT(21), -+ RX_FLAG_ICV_STRIPPED = BIT(22), -+ RX_FLAG_AMPDU_EOF_BIT = BIT(23), -+ RX_FLAG_AMPDU_EOF_BIT_KNOWN = BIT(24), -+ RX_FLAG_RADIOTAP_HE = BIT(25), -+ RX_FLAG_RADIOTAP_HE_MU = BIT(26), -+ RX_FLAG_RADIOTAP_LSIG = BIT(27), -+ RX_FLAG_NO_PSDU = BIT(28), -+ RX_FLAG_8023 = BIT(29), - }; - - /** ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -527,18 +527,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; -- if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN) -- flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN; - if (status->flag & RX_FLAG_AMPDU_EOF_BIT_KNOWN) - flags |= IEEE80211_RADIOTAP_AMPDU_EOF_KNOWN; - if (status->flag & RX_FLAG_AMPDU_EOF_BIT) - flags |= IEEE80211_RADIOTAP_AMPDU_EOF; - put_unaligned_le16(flags, pos); - pos += 2; -- if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN) -- *pos++ = status->ampdu_delimiter_crc; -- else -- *pos++ = 0; -+ *pos++ = 0; - *pos++ = 0; - } - 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 5d45089546e492..00000000000000 --- 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 -@@ -1459,7 +1459,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), -@@ -1491,6 +1495,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), - }; - - /** -@@ -1558,6 +1564,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 -@@ -1611,6 +1618,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/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch b/package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch index b2bc7e750b51eb..322207d796f97b 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch @@ -41,10 +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) - { -@@ -4321,13 +4322,18 @@ void __ieee80211_subif_start_xmit(struct + static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, +@@ -4309,13 +4310,18 @@ void __ieee80211_subif_start_xmit(struct atomic_inc(&sta->tx_netif_pkts); if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { @@ -66,16 +66,16 @@ Signed-off-by: Aaradhana Sahu rcu_read_unlock(); return; } -@@ -4373,7 +4379,7 @@ void __ieee80211_subif_start_xmit(struct +@@ -4361,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); -@@ -4674,19 +4680,29 @@ static bool ieee80211_tx_8023(struct iee +@@ -4662,19 +4668,29 @@ 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, @@ -106,7 +106,7 @@ Signed-off-by: Aaradhana Sahu if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)) && test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) goto out_free; -@@ -4721,6 +4737,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4709,6 +4725,7 @@ static void ieee80211_8023_xmit(struct i info = IEEE80211_SKB_CB(skb); memset(info, 0, sizeof(*info)); @@ -114,7 +114,7 @@ Signed-off-by: Aaradhana Sahu info->hw_queue = sdata->vif.hw_queue[queue]; if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) -@@ -4740,9 +4757,10 @@ static void ieee80211_8023_xmit(struct i +@@ -4728,9 +4745,10 @@ static void ieee80211_8023_xmit(struct i memcpy(IEEE80211_SKB_CB(seg), info, sizeof(*info)); } @@ -128,7 +128,7 @@ Signed-off-by: Aaradhana Sahu info->ack_frame_id = ieee80211_store_ack_skb(local, skb, &info->flags, NULL); -@@ -4767,7 +4785,8 @@ out_free: +@@ -4755,7 +4773,8 @@ out_free: void ieee80211_8023_xmit_ap(struct ieee80211_sub_if_data *sdata, struct net_device *dev, struct sta_info *sta, @@ -138,7 +138,7 @@ Signed-off-by: Aaradhana Sahu { struct ieee80211_tx_info *info; struct ieee80211_local *local = sdata->local; -@@ -4776,6 +4795,9 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4764,6 +4783,9 @@ void ieee80211_8023_xmit_ap(struct ieee8 unsigned long flags; int q; u16 q_map; @@ -148,7 +148,7 @@ Signed-off-by: Aaradhana Sahu /* * If the skb is shared we need to obtain our own copy. -@@ -4787,11 +4809,13 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4775,11 +4797,13 @@ void ieee80211_8023_xmit_ap(struct ieee8 info = IEEE80211_SKB_CB(skb); memset(info, 0, sizeof(*info)); @@ -165,7 +165,7 @@ Signed-off-by: Aaradhana Sahu info->flags |= IEEE80211_TX_CTL_HW_80211_ENCAP; info->control.vif = &sdata->vif; -@@ -4828,14 +4852,23 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4816,14 +4840,23 @@ void ieee80211_8023_xmit_ap(struct ieee8 if (sta) atomic_inc(&sta->tx_drv_pkts); } @@ -190,7 +190,7 @@ Signed-off-by: Aaradhana Sahu #ifdef CPTCFG_MAC80211_NSS_SUPPORT ieee80211_xmit_nss_fixup(skb, dev); -@@ -4851,14 +4884,15 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4839,14 +4872,15 @@ netdev_tx_t ieee80211_subif_start_xmit_8 kfree_skb(skb); goto out; } @@ -208,7 +208,7 @@ Signed-off-by: Aaradhana Sahu goto skip_offload; key = rcu_dereference(sta->ptk[sta->ptk_idx]); -@@ -4869,13 +4903,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4857,13 +4891,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 goto skip_offload; if (sdata->vif.type == NL80211_IFTYPE_AP) { @@ -224,7 +224,7 @@ Signed-off-by: Aaradhana Sahu goto out; skip_offload: -@@ -6381,13 +6415,10 @@ start_xmit: +@@ -6369,13 +6403,10 @@ start_xmit: mutex_lock(&local->mtx); local_bh_disable(); 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 4a8328f4e3ca83..00000000000000 --- 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/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 index 1548ede8c6e660..12ce4198462047 100644 --- 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 @@ -19,7 +19,7 @@ Signed-off-by: Ramanathan Choodamani --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4584,6 +4584,7 @@ netdev_tx_t ieee80211_subif_start_xmit(s +@@ -4572,6 +4572,7 @@ netdev_tx_t ieee80211_subif_start_xmit(s #ifdef CPTCFG_MAC80211_NSS_SUPPORT ieee80211_xmit_nss_fixup(skb, dev); #endif @@ -27,7 +27,7 @@ Signed-off-by: Ramanathan Choodamani if (likely(!is_multicast_ether_addr(eth->h_dest))) goto normal; -@@ -4855,7 +4856,43 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4843,7 +4844,43 @@ void ieee80211_8023_xmit_ap(struct ieee8 netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, struct net_device *dev) { diff --git a/package/kernel/mac80211/patches/ath11k_nss/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch b/package/kernel/mac80211/patches/ath11k_nss/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch index cc77cf8d4be1a6..6ce5418f48a367 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/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, -@@ -3643,7 +3645,7 @@ ieee80211_sdata_netdev_features(struct i +@@ -3631,7 +3633,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; -@@ -3661,7 +3663,7 @@ ieee80211_tx_skb_fixup(struct sk_buff *s +@@ -3649,7 +3651,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) -@@ -3807,7 +3809,7 @@ static bool ieee80211_xmit_fast(struct i +@@ -3795,7 +3797,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; -@@ -4356,7 +4358,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,7 +67,7 @@ Signed-off-by: Tamizh Chelvam Raja if (!skb) { len = 0; goto out; -@@ -4584,7 +4586,6 @@ netdev_tx_t ieee80211_subif_start_xmit(s +@@ -4572,7 +4574,6 @@ netdev_tx_t ieee80211_subif_start_xmit(s #ifdef CPTCFG_MAC80211_NSS_SUPPORT ieee80211_xmit_nss_fixup(skb, dev); #endif @@ -75,7 +75,7 @@ Signed-off-by: Tamizh Chelvam Raja if (likely(!is_multicast_ether_addr(eth->h_dest))) goto normal; -@@ -4731,7 +4732,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4719,7 +4720,7 @@ static void ieee80211_8023_xmit(struct i } } @@ -84,7 +84,7 @@ Signed-off-by: Tamizh Chelvam Raja if (!skb) return; -@@ -4856,6 +4857,7 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4844,6 +4845,7 @@ void ieee80211_8023_xmit_ap(struct ieee8 netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, struct net_device *dev) { @@ -92,7 +92,7 @@ Signed-off-by: Tamizh Chelvam Raja 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 = {}; -@@ -4890,9 +4892,10 @@ out: +@@ -4878,9 +4880,10 @@ out: } return NETDEV_TX_OK; diff --git a/package/kernel/mac80211/patches/ath11k_nss/829-mac80211-fix-mesh-ping-issue.patch b/package/kernel/mac80211/patches/ath11k_nss/829-mac80211-fix-mesh-ping-issue.patch index 535b5d1833757b..eed0aececb6779 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/829-mac80211-fix-mesh-ping-issue.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/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 -@@ -4746,16 +4746,14 @@ void ieee80211_check_fast_rx(struct sta_ +@@ -4643,16 +4643,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; } -@@ -4978,10 +4976,7 @@ static bool ieee80211_invoke_fast_rx(str +@@ -4875,10 +4873,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 -@@ -5031,37 +5026,6 @@ static bool ieee80211_invoke_fast_rx(str +@@ -4928,37 +4923,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))) -@@ -5099,30 +5063,6 @@ static bool ieee80211_invoke_fast_rx(str +@@ -4996,30 +4960,6 @@ static bool ieee80211_invoke_fast_rx(str return true; } diff --git a/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch b/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch index d6d0af9c6245de..9ec90f986bf329 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch @@ -56,7 +56,7 @@ if (rxcb->is_mcbc) { --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -9412,7 +9412,7 @@ void cfg80211_bss_flush(struct wiphy *wi +@@ -9228,7 +9228,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 +65,7 @@ enum nl80211_commands cmd, u8 count, u64 color_bitmap); -@@ -9422,9 +9422,9 @@ int cfg80211_bss_color_notify(struct net +@@ -9238,9 +9238,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 +77,7 @@ 0, color_bitmap); } -@@ -9438,7 +9438,7 @@ static inline int cfg80211_obss_color_co +@@ -9254,7 +9254,7 @@ static inline int cfg80211_obss_color_co static inline int cfg80211_color_change_started_notify(struct net_device *dev, u8 count) { @@ -86,7 +86,7 @@ count, 0); } -@@ -9450,7 +9450,7 @@ static inline int cfg80211_color_change_ +@@ -9266,7 +9266,7 @@ static inline int cfg80211_color_change_ */ static inline int cfg80211_color_change_aborted_notify(struct net_device *dev) { @@ -95,7 +95,7 @@ 0, 0); } -@@ -9462,7 +9462,7 @@ static inline int cfg80211_color_change_ +@@ -9278,7 +9278,7 @@ static inline int cfg80211_color_change_ */ static inline int cfg80211_color_change_notify(struct net_device *dev) { 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/ath11k_nss/902-000-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch index 7bf1937047e98b..68728ea7ecf6a0 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/ath11k_nss/902-000-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 -@@ -5134,6 +5134,17 @@ void ieee80211_sta_pspoll(struct ieee802 +@@ -5129,6 +5129,17 @@ void ieee80211_sta_pspoll(struct ieee802 */ void ieee80211_sta_uapsd_trigger(struct ieee80211_sta *sta, u8 tid); @@ -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,7 +137,7 @@ Signed-off-by: Sathishkumar Muruganandam { --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4742,7 +4742,8 @@ static void ieee80211_8023_xmit(struct i +@@ -4730,7 +4730,8 @@ static void ieee80211_8023_xmit(struct i info->flags |= info_flags; info->hw_queue = sdata->vif.hw_queue[queue]; 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/ath11k_nss/902-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch index 9f51d50ad2e289..d54dae55fc414e 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/902-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/902-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 -@@ -2111,6 +2111,8 @@ enum ieee80211_key_flags { +@@ -2106,6 +2106,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) -@@ -2130,6 +2132,7 @@ struct ieee80211_key_conf { +@@ -2125,6 +2127,7 @@ struct ieee80211_key_conf { u8 hw_key_idx; s8 keyidx; u16 flags; From 88a59efaa24d31c6b96123940c3842079b345ea2 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Wed, 17 Jan 2024 17:59:05 -0500 Subject: [PATCH 095/225] ath11k_nss: revert qsdk 4.4 related changes --- .../ath11k_nss/245-compilation_fix.patch | 81 ------------------- ...x-memory-corruption-during-mesh-beac.patch | 2 +- 2 files changed, 1 insertion(+), 82 deletions(-) diff --git a/package/kernel/mac80211/patches/ath11k_nss/245-compilation_fix.patch b/package/kernel/mac80211/patches/ath11k_nss/245-compilation_fix.patch index b4a735f10fc0e6..923517d3d2d40d 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/245-compilation_fix.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/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,42 +28,6 @@ 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 @@ -156,37 +109,3 @@ Signed-off-by: Gautham Kumar Senthilkumaran 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)); -- - /* - * 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); -- -- 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); diff --git a/package/kernel/mac80211/patches/ath11k_nss/902-wifi-mac80211-Fix-memory-corruption-during-mesh-beac.patch b/package/kernel/mac80211/patches/ath11k_nss/902-wifi-mac80211-Fix-memory-corruption-during-mesh-beac.patch index ea76cd96327e46..db714cd568b203 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/902-wifi-mac80211-Fix-memory-corruption-during-mesh-beac.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/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; From 6335f352aab9c0a210969e1b79ba44d1e4267686 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Wed, 17 Jan 2024 18:07:56 -0500 Subject: [PATCH 096/225] ath11k_nss: bump release version '8' --- package/kernel/mac80211/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 654aebd069640e..e529f02d81019b 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 PKG_VERSION:=6.5 -PKG_RELEASE:=7 +PKG_RELEASE:=8 # PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.15.58/ PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/ PKG_HASH:=908c22dceba185eab83caa5a1e58ce6b3ebdc58f099c3fd3e11c7352ebfab2d7 From 3dd22f4bca3fe6cb433a50c3e0e9d83dbfe5e94b Mon Sep 17 00:00:00 2001 From: Qosmio Date: Fri, 19 Jan 2024 21:56:37 -0500 Subject: [PATCH 097/225] mac80211: refactor NSS patches Since NSS requires patches to subsys, and ath*k directories. Move patches into a subset of nss for better tracking against QSDK, and modularization. --- package/kernel/mac80211/Makefile | 14 +++- .../199-004-ath10k-fixup-nss-compile.patch | 0 ...th11k-fix-for-peer-memory-corruption.patch | 0 ...dma-counter-increamenting-improperly.patch | 0 .../ath11k}/107-ath11k-tid-counter-fix.patch | 0 .../113-ath11k-add-8023-undecap-support.patch | 0 ...-adding-support-for-mgmt-frame-stats.patch | 0 ...91-ath11k-add-mgmt-and-data-ack-rssi.patch | 0 ...-ath11k_nss-add-nss-driver-interface.patch | 0 .../199-003-ath11k-add-nss-support.patch | 0 ...-ath11k-Add-support-for-dynamic-vlan.patch | 0 ...207-ath11k-Enable-256_512MB-profiles.patch | 0 .../211-ath11k-add-obss-pd-support.patch | 0 ...14-ath11k-qos-null-frame-tx-over-wmi.patch | 0 ...11k-Disable-rx_header-tlv-for-2K-SKB.patch | 0 ...01-ath11k-account-tx-rx-packets-flow.patch | 0 ...th11k-Add-support-for-beacon-tx-mode.patch | 0 ...dd-provision-to-configure-rx-hashmap.patch | 0 ...dst-ring-descriptors-from-cacheable-.patch | 0 ...ow-fast-rx-by-bypassing-stats-update.patch | 0 ...-nss-thread-priority-during-pdev_ini.patch | 0 ...avoid-stack-corrupt-in-nwifi-undecap.patch | 0 ...e-free-of-peer-rx_tid-during-reo-cmd.patch | 0 ...TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch | 0 ...1k-skip-status-ring-entry-processing.patch | 0 ...ccess-of-the-dma-buffer-back-to-dma-.patch | 0 ...-fix-clear-peer-keys-during-disassoc.patch | 0 ...-fix-tkip-encryption-traffic-failure.patch | 0 ...-event-handler-support-for-link-desc.patch | 0 .../702-ath11k-fix-memory-leak-in-dp-rx.patch | 0 ...load-changes-to-NSS-driver-interface.patch | 0 ...-support-on-NSS-offload-for-STA-mode.patch | 0 .../902-020-ath11k-add-btcoex-config.patch | 0 .../902-022-ath11k-add-ap-ps-support.patch | 0 ...69-ath11k-add-HE-stats-in-peer-stats.patch | 0 ...vdev-in-NSS-for-AP_VLAN-vif-handling.patch | 0 ...pport-for-WDS-offload-in-NSS-offload.patch | 0 ...dev-in-NSS-for-dynamic-VLAN-handling.patch | 0 ...-dynamic-VLAN-support-in-NSS-offload.patch | 0 ...04-300-ath11k-nss_get_arvif_from_dev.patch | 0 .../905-ath11k-add-support-memory-stats.patch | 0 ...support-to-send-the-QoS-Null-Data-fr.patch | 0 .../906-ath11k-m3-ssr-dump-collection.patch | 0 ...07-068-ath11k-add-rx-histogram-stats.patch | 10 +-- ...ul-ofdma-ru-allocation-in-peer-stats.patch | 14 ++-- ...11k-remove-error-on-soc-debugfs-fail.patch | 0 .../908-301-ath11k-nss-mcbc-exception.patch | 2 +- ...30-ath11k-sync-wds_ast_entry-updates.patch | 0 ...ct-ast-index-assignment-for-wds-peer.patch | 0 .../ath11k}/911-244-ath11k-dp-tx-perf.patch | 0 ...-0001-ath11k-optimize-tx-completions.patch | 0 ...se-DECLARE_BITMAP-for-idr-operations.patch | 0 ...1k-add-simple-tx-handler-for-AP-mode.patch | 0 .../911-335-ath11k-fix-ar-ops-crash.patch | 0 ...Add-retry-mechanism-for-update_rx_qu.patch | 0 ...rt-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch | 0 ...-frags-from-uninitialized-peer-in-dp.patch | 0 ...356-ath11k-invalid-desc-sanity-check.patch | 4 +- ...k-skb_headroom-before-using-skb_push.patch | 64 ++++++++++++++-- ...ing-memset-of-ppdu-info-for-next-skb.patch | 0 .../subsys/007-fix_compilation_issue.patch} | 74 +++---------------- ...-when-using-encapsulation-offloading.patch | 0 .../199-001-mac80211-add-nss-support.patch | 2 +- ...t-callback-when-hwencap-enable-in-st.patch | 0 ...ac80211-Add-support-for-dynamic-vlan.patch | 0 ...07-mac80211-add-nss-redirect-support.patch | 0 ...-mac80211-account-tx-rx-packets-flow.patch | 0 ...80211-Add-support-for-beacon-tx-mode.patch | 0 .../subsys}/245-compilation_fix.patch | 0 ...00-mac80211-nss-mesh-offload-support.patch | 0 ...TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch | 0 ...-0005-mac80211-simple-tx-for-AP-mode.patch | 0 .../336-mac80211-Mesh-Fast-rx-support.patch | 0 ...mac80211-fix-unconditional-sta-usage.patch | 0 ...rning-with-monitor-interface-restart.patch | 0 ...ncapsulation-of-EAPOL-frames-if-OFFL.patch | 6 +- ...-the-frame-to-driver-tx-ops-directly.patch | 0 ...se-HW-checksum-offload-only-for-ethm.patch | 2 +- .../829-mac80211-fix-mesh-ping-issue.patch | 0 ...N-iftype-support-on-NSS-offload-case.patch | 0 ...-dynamic-VLAN-support-on-NSS-offload.patch | 0 ...x-memory-corruption-during-mesh-beac.patch | 0 ...fix-RCU-stall-in-mesh-fast-xmit-path.patch | 0 ...ix-crash-when-accessing-null-pointer.patch | 0 84 files changed, 100 insertions(+), 92 deletions(-) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath10k}/199-004-ath10k-fixup-nss-compile.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/033-ath11k-fix-for-peer-memory-corruption.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/087-ath11k-fix-ul-ofdma-counter-increamenting-improperly.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/107-ath11k-tid-counter-fix.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/113-ath11k-add-8023-undecap-support.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/142-ath11k-adding-support-for-mgmt-frame-stats.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/191-ath11k-add-mgmt-and-data-ack-rssi.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/199-002-ath11k_nss-add-nss-driver-interface.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/199-003-ath11k-add-nss-support.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/207-ath11k-Add-support-for-dynamic-vlan.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/207-ath11k-Enable-256_512MB-profiles.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/211-ath11k-add-obss-pd-support.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/214-ath11k-qos-null-frame-tx-over-wmi.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/234-001-ath11k-account-tx-rx-packets-flow.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/235-001-ath11k-Add-support-for-beacon-tx-mode.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/237-002-ath11k-Add-provision-to-configure-rx-hashmap.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/237-003-ath11k-allocate-dst-ring-descriptors-from-cacheable-.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/318-ath11k-avoid-stack-corrupt-in-nwifi-undecap.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/319-ath11k-fix-double-free-of-peer-rx_tid-during-reo-cmd.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/335-0003-ath11k-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/336-ath11k-skip-status-ring-entry-processing.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/342-ath11k-provide-access-of-the-dma-buffer-back-to-dma-.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/357-ath11k-fix-clear-peer-keys-during-disassoc.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/359-ath11k-fix-tkip-encryption-traffic-failure.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/376-ath11k-Add-nss-event-handler-support-for-link-desc.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/702-ath11k-fix-memory-leak-in-dp-rx.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/902-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/902-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/902-020-ath11k-add-btcoex-config.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/902-022-ath11k-add-ap-ps-support.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/902-069-ath11k-add-HE-stats-in-peer-stats.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/903-002-ath11k-add-support-for-ext-vdev-in-NSS-for-AP_VLAN-vif-handling.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/904-002-ath11k-extend-ext-vdev-in-NSS-for-dynamic-VLAN-handling.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/904-003-ath11k-add-dynamic-VLAN-support-in-NSS-offload.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/904-300-ath11k-nss_get_arvif_from_dev.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/905-ath11k-add-support-memory-stats.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/906-456-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/906-ath11k-m3-ssr-dump-collection.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/907-068-ath11k-add-rx-histogram-stats.patch (98%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch (97%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/907-ath11k-remove-error-on-soc-debugfs-fail.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/908-301-ath11k-nss-mcbc-exception.patch (99%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/908-330-ath11k-sync-wds_ast_entry-updates.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/908-362-ath11k-fix-incorrect-ast-index-assignment-for-wds-peer.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/911-244-ath11k-dp-tx-perf.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/911-335-0001-ath11k-optimize-tx-completions.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/911-335-0002-ath11k-use-DECLARE_BITMAP-for-idr-operations.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/911-335-0006-ath11k-add-simple-tx-handler-for-AP-mode.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/911-335-ath11k-fix-ar-ops-crash.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/913-341-ath11k-fix-support-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/913-353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/913-356-ath11k-invalid-desc-sanity-check.patch (97%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/913-374-ath11k-Check-skb_headroom-before-using-skb_push.patch (79%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/913-830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss/900-fix-build.patch => nss/subsys/007-fix_compilation_issue.patch} (62%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/146-mac80211-enable-TKIP-when-using-encapsulation-offloading.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/199-001-mac80211-add-nss-support.patch (99%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/199-mac80211-fix-xmit-callback-when-hwencap-enable-in-st.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/207-mac80211-Add-support-for-dynamic-vlan.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/207-mac80211-add-nss-redirect-support.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/234-002-mac80211-account-tx-rx-packets-flow.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/235-002-mac80211-Add-support-for-beacon-tx-mode.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/245-compilation_fix.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/300-mac80211-nss-mesh-offload-support.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/335-0003-mac80211-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/335-0005-mac80211-simple-tx-for-AP-mode.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/336-mac80211-Mesh-Fast-rx-support.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/342-mac80211-fix-unconditional-sta-usage.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/353-mac80211-fix-dynamic-vlan-warning-with-monitor-interface-restart.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch (98%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch (98%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/829-mac80211-fix-mesh-ping-issue.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/902-000-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/902-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/902-wifi-mac80211-Fix-memory-corruption-during-mesh-beac.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/913-686-mac80211-fix-RCU-stall-in-mesh-fast-xmit-path.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/913-726-mac80211-fix-crash-when-accessing-null-pointer.patch (100%) diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index e529f02d81019b..7314b6dbd2bc81 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -299,6 +299,8 @@ ifdef CONFIG_ATH11K_NSS_SUPPORT IREMAP_CFLAGS+=-I$(STAGING_DIR)/usr/include/qca-nss-drv -I$(STAGING_DIR)/usr/include/qca-nss-clients endif +NSS_PATCHES:= subsys ath10k ath11k + config-$(CONFIG_PACKAGE_MAC80211_NSS_SUPPORT) += MAC80211_NSS_SUPPORT MAKE_OPTS:= \ @@ -369,7 +371,11 @@ define Build/Patch $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath9k,ath9k/) $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/) $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/) - $(if $(CONFIG_ATH11K_NSS_SUPPORT),$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k_nss,ath11k_nss/)) +ifdef CONFIG_ATH11K_NSS_SUPPORT + $(foreach driver,$(NSS_PATCHES), + $(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/) @@ -386,7 +392,11 @@ define Quilt/Refresh/Package $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath9k,ath9k/) $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/) $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/) - $(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_PATCHES), + $(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/) diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-004-ath10k-fixup-nss-compile.patch b/package/kernel/mac80211/patches/nss/ath10k/199-004-ath10k-fixup-nss-compile.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/199-004-ath10k-fixup-nss-compile.patch rename to package/kernel/mac80211/patches/nss/ath10k/199-004-ath10k-fixup-nss-compile.patch 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/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 100% 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 diff --git a/package/kernel/mac80211/patches/ath11k_nss/107-ath11k-tid-counter-fix.patch b/package/kernel/mac80211/patches/nss/ath11k/107-ath11k-tid-counter-fix.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/107-ath11k-tid-counter-fix.patch rename to package/kernel/mac80211/patches/nss/ath11k/107-ath11k-tid-counter-fix.patch 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 100% 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 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 100% 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 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 100% 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 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 100% 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 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 100% 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 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 100% 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 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 100% 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 diff --git a/package/kernel/mac80211/patches/ath11k_nss/211-ath11k-add-obss-pd-support.patch b/package/kernel/mac80211/patches/nss/ath11k/211-ath11k-add-obss-pd-support.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/211-ath11k-add-obss-pd-support.patch rename to package/kernel/mac80211/patches/nss/ath11k/211-ath11k-add-obss-pd-support.patch 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 100% 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 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/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch similarity index 100% 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/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/234-001-ath11k-account-tx-rx-packets-flow.patch b/package/kernel/mac80211/patches/nss/ath11k/234-001-ath11k-account-tx-rx-packets-flow.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/234-001-ath11k-account-tx-rx-packets-flow.patch rename to package/kernel/mac80211/patches/nss/ath11k/234-001-ath11k-account-tx-rx-packets-flow.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/235-001-ath11k-Add-support-for-beacon-tx-mode.patch b/package/kernel/mac80211/patches/nss/ath11k/235-001-ath11k-Add-support-for-beacon-tx-mode.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/235-001-ath11k-Add-support-for-beacon-tx-mode.patch rename to package/kernel/mac80211/patches/nss/ath11k/235-001-ath11k-Add-support-for-beacon-tx-mode.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/237-002-ath11k-Add-provision-to-configure-rx-hashmap.patch b/package/kernel/mac80211/patches/nss/ath11k/237-002-ath11k-Add-provision-to-configure-rx-hashmap.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/237-002-ath11k-Add-provision-to-configure-rx-hashmap.patch rename to package/kernel/mac80211/patches/nss/ath11k/237-002-ath11k-Add-provision-to-configure-rx-hashmap.patch 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 100% 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 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 100% 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 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/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch similarity index 100% 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/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch 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 100% 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 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 100% 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 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 100% 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 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/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 100% 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 diff --git a/package/kernel/mac80211/patches/ath11k_nss/359-ath11k-fix-tkip-encryption-traffic-failure.patch b/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/359-ath11k-fix-tkip-encryption-traffic-failure.patch rename to package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch 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 100% 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 diff --git a/package/kernel/mac80211/patches/ath11k_nss/702-ath11k-fix-memory-leak-in-dp-rx.patch b/package/kernel/mac80211/patches/nss/ath11k/702-ath11k-fix-memory-leak-in-dp-rx.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/702-ath11k-fix-memory-leak-in-dp-rx.patch rename to package/kernel/mac80211/patches/nss/ath11k/702-ath11k-fix-memory-leak-in-dp-rx.patch 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/902-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch similarity index 100% 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/902-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch 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/902-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch similarity index 100% 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/902-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/902-020-ath11k-add-btcoex-config.patch b/package/kernel/mac80211/patches/nss/ath11k/902-020-ath11k-add-btcoex-config.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/902-020-ath11k-add-btcoex-config.patch rename to package/kernel/mac80211/patches/nss/ath11k/902-020-ath11k-add-btcoex-config.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/902-022-ath11k-add-ap-ps-support.patch b/package/kernel/mac80211/patches/nss/ath11k/902-022-ath11k-add-ap-ps-support.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/902-022-ath11k-add-ap-ps-support.patch rename to package/kernel/mac80211/patches/nss/ath11k/902-022-ath11k-add-ap-ps-support.patch 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/902-069-ath11k-add-HE-stats-in-peer-stats.patch similarity index 100% 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/902-069-ath11k-add-HE-stats-in-peer-stats.patch 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/903-002-ath11k-add-support-for-ext-vdev-in-NSS-for-AP_VLAN-vif-handling.patch similarity index 100% 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/903-002-ath11k-add-support-for-ext-vdev-in-NSS-for-AP_VLAN-vif-handling.patch 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/903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch similarity index 100% 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/903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch 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/904-002-ath11k-extend-ext-vdev-in-NSS-for-dynamic-VLAN-handling.patch similarity index 100% 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/904-002-ath11k-extend-ext-vdev-in-NSS-for-dynamic-VLAN-handling.patch 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/904-003-ath11k-add-dynamic-VLAN-support-in-NSS-offload.patch similarity index 100% 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/904-003-ath11k-add-dynamic-VLAN-support-in-NSS-offload.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/904-300-ath11k-nss_get_arvif_from_dev.patch b/package/kernel/mac80211/patches/nss/ath11k/904-300-ath11k-nss_get_arvif_from_dev.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/904-300-ath11k-nss_get_arvif_from_dev.patch rename to package/kernel/mac80211/patches/nss/ath11k/904-300-ath11k-nss_get_arvif_from_dev.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/905-ath11k-add-support-memory-stats.patch b/package/kernel/mac80211/patches/nss/ath11k/905-ath11k-add-support-memory-stats.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/905-ath11k-add-support-memory-stats.patch rename to package/kernel/mac80211/patches/nss/ath11k/905-ath11k-add-support-memory-stats.patch 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/906-456-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch similarity index 100% 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/906-456-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/906-ath11k-m3-ssr-dump-collection.patch b/package/kernel/mac80211/patches/nss/ath11k/906-ath11k-m3-ssr-dump-collection.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/906-ath11k-m3-ssr-dump-collection.patch rename to package/kernel/mac80211/patches/nss/ath11k/906-ath11k-m3-ssr-dump-collection.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/907-068-ath11k-add-rx-histogram-stats.patch similarity index 98% rename from package/kernel/mac80211/patches/ath11k_nss/907-068-ath11k-add-rx-histogram-stats.patch rename to package/kernel/mac80211/patches/nss/ath11k/907-068-ath11k-add-rx-histogram-stats.patch index c90cde7eef6619..17ded34963fd0f 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/907-068-ath11k-add-rx-histogram-stats.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/907-068-ath11k-add-rx-histogram-stats.patch @@ -214,7 +214,7 @@ Signed-off-by: Manikanta Pubbisetty rx_stats->dcm_count, rx_stats->ru_alloc_cnt[0], --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -3233,10 +3233,43 @@ exit: +@@ -3221,10 +3221,43 @@ exit: return total_msdu_reaped; } @@ -258,7 +258,7 @@ Signed-off-by: Manikanta Pubbisetty u32 num_msdu; int i; -@@ -3246,6 +3279,8 @@ static void ath11k_dp_rx_update_peer_sta +@@ -3234,6 +3267,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 +267,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; -@@ -3262,18 +3297,6 @@ static void ath11k_dp_rx_update_peer_sta +@@ -3250,18 +3285,6 @@ static void ath11k_dp_rx_update_peer_sta ppdu_info->tid = IEEE80211_NUM_TIDS; } @@ -286,7 +286,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; -@@ -3302,8 +3325,6 @@ static void ath11k_dp_rx_update_peer_sta +@@ -3290,8 +3313,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 +295,7 @@ Signed-off-by: Manikanta Pubbisetty BUILD_BUG_ON(ARRAY_SIZE(arsta->chain_signal) > ARRAY_SIZE(ppdu_info->rssi_chain_pri20)); -@@ -3312,6 +3333,52 @@ static void ath11k_dp_rx_update_peer_sta +@@ -3300,6 +3321,52 @@ static void ath11k_dp_rx_update_peer_sta rx_stats->rx_duration += ppdu_info->rx_duration; arsta->rx_duration = rx_stats->rx_duration; 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/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch similarity index 97% 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/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch index 9be70411b10996..609e78be7357e7 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/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch @@ -15,7 +15,7 @@ "\nDCM: %llu\nRU: 26 %llu 52: %llu 106: %llu 242: %llu 484: %llu 996: %llu\n", --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -3236,11 +3236,12 @@ exit: +@@ -3224,11 +3224,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 +@@ -3250,10 +3251,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 +@@ -3311,7 +3315,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 +@@ -3329,10 +3332,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 +@@ -3365,7 +3368,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 +@@ -5834,6 +5950,55 @@ static void ath11k_dp_rx_mon_dest_proces } } @@ -247,7 +247,7 @@ 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 +@@ -5905,10 +6070,13 @@ int ath11k_dp_rx_process_mon_status(stru goto next_skb; } 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/907-ath11k-remove-error-on-soc-debugfs-fail.patch similarity index 100% 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/907-ath11k-remove-error-on-soc-debugfs-fail.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch b/package/kernel/mac80211/patches/nss/ath11k/908-301-ath11k-nss-mcbc-exception.patch similarity index 99% rename from package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch rename to package/kernel/mac80211/patches/nss/ath11k/908-301-ath11k-nss-mcbc-exception.patch index c058eeaad29a65..094d5b36305ac5 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/908-301-ath11k-nss-mcbc-exception.patch @@ -218,7 +218,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 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 +@@ -3074,6 +3074,23 @@ static void ath11k_dp_rx_process_receive } } 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/908-330-ath11k-sync-wds_ast_entry-updates.patch similarity index 100% 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/908-330-ath11k-sync-wds_ast_entry-updates.patch 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/908-362-ath11k-fix-incorrect-ast-index-assignment-for-wds-peer.patch similarity index 100% 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/908-362-ath11k-fix-incorrect-ast-index-assignment-for-wds-peer.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/911-244-ath11k-dp-tx-perf.patch b/package/kernel/mac80211/patches/nss/ath11k/911-244-ath11k-dp-tx-perf.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/911-244-ath11k-dp-tx-perf.patch rename to package/kernel/mac80211/patches/nss/ath11k/911-244-ath11k-dp-tx-perf.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/911-335-0001-ath11k-optimize-tx-completions.patch b/package/kernel/mac80211/patches/nss/ath11k/911-335-0001-ath11k-optimize-tx-completions.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/911-335-0001-ath11k-optimize-tx-completions.patch rename to package/kernel/mac80211/patches/nss/ath11k/911-335-0001-ath11k-optimize-tx-completions.patch 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/911-335-0002-ath11k-use-DECLARE_BITMAP-for-idr-operations.patch similarity index 100% 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/911-335-0002-ath11k-use-DECLARE_BITMAP-for-idr-operations.patch 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/nss/ath11k/911-335-0006-ath11k-add-simple-tx-handler-for-AP-mode.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/911-335-0006-ath11k-add-simple-tx-handler-for-AP-mode.patch rename to package/kernel/mac80211/patches/nss/ath11k/911-335-0006-ath11k-add-simple-tx-handler-for-AP-mode.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/911-335-ath11k-fix-ar-ops-crash.patch b/package/kernel/mac80211/patches/nss/ath11k/911-335-ath11k-fix-ar-ops-crash.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/911-335-ath11k-fix-ar-ops-crash.patch rename to package/kernel/mac80211/patches/nss/ath11k/911-335-ath11k-fix-ar-ops-crash.patch 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/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch similarity index 100% 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/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch 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/913-341-ath11k-fix-support-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch similarity index 100% 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/913-341-ath11k-fix-support-for-ext-vdev-in-NSS-for-AP_VLAN-v.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/913-353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch similarity index 100% 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/913-353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/913-356-ath11k-invalid-desc-sanity-check.patch b/package/kernel/mac80211/patches/nss/ath11k/913-356-ath11k-invalid-desc-sanity-check.patch similarity index 97% rename from package/kernel/mac80211/patches/ath11k_nss/913-356-ath11k-invalid-desc-sanity-check.patch rename to package/kernel/mac80211/patches/nss/ath11k/913-356-ath11k-invalid-desc-sanity-check.patch index 4e7e37957b1f31..5f01d21384ec1c 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/913-356-ath11k-invalid-desc-sanity-check.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/913-356-ath11k-invalid-desc-sanity-check.patch @@ -46,7 +46,7 @@ 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: +@@ -3216,6 +3216,16 @@ try_again: while (likely(desc = (struct hal_reo_dest_ring *)ath11k_hal_srng_dst_get_next_entry(ab, srng))) { @@ -63,7 +63,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: +@@ -3246,8 +3256,6 @@ try_again: num_buffs_reaped[mac_id]++; 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/913-374-ath11k-Check-skb_headroom-before-using-skb_push.patch similarity index 79% 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/913-374-ath11k-Check-skb_headroom-before-using-skb_push.patch index 1bbbdd6c7446da..48d768d519bd43 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/913-374-ath11k-Check-skb_headroom-before-using-skb_push.patch @@ -39,7 +39,7 @@ Signed-off-by: Tamizh Chelvam Raja size_t hdr_len, crypto_len; struct ieee80211_hdr *hdr; u16 fc, qos_ctl = 0; -+ int expand_by; ++ int expand_by = 0; u8 *crypto_hdr; if (!(status->flag & RX_FLAG_IV_STRIPPED)) { @@ -127,7 +127,7 @@ Signed-off-by: Tamizh Chelvam Raja u8 da[ETH_ALEN]; u8 sa[ETH_ALEN]; void *rfc1042; -+ int expand_by; ++ int expand_by = 0; struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); struct ath11k_dp_rfc1042_hdr rfc = {0xaa, 0xaa, 0x03, {0x00, 0x00, 0x00}}; @@ -182,11 +182,65 @@ 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 +@@ -2547,6 +2600,7 @@ static void ath11k_dp_rx_h_undecap_snap( + struct ieee80211_hdr *hdr; + size_t hdr_len; + u8 l3_pad_bytes; ++ int expand_by = 0; + struct hal_rx_desc *rx_desc; + struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); + +@@ -2571,12 +2625,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); + } + +@@ -2706,7 +2770,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; +@@ -2721,7 +2785,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) { +@@ -2942,10 +3007,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; -+ int expand_by; ++ int expand_by = 0; if (status->encoding == RX_ENC_HE && !(status->flag & RX_FLAG_RADIOTAP_HE) && @@ -199,7 +253,7 @@ 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 +@@ -3001,6 +3072,7 @@ static void ath11k_dp_rx_deliver_msdu(st !(is_mcbc && rx_status->flag & RX_FLAG_DECRYPTED)) rx_status->flag |= RX_FLAG_8023; 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/913-830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch similarity index 100% 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/913-830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch 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 62% 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 9ec90f986bf329..3b9f555b3bce51 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 +@@ -9224,7 +9224,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 +@@ -9234,9 +9234,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 +@@ -9250,7 +9250,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_ +@@ -9262,7 +9262,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_ +@@ -9274,7 +9274,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 -@@ -4793,7 +4793,7 @@ void ieee80211_color_collision_detection +@@ -4771,7 +4771,7 @@ void ieee80211_color_collision_detection struct ieee80211_sub_if_data *sdata = link->sdata; sdata_lock(sdata); @@ -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 +@@ -19406,7 +19406,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 +@@ -19420,7 +19420,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 +@@ -19443,7 +19443,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 100% 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 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 99% 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 a06ef7652df538..dc539711a5bba5 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 @@ -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 +@@ -2368,6 +2368,9 @@ sta_get_last_rx_stats(struct sta_info *s struct ieee80211_sta_rx_stats *stats = &sta->deflink.rx_stats; int cpu; 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 100% 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 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-mac80211-Add-support-for-dynamic-vlan.patch similarity index 100% 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-mac80211-Add-support-for-dynamic-vlan.patch 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 100% 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 diff --git a/package/kernel/mac80211/patches/ath11k_nss/234-002-mac80211-account-tx-rx-packets-flow.patch b/package/kernel/mac80211/patches/nss/subsys/234-002-mac80211-account-tx-rx-packets-flow.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/234-002-mac80211-account-tx-rx-packets-flow.patch rename to package/kernel/mac80211/patches/nss/subsys/234-002-mac80211-account-tx-rx-packets-flow.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/235-002-mac80211-Add-support-for-beacon-tx-mode.patch b/package/kernel/mac80211/patches/nss/subsys/235-002-mac80211-Add-support-for-beacon-tx-mode.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/235-002-mac80211-Add-support-for-beacon-tx-mode.patch rename to package/kernel/mac80211/patches/nss/subsys/235-002-mac80211-Add-support-for-beacon-tx-mode.patch 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 100% rename from package/kernel/mac80211/patches/ath11k_nss/245-compilation_fix.patch rename to package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch b/package/kernel/mac80211/patches/nss/subsys/300-mac80211-nss-mesh-offload-support.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch rename to package/kernel/mac80211/patches/nss/subsys/300-mac80211-nss-mesh-offload-support.patch 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-mac80211-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch similarity index 100% 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-mac80211-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch 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 100% 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 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 100% 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 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 100% 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 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 100% 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 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 98% 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 322207d796f97b..b54cea6c97751f 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 +@@ -2061,6 +2061,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); @@ -68,12 +68,12 @@ Signed-off-by: Aaradhana Sahu } @@ -4361,7 +4367,7 @@ void __ieee80211_subif_start_xmit(struct if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { - if (sta) + 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 { - dev_sw_netstats_tx_add(dev, 1, skb->len); + dev_sw_netstats_tx_add(dev, 1, skb->len); ieee80211_xmit(sdata, sta, skb); @@ -4662,19 +4668,29 @@ static bool ieee80211_tx_8023(struct iee 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/nss/subsys/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch rename to package/kernel/mac80211/patches/nss/subsys/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch 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 98% 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 6ce5418f48a367..b59cd3f547936e 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 @@ -107,7 +107,7 @@ Signed-off-by: Tamizh Chelvam Raja netdev_tx_t __ieee80211_subif_start_xmit_8023(struct sk_buff *skb, --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c -@@ -2251,6 +2251,10 @@ int ieee80211_if_add(struct ieee80211_lo +@@ -2255,6 +2255,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/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 100% 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 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/902-000-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch similarity index 100% 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/902-000-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch 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/902-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch similarity index 100% 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/902-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch 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 100% 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 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/913-686-mac80211-fix-RCU-stall-in-mesh-fast-xmit-path.patch similarity index 100% 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/913-686-mac80211-fix-RCU-stall-in-mesh-fast-xmit-path.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/913-726-mac80211-fix-crash-when-accessing-null-pointer.patch b/package/kernel/mac80211/patches/nss/subsys/913-726-mac80211-fix-crash-when-accessing-null-pointer.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/913-726-mac80211-fix-crash-when-accessing-null-pointer.patch rename to package/kernel/mac80211/patches/nss/subsys/913-726-mac80211-fix-crash-when-accessing-null-pointer.patch From 2a135b738a250fc370ffd5919c71c8932aad65ad Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 20 Jan 2024 04:28:42 -0500 Subject: [PATCH 098/225] ath11k_nss: rename patches --- ...ix-RCU-stall-in-mesh-fast-xmit-path.patch} | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) rename package/kernel/mac80211/patches/nss/subsys/{913-686-mac80211-fix-RCU-stall-in-mesh-fast-xmit-path.patch => 686-mac80211-fix-RCU-stall-in-mesh-fast-xmit-path.patch} (89%) diff --git a/package/kernel/mac80211/patches/nss/subsys/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 89% rename from package/kernel/mac80211/patches/nss/subsys/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 6614d8d496b354..76896c8fc046ca 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 @@ -73,48 +73,48 @@ 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_ - if (mpath->flags & MESH_PATH_RESOLVED) - pinfo->flags |= NL80211_MPATH_FLAG_RESOLVED; - pinfo->hop_count = mpath->hop_count; + if (mpath->flags & MESH_PATH_RESOLVED) + pinfo->flags |= NL80211_MPATH_FLAG_RESOLVED; + pinfo->hop_count = mpath->hop_count; - pinfo->path_change_count = mpath->path_change_count; + pinfo->path_change_count = atomic_read(&mpath->path_change_count); } - + static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev, --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -126,7 +126,7 @@ struct mesh_path { - unsigned long fast_tx_check; - bool is_root; - bool is_gate; + unsigned long fast_tx_check; + bool is_root; + bool is_gate; - u32 path_change_count; + atomic_t path_change_count; }; - + #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 - if (next_hop) - ether_addr_copy(old_next_hop_addr, next_hop->sta.addr); - if (next_hop != sta) { + 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); + flush_mpath = true; + } + mesh_path_assign_nexthop(mpath, sta); @@ -565,7 +568,10 @@ 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) { + 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); + flush_mpath = true; + } + mesh_path_assign_nexthop(mpath, sta); From 19def8c15a5827da6f303a63979cf85a2af439a8 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 20 Jan 2024 04:29:34 -0500 Subject: [PATCH 099/225] Revert "ath11k_nss: remove unused symbol" This reverts commit 6e204eccfb14cd44825c1abff64b0344a01c5e8b. --- package/kernel/mac80211/ath.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk index 6b8fac507d2894..c10c326d6a3084 100644 --- a/package/kernel/mac80211/ath.mk +++ b/package/kernel/mac80211/ath.mk @@ -342,6 +342,7 @@ define KernelPackage/ath11k/config 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 choice From 058048cc6a9c927212de40d70d8960fe4b15fe03 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 20 Jan 2024 05:32:13 -0500 Subject: [PATCH 100/225] ath11k_nss: clean up optional patches To reduce bug tracking headaches, I've remove the following patches, as they are not required for NSS offload and have been around the last 2-3 years without ever being upstreamed. nss/ath11k/235-001-ath11k-Add-support-for-beacon-tx-mode.patch nss/ath11k/237-002-ath11k-Add-provision-to-configure-rx-hashmap.patch nss/ath11k/902-020-ath11k-add-btcoex-config.patch nss/ath11k/902-022-ath11k-add-ap-ps-support.patch nss/ath11k/907-068-ath11k-add-rx-histogram-stats.patch nss/ath11k/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch nss/ath11k/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch nss/ath11k/913-353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch nss/ath11k/913-356-ath11k-invalid-desc-sanity-check.patch nss/ath11k/913-374-ath11k-Check-skb_headroom-before-using-skb_push.patch nss/ath11k/913-830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch nss/subsys/235-002-mac80211-Add-support-for-beacon-tx-mode.patch nss/subsys/913-726-mac80211-fix-crash-when-accessing-null-pointer.patch --- package/kernel/mac80211/Makefile | 8 +- package/kernel/mac80211/ath.mk | 7 +- ...-adding-support-for-mgmt-frame-stats.patch | 2 +- .../199-003-ath11k-add-nss-support.patch | 148 +---- ...207-ath11k-Enable-256_512MB-profiles.patch | 36 +- .../211-ath11k-add-obss-pd-support.patch | 16 +- ...14-ath11k-qos-null-frame-tx-over-wmi.patch | 66 +- ...11k-Disable-rx_header-tlv-for-2K-SKB.patch | 18 - ...th11k-Add-support-for-beacon-tx-mode.patch | 45 -- ...dd-provision-to-configure-rx-hashmap.patch | 208 ------ ...ow-fast-rx-by-bypassing-stats-update.patch | 34 +- ...-support-on-NSS-offload-for-STA-mode.patch | 29 +- .../902-020-ath11k-add-btcoex-config.patch | 612 ------------------ .../902-022-ath11k-add-ap-ps-support.patch | 324 ---------- ...69-ath11k-add-HE-stats-in-peer-stats.patch | 8 +- ...pport-for-WDS-offload-in-NSS-offload.patch | 43 +- .../905-ath11k-add-support-memory-stats.patch | 52 +- ...07-068-ath11k-add-rx-histogram-stats.patch | 608 ----------------- ...ul-ofdma-ru-allocation-in-peer-stats.patch | 453 ------------- ...11k-remove-error-on-soc-debugfs-fail.patch | 22 +- ...30-ath11k-sync-wds_ast_entry-updates.patch | 45 +- ...Add-retry-mechanism-for-update_rx_qu.patch | 384 ----------- ...-frags-from-uninitialized-peer-in-dp.patch | 74 --- ...356-ath11k-invalid-desc-sanity-check.patch | 74 --- ...k-skb_headroom-before-using-skb_push.patch | 263 -------- ...ing-memset-of-ppdu-info-for-next-skb.patch | 87 --- ...80211-Add-support-for-beacon-tx-mode.patch | 159 ----- ...00-mac80211-nss-mesh-offload-support.patch | 30 +- ...fix-RCU-stall-in-mesh-fast-xmit-path.patch | 40 +- ...ix-crash-when-accessing-null-pointer.patch | 87 --- 30 files changed, 186 insertions(+), 3796 deletions(-) delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/235-001-ath11k-Add-support-for-beacon-tx-mode.patch delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/237-002-ath11k-Add-provision-to-configure-rx-hashmap.patch delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/902-020-ath11k-add-btcoex-config.patch delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/902-022-ath11k-add-ap-ps-support.patch delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/907-068-ath11k-add-rx-histogram-stats.patch delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/913-353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/913-356-ath11k-invalid-desc-sanity-check.patch delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/913-374-ath11k-Check-skb_headroom-before-using-skb_push.patch delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/913-830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch delete mode 100644 package/kernel/mac80211/patches/nss/subsys/235-002-mac80211-Add-support-for-beacon-tx-mode.patch delete mode 100644 package/kernel/mac80211/patches/nss/subsys/913-726-mac80211-fix-crash-when-accessing-null-pointer.patch diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 7314b6dbd2bc81..6098a81eb1baf5 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 PKG_VERSION:=6.5 -PKG_RELEASE:=8 +PKG_RELEASE:=9 # PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.15.58/ PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/ PKG_HASH:=908c22dceba185eab83caa5a1e58ce6b3ebdc58f099c3fd3e11c7352ebfab2d7 @@ -44,6 +44,8 @@ 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/ @@ -372,7 +374,7 @@ define Build/Patch $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/) $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/) ifdef CONFIG_ATH11K_NSS_SUPPORT - $(foreach driver,$(NSS_PATCHES), + $(foreach driver,$(NSS_PATCH), $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/nss/$(driver),nss/$(driver)/) ) endif @@ -393,7 +395,7 @@ define Quilt/Refresh/Package $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/) $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/) ifdef CONFIG_ATH11K_NSS_SUPPORT - $(foreach driver,$(NSS_PATCHES), + $(foreach driver,$(NSS_PATCH), $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/nss/$(driver),nss/$(driver)/) ) endif diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk index c10c326d6a3084..dd35624db313db 100644 --- a/package/kernel/mac80211/ath.mk +++ b/package/kernel/mac80211/ath.mk @@ -311,7 +311,9 @@ 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_SUPPORT):NSS_DRV_WIFI_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 @@ -341,9 +343,6 @@ define KernelPackage/ath11k/config 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 choice prompt "ATH11K Memory Profile" diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index f1dfc0f7b9a887..7a2c473b57a963 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -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", diff --git a/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch b/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch index 1e6941e26f96b0..ddfe25a4395de4 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch @@ -496,7 +496,7 @@ Signed-off-by: Sriram R +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); @@ -691,7 +691,7 @@ Signed-off-by: Sriram R } ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; -@@ -9636,6 +9745,9 @@ static int __ath11k_mac_register(struct +@@ -9634,6 +9743,9 @@ static int __ath11k_mac_register(struct ab->hw_params.bios_sar_capa) ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa; @@ -811,80 +811,7 @@ 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 +@@ -1977,6 +1977,75 @@ static const struct file_operations ath1 .open = simple_open }; @@ -957,75 +884,6 @@ 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); -+ } -+ -+ if (ab->nss.enabled) -+ debugfs_create_file("nss_peer_stats_config", 0644, -+ 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; diff --git a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch index 3d88021c7c8e40..0e7e5899d4ba03 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch @@ -149,7 +149,7 @@ Signed-off-by: Ramya Gnanasekar ATH11K_TRACING= --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -864,6 +864,11 @@ struct ath11k_msi_config { +@@ -853,6 +853,11 @@ struct ath11k_msi_config { u16 hw_rev; }; @@ -161,7 +161,7 @@ Signed-off-by: Ramya Gnanasekar /* Master structure to hold the hw data which may be used in core module */ struct ath11k_base { enum ath11k_hw_rev hw_rev; -@@ -1017,6 +1022,9 @@ struct ath11k_base { +@@ -1006,6 +1011,9 @@ struct ath11k_base { } testmode; #endif @@ -258,7 +258,7 @@ 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 +@@ -95,7 +99,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = true, @@ -267,8 +267,7 @@ Signed-off-by: Ramya Gnanasekar .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, +@@ -103,7 +107,6 @@ static struct ath11k_hw_params ath11k_hw .supports_regdb = false, .fix_l1ss = true, .credit_flow = false, @@ -276,7 +275,7 @@ Signed-off-by: Ramya Gnanasekar .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 +130,9 @@ static struct ath11k_hw_params ath11k_hw .tcl_ring_retry = true, .tx_ring_size = DP_TCL_DATA_RING_SIZE, .smp2p_wow_exit = false, @@ -286,7 +285,7 @@ Signed-off-by: Ramya Gnanasekar }, { .hw_rev = ATH11K_HW_IPQ6018_HW10, -@@ -177,7 +184,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -177,7 +183,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = true, .coldboot_cal_ftm = true, .cbcal_restart_fw = true, @@ -295,7 +294,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = false, -@@ -259,7 +266,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -259,7 +265,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -304,7 +303,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -426,7 +433,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -426,7 +432,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -313,7 +312,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -509,7 +516,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -509,7 +515,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -322,7 +321,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -593,7 +600,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -593,7 +599,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = true, .coldboot_cal_ftm = true, .cbcal_restart_fw = false, @@ -331,7 +330,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = false, -@@ -672,7 +679,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -672,7 +678,7 @@ static struct ath11k_hw_params ath11k_hw .supports_monitor = false, .supports_sta_ps = false, .supports_shadow_regs = false, @@ -340,7 +339,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_regdb = false, -@@ -710,7 +717,23 @@ static struct ath11k_hw_params ath11k_hw +@@ -710,7 +716,23 @@ static struct ath11k_hw_params ath11k_hw }, }; @@ -365,14 +364,3 @@ Signed-off-by: Ramya Gnanasekar { 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(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", diff --git a/package/kernel/mac80211/patches/nss/ath11k/211-ath11k-add-obss-pd-support.patch b/package/kernel/mac80211/patches/nss/ath11k/211-ath11k-add-obss-pd-support.patch index ddae9fcbc50e7d..0fdb80c33fa961 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/211-ath11k-add-obss-pd-support.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/211-ath11k-add-obss-pd-support.patch @@ -14,17 +14,25 @@ Signed-off-by: Rajkumar Manoharan --- 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 +@@ -22,7 +22,6 @@ + #include "testmode.h" + #include "peer.h" + #include "debugfs_sta.h" +-#include "hif.h" + #include "wow.h" + #include "nss.h" + +@@ -3272,7 +3271,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; ++ u8 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 +@@ -3301,8 +3301,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); @@ -33,7 +41,7 @@ Signed-off-by: Rajkumar Manoharan param_val |= ATH11K_OBSS_PD_NON_SRG_EN; } -@@ -3317,7 +3316,8 @@ static int ath11k_mac_config_obss_pd(str +@@ -3317,7 +3315,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 { diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index a69c5b2af244f8..642c14ea4b9f59 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -259,15 +259,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 +@@ -5855,8 +5905,8 @@ static int ath11k_pull_mgmt_rx_params_tl return 0; } @@ -278,37 +270,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 - info->status.ack_signal = tx_compl_param->ack_rssi; - } - -+ /* dont update rates in this path, qos null data tx completions also can -+ * take this path in case of nss offload and can update invalid rates. -+ */ -+ info->status.rates[0].idx = -1; -+ - 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 - 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]++; -+ 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: -@@ -5938,12 +5995,13 @@ skip_mgmt_stats: +@@ -5937,12 +5987,13 @@ skip_mgmt_stats: return 0; } @@ -326,7 +288,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 +@@ -5952,7 +6003,7 @@ static int ath11k_pull_mgmt_tx_compl_par return ret; } @@ -335,7 +297,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: +@@ -7729,10 +7780,11 @@ exit: static void ath11k_mgmt_tx_compl_event(struct ath11k_base *ab, struct sk_buff *skb) { @@ -349,7 +311,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 +@@ -7745,7 +7797,7 @@ static void ath11k_mgmt_tx_compl_event(s goto exit; } @@ -358,7 +320,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: +@@ -7756,6 +7808,36 @@ exit: rcu_read_unlock(); } @@ -395,7 +357,7 @@ 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 +@@ -8842,6 +8924,9 @@ static void ath11k_wmi_tlv_op_rx(struct case WMI_GTK_OFFLOAD_STATUS_EVENTID: ath11k_wmi_gtk_offload_status_event(ab, skb); break; @@ -473,15 +435,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 { +@@ -4917,7 +4935,7 @@ struct wmi_rssi_ctl_ext { u32 rssi_ctl_ext[MAX_ANTENNA_EIGHT - ATH_MAX_ANTENNA]; }; @@ -490,7 +444,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 +@@ -5748,6 +5766,17 @@ struct wmi_debug_log_config_cmd_fixed_pa u32 value; } __packed; @@ -508,7 +462,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 +@@ -6358,6 +6387,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/nss/ath11k/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch b/package/kernel/mac80211/patches/nss/ath11k/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch index 67b84c10946199..c403bca30c5c74 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch @@ -825,15 +825,6 @@ 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); @@ -6338,6 +6338,7 @@ static int ath11k_mac_config_mon_status_ tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar); } @@ -842,15 +833,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, -@@ -9714,8 +9715,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 { diff --git a/package/kernel/mac80211/patches/nss/ath11k/235-001-ath11k-Add-support-for-beacon-tx-mode.patch b/package/kernel/mac80211/patches/nss/ath11k/235-001-ath11k-Add-support-for-beacon-tx-mode.patch deleted file mode 100644 index 5d5a83911d8519..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/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/nss/ath11k/237-002-ath11k-Add-provision-to-configure-rx-hashmap.patch b/package/kernel/mac80211/patches/nss/ath11k/237-002-ath11k-Add-provision-to-configure-rx-hashmap.patch deleted file mode 100644 index f0347b3bde6046..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/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, -@@ -1038,6 +1039,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/nss/ath11k/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 index 04b8b1d01e47fa..965c44706ac55c 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -136,6 +136,7 @@ struct ath11k_skb_rxcb { +@@ -135,6 +135,7 @@ struct ath11k_skb_rxcb { u8 tid; u16 peer_id; u16 seq_no; @@ -31,21 +31,20 @@ Signed-off-by: P Praneesh }; enum ath11k_hw_rev { -@@ -1040,6 +1041,7 @@ struct ath11k_base { - struct ath11k_num_vdevs_peers *num_vdevs_peers; +@@ -1026,6 +1027,7 @@ struct ath11k_base { - u32 rx_hash; + atomic_t num_max_allowed; + struct ath11k_num_vdevs_peers *num_vdevs_peers; + 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, +@@ -972,6 +972,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}; @@ -122,15 +121,6 @@ Signed-off-by: P Praneesh 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 @@ -333,7 +323,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 +@@ -297,6 +297,16 @@ static bool ath11k_hw_ipq8074_rx_desc_ge __le32_to_cpu(desc->u.ipq8074.msdu_start.info2)); } @@ -350,7 +340,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 +@@ -584,6 +594,16 @@ static bool ath11k_hw_qcn9074_rx_desc_ge __le32_to_cpu(desc->u.qcn9074.msdu_start.info2)); } @@ -367,7 +357,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 = +@@ -1137,6 +1157,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 +365,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 = +@@ -1298,6 +1319,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, @@ -395,7 +385,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 +@@ -5197,6 +5197,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/nss/ath11k/902-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch b/package/kernel/mac80211/patches/nss/ath11k/902-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch index 8149cd4027d907..e39057c781c3a6 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/902-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/902-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 -@@ -635,6 +635,7 @@ struct ath11k { +@@ -624,6 +624,7 @@ struct ath11k { struct ath11k_pdev_wmi *wmi; #ifdef CPTCFG_ATH11K_NSS_SUPPORT struct ath11k_nss nss; @@ -34,7 +34,7 @@ Signed-off-by: Sathishkumar Muruganandam #endif struct ath11k_pdev_dp dp; u8 mac_addr[ETH_ALEN]; -@@ -1043,6 +1044,8 @@ struct ath11k_base { +@@ -1032,6 +1033,8 @@ struct ath11k_base { u32 rx_hash; bool stats_disable; @@ -612,13 +612,10 @@ Signed-off-by: Sathishkumar Muruganandam struct ath11k_sta *arsta; int ret, fbret; -@@ -450,7 +865,14 @@ int ath11k_peer_create(struct ath11k *ar - +@@ -451,6 +866,12 @@ int ath11k_peer_create(struct ath11k *ar peer->sec_type = HAL_ENCRYPT_TYPE_OPEN; peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; -- peer->vif = arvif->vif; -+ peer->vif = vif; -+ + +#ifdef CPTCFG_ATH11K_NSS_SUPPORT + if (vif->type == NL80211_IFTYPE_STATION && ar->ab->nss.enabled) + ar->bss_peer = peer; @@ -626,8 +623,8 @@ Signed-off-by: Sathishkumar Muruganandam + ar->bss_peer = NULL; +#endif - if (sta) { + arsta = ath11k_sta_to_arsta(sta); --- a/drivers/net/wireless/ath/ath11k/peer.h +++ b/drivers/net/wireless/ath/ath11k/peer.h @@ -7,6 +7,47 @@ @@ -678,7 +675,7 @@ Signed-off-by: Sathishkumar Muruganandam struct ath11k_peer { struct list_head list; struct ieee80211_sta *sta; -@@ -18,6 +59,10 @@ struct ath11k_peer { +@@ -17,6 +58,10 @@ struct ath11k_peer { u8 pdev_idx; u16 hw_peer_id; struct ath11k_nss_peer nss; @@ -689,7 +686,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 { +@@ -40,8 +85,13 @@ struct ath11k_peer { }; void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id); @@ -703,7 +700,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_ +@@ -58,4 +108,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); @@ -837,7 +834,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 +@@ -6380,6 +6426,36 @@ static int ath11k_pull_peer_assoc_conf_e return 0; } @@ -874,7 +871,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 +@@ -7295,6 +7371,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 +879,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 +@@ -8734,6 +8811,22 @@ static void ath11k_wmi_gtk_offload_statu kfree(tb); } @@ -905,7 +902,7 @@ 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 +@@ -8864,6 +8957,9 @@ static void ath11k_wmi_tlv_op_rx(struct case WMI_QOS_NULL_FRAME_TX_COMPLETION_EVENTID: ath11k_qos_null_compl_event(ab, skb); break; @@ -961,7 +958,7 @@ Signed-off-by: Sathishkumar Muruganandam /* * PDEV statistics */ -@@ -6430,6 +6460,9 @@ int ath11k_wmi_set_sta_ps_param(struct a +@@ -6431,6 +6461,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/nss/ath11k/902-020-ath11k-add-btcoex-config.patch b/package/kernel/mac80211/patches/nss/ath11k/902-020-ath11k-add-btcoex-config.patch deleted file mode 100644 index 5b8b6a8799002e..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/902-020-ath11k-add-btcoex-config.patch +++ /dev/null @@ -1,612 +0,0 @@ ---- a/drivers/net/wireless/ath/ath11k/Makefile -+++ b/drivers/net/wireless/ath/ath11k/Makefile -@@ -17,7 +17,8 @@ ath11k-y += core.o \ - peer.o \ - dbring.o \ - hw.o \ -- pcic.o -+ pcic.o \ -+ vendor.o - - ath11k-$(CPTCFG_ATH11K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o - ath11k-$(CPTCFG_NL80211_TESTMODE) += testmode.o ---- a/drivers/net/wireless/ath/ath11k/core.h -+++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -627,6 +627,16 @@ struct ath11k_per_peer_tx_stats { - #define ATH11K_FLUSH_TIMEOUT (5 * HZ) - #define ATH11K_VDEV_DELETE_TIMEOUT_HZ (5 * HZ) - -+struct ath11k_coex_info { -+ bool coex_support; -+ u32 pta_num; -+ u32 coex_mode; -+ u32 bt_active_time_slot; -+ u32 bt_priority_time_slot; -+ u32 coex_algo_type; -+ u32 pta_priority; -+}; -+ - struct ath11k { - struct ath11k_base *ab; - struct ath11k_pdev *pdev; -@@ -750,6 +760,8 @@ struct ath11k { - struct ath11k_per_peer_tx_stats cached_stats; - u32 last_ppdu_id; - u32 cached_ppdu_id; -+ -+ struct ath11k_coex_info coex; - int monitor_vdev_id; - struct completion fw_mode_reset; - u8 ftm_msgref; ---- a/drivers/net/wireless/ath/ath11k/mac.c -+++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -24,6 +25,7 @@ - #include "debugfs_sta.h" - #include "hif.h" - #include "wow.h" -+#include "vendor.h" - #include "nss.h" - - #define CHAN2G(_channel, _freq, _flags) { \ -@@ -9284,6 +9286,91 @@ err_fallback: - return 0; - } - -+#define ATH11K_WLAN_PRIO_MAX 0x63 -+#define ATH11K_WLAN_PRIO_WEIGHT 0xff -+ -+int ath11k_mac_coex_config(struct ath11k *ar, struct ath11k_vif *arvif, -+ int coex, u32 wlan_prio_mask, u8 wlan_weight) -+{ -+ struct coex_config_arg coex_config; -+ int ret; -+ -+ if (ar->state != ATH11K_STATE_ON && -+ ar->state != ATH11K_STATE_RESTARTED) -+ return -ENETDOWN; -+ -+ if (coex == -1 || !(test_bit(ATH11K_FLAG_BTCOEX, &ar->ab->dev_flags) ^ coex)) -+ goto next; -+ -+ coex_config.vdev_id = arvif->vdev_id; -+ if (coex == 1) { -+ coex_config.config_type = WMI_COEX_CONFIG_PTA_INTERFACE; -+ coex_config.pta_num = ar->coex.pta_num; -+ coex_config.coex_mode = ar->coex.coex_mode; -+ coex_config.bt_txrx_time = ar->coex.bt_active_time_slot; -+ coex_config.bt_priority_time = ar->coex.bt_priority_time_slot; -+ coex_config.pta_algorithm = ar->coex.coex_algo_type; -+ coex_config.pta_priority = ar->coex.pta_priority; -+ ret = ath11k_send_coex_config_cmd(ar, &coex_config); -+ if (ret) { -+ ath11k_warn(ar->ab, -+ "failed to set coex config vdev_id %d ret %d\n", -+ coex_config.vdev_id, ret); -+ goto out; -+ } -+ } -+ -+ memset(&coex_config, 0, sizeof(struct coex_config_arg)); -+ coex_config.vdev_id = arvif->vdev_id; -+ coex_config.config_type = WMI_COEX_CONFIG_BTC_ENABLE; -+ coex_config.coex_enable = coex; -+ ret = ath11k_send_coex_config_cmd(ar, &coex_config); -+ if (ret) { -+ ath11k_warn(ar->ab, -+ "failed to set coex config vdev_id %d ret %d\n", -+ coex_config.vdev_id, ret); -+ goto out; -+ } -+ -+ if (coex) -+ set_bit(ATH11K_FLAG_BTCOEX, &ar->ab->dev_flags); -+ else -+ clear_bit(ATH11K_FLAG_BTCOEX, &ar->ab->dev_flags); -+ -+next: -+ if (!wlan_prio_mask) { -+ ret = 0; -+ goto out; -+ } -+ -+ if (!(test_bit(ATH11K_FLAG_BTCOEX, &ar->ab->dev_flags))) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ if (wlan_prio_mask > ATH11K_WLAN_PRIO_MAX || -+ wlan_weight > ATH11K_WLAN_PRIO_WEIGHT) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ memset(&coex_config, 0, sizeof(struct coex_config_arg)); -+ coex_config.vdev_id = arvif->vdev_id; -+ coex_config.config_type = WMI_COEX_CONFIG_WLAN_PKT_PRIORITY; -+ coex_config.wlan_pkt_type = wlan_prio_mask; -+ coex_config.wlan_pkt_weight = wlan_weight; -+ ret = ath11k_send_coex_config_cmd(ar, &coex_config); -+ if (ret) { -+ ath11k_warn(ar->ab, -+ "failed to set coex config vdev_id %d ret %d\n", -+ coex_config.vdev_id, ret); -+ goto out; -+ } -+ -+out: -+ return ret; -+} -+ - static const struct ieee80211_ops ath11k_ops = { - .tx = ath11k_mac_op_tx, - .wake_tx_queue = ieee80211_handle_wake_tx_queue, -@@ -9523,6 +9610,56 @@ static int ath11k_mac_setup_iface_combin - return 0; - } - -+static void ath11k_mac_fetch_coex_info(struct ath11k *ar) -+{ -+ struct ath11k_pdev_cap *cap = &ar->pdev->cap; -+ struct ath11k_base *ab = ar->ab; -+ struct device *dev = ab->dev; -+ -+ ar->coex.coex_support = false; -+ -+ if (!(cap->supported_bands & WMI_HOST_WLAN_2G_CAP)) -+ return; -+ -+ if (of_property_read_u32(dev->of_node, "qcom,pta-num", -+ &ar->coex.pta_num)) { -+ ath11k_err(ab, "No qcom,pta_num entry in dev-tree.\n"); -+ } -+ -+ if (of_property_read_u32(dev->of_node, "qcom,coex-mode", -+ &ar->coex.coex_mode)) { -+ ath11k_err(ab, "No qcom,coex_mode entry in dev-tree.\n"); -+ } -+ -+ if (of_property_read_u32(dev->of_node, "qcom,bt-active-time", -+ &ar->coex.bt_active_time_slot)) { -+ ath11k_err(ab, "No qcom,bt-active-time entry in dev-tree.\n"); -+ } -+ -+ if (of_property_read_u32(dev->of_node, "qcom,bt-priority-time", -+ &ar->coex.bt_priority_time_slot)) { -+ ath11k_err(ab, "No qcom,bt-priority-time entry in dev-tree.\n"); -+ } -+ -+ if (of_property_read_u32(dev->of_node, "qcom,coex-algo", -+ &ar->coex.coex_algo_type)) { -+ ath11k_err(ab, "No qcom,coex-algo entry in dev-tree.\n"); -+ } -+ -+ if (of_property_read_u32(dev->of_node, "qcom,pta-priority", -+ &ar->coex.pta_priority)) { -+ ath11k_err(ab, "No qcom,pta-priority entry in dev-tree.\n"); -+ } -+ -+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "coex pta_num %u coex_mode %u" -+ " bt_active_time_slot %u bt_priority_time_slot %u" -+ " coex_algorithm %u pta_priority %u\n", ar->coex.pta_num, -+ ar->coex.coex_mode, ar->coex.bt_active_time_slot, -+ ar->coex.bt_priority_time_slot, ar->coex.coex_algo_type, -+ ar->coex.pta_priority); -+ ar->coex.coex_support = true; -+} -+ - static const u8 ath11k_if_types_ext_capa[] = { - [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, - [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT, -@@ -9786,6 +9923,7 @@ static int __ath11k_mac_register(struct - ar->hw->wiphy->ema_max_profile_periodicity = TARGET_EMA_MAX_PROFILE_PERIOD; - - ath11k_reg_init(ar); -+ ath11k_vendor_register(ar); - - if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) { - ar->hw->netdev_features = NETIF_F_HW_CSUM; -@@ -9951,6 +10089,7 @@ int ath11k_mac_allocate(struct ath11k_ba - */ - ath11k_wmi_pdev_attach(ab, i); - -+ ath11k_mac_fetch_coex_info(ar); - ar->cfg_tx_chainmask = pdev->cap.tx_chain_mask; - ar->cfg_rx_chainmask = pdev->cap.rx_chain_mask; - ar->num_tx_chains = get_num_chains(pdev->cap.tx_chain_mask); ---- a/drivers/net/wireless/ath/ath11k/mac.h -+++ b/drivers/net/wireless/ath/ath11k/mac.h -@@ -150,8 +150,9 @@ void __ath11k_mac_scan_finish(struct ath - void ath11k_mac_scan_finish(struct ath11k *ar); - - struct ath11k_vif *ath11k_mac_get_arvif(struct ath11k *ar, u32 vdev_id); --struct ath11k_vif *ath11k_mac_get_arvif_by_vdev_id(struct ath11k_base *ab, -- u32 vdev_id); -+struct ath11k_vif *ath11k_mac_get_arvif_by_vdev_id(struct ath11k_base *ab, u32 vdev_id); -+int ath11k_mac_coex_config(struct ath11k *ar, struct ath11k_vif *arvif, -+ int coex, u32 wlan_prio_mask, u8 wlan_weight); - u8 ath11k_mac_get_target_pdev_id(struct ath11k *ar); - u8 ath11k_mac_get_target_pdev_id_from_vif(struct ath11k_vif *arvif); - struct ath11k_vif *ath11k_mac_get_vif_up(struct ath11k_base *ab); ---- /dev/null -+++ b/drivers/net/wireless/ath/ath11k/vendor.c -@@ -0,0 +1,121 @@ -+// SPDX-License-Identifier: ISC -+/* -+ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. -+ */ -+ -+#include -+#include -+#include "core.h" -+#include "vendor.h" -+#include "debug.h" -+ -+static const struct nla_policy -+ath11k_vendor_btcoex_config_policy[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_MAX + 1] = { -+ [QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE] = { .type = NLA_U8 }, -+ [QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY] = { .type = NLA_NESTED }, -+}; -+ -+static const struct nla_policy -+ath11k_vendor_wlan_prio_policy[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MAX + 1] = { -+ [QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK] = { .type = NLA_U8 }, -+ [QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT] = { .type = NLA_U8 }, -+}; -+ -+static int ath11k_vendor_btcoex_configure(struct wiphy *wiphy, -+ 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_BTCOEX_CONFIG_MAX + 1]; -+ struct nlattr *tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MAX + 1]; -+ struct nlattr *wlan_prio; -+ enum qca_wlan_priority_type wlan_prio_mask = 0; -+ int ret, coex = -1, rem_conf; -+ u8 wlan_weight = 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_BTCOEX_CONFIG_MAX, data, data_len, -+ ath11k_vendor_btcoex_config_policy, NULL); -+ if (ret) { -+ ath11k_warn(ar->ab, "invalid BTCOEX config policy attribute\n"); -+ goto out; -+ } -+ -+ if (!tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE] && -+ !tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY]) { -+ ath11k_warn(ar->ab, "invalid BTCOEX config attributes\n"); -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ if (tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE]) { -+ coex = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE]); -+ ret = ath11k_mac_coex_config(ar, arvif, coex, wlan_prio_mask, wlan_weight); -+ if (ret) -+ goto out; -+ } -+ if (tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY]) { -+ nla_for_each_nested(wlan_prio, -+ tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY], -+ rem_conf) { -+ ret = -+ nla_parse_nested(tb_wlan_prio, QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MAX, -+ wlan_prio, ath11k_vendor_wlan_prio_policy, -+ NULL); -+ if (ret) -+ goto out; -+ wlan_prio_mask = -+ nla_get_u8(tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK]); -+ if (tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT]) -+ wlan_weight = -+ nla_get_u8(tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT]); -+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, -+ "BTCOEX enable %u WLAN Priority %u wlan weight %u\n", -+ coex, wlan_prio_mask, wlan_weight); -+ -+ ret = ath11k_mac_coex_config(ar, arvif, coex, wlan_prio_mask, wlan_weight); -+ if (ret) -+ goto out; -+ } -+ } -+ -+out: -+ mutex_unlock(&ar->conf_mutex); -+ return ret; -+} -+ -+static struct wiphy_vendor_command ath11k_vendor_commands[] = { -+ { -+ .info.vendor_id = QCA_NL80211_VENDOR_ID, -+ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_BTCOEX_CONFIG, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | -+ WIPHY_VENDOR_CMD_NEED_RUNNING, -+ .doit = ath11k_vendor_btcoex_configure, -+ .policy = ath11k_vendor_btcoex_config_policy -+ } -+}; -+ -+int ath11k_vendor_register(struct ath11k *ar) -+{ -+ ar->hw->wiphy->vendor_commands = ath11k_vendor_commands; -+ ar->hw->wiphy->n_vendor_commands = ARRAY_SIZE(ath11k_vendor_commands); -+ -+ return 0; -+} ---- /dev/null -+++ b/drivers/net/wireless/ath/ath11k/vendor.h -@@ -0,0 +1,83 @@ -+/* SPDX-License-Identifier: ISC */ -+/* -+ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. -+ */ -+ -+#ifndef ATH11K_VENDOR_H -+#define ATH11K_VENDOR_H -+ -+#define QCA_NL80211_VENDOR_ID 0x001374 -+ -+enum qca_nl80211_vendor_subcmds { -+ /* 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 -+ * enum qca-vendor_attr_btcoex_config. -+ */ -+ QCA_NL80211_VENDOR_SUBCMD_BTCOEX_CONFIG = 182, -+}; -+ -+/* -+ * enum qca_wlan_priority_type - priority mask -+ * This enum defines priority mask that user can configure -+ * over BT traffic type which can be passed through -+ * QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY attribute. -+ * -+ * @QCA_WLAN_PRIORITY_BE: Bit mask for WLAN Best effort traffic -+ * @QCA_WLAN_PRIORITY_BK: Bit mask for WLAN Background traffic -+ * @QCA_WLAN_PRIORITY_VI: Bit mask for WLAN Video traffic -+ * @QCA_WLAN_PRIORITY_VO: Bit mask for WLAN Voice traffic -+ * @QCA_WLAN_PRIORITY_BEACON: Bit mask for WLAN BEACON frame -+ * @QCA_WLAN_PRIORITY_MGMT: Bit mask for WLAN Management frame -+*/ -+enum qca_wlan_priority_type { -+ QCA_WLAN_PRIORITY_BE = BIT(0), -+ QCA_WLAN_PRIORITY_BK = BIT(1), -+ QCA_WLAN_PRIORITY_VI = BIT(2), -+ QCA_WLAN_PRIORITY_VO = BIT(3), -+ QCA_WLAN_PRIORITY_BEACON = BIT(4), -+ QCA_WLAN_PRIORITY_MGMT = BIT(5), -+}; -+ -+/** -+ * enum qca_wlan_vendor_attr_wlan_prio - Used to configure -+ * WLAN priority mask and its respective weight value. -+ * @QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK - This is u8 attribute -+ * used to pass traffic type mask value see %qca_wlan_priority_type -+ * @QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT - This is u8 attribute -+ * accepts value between 0 and 255 and used to configure weight for -+ * traffic type mentioned in %QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK. -+ */ -+enum qca_wlan_vendor_attr_wlan_prio { -+ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_INVALID = 0, -+ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK = 1, -+ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT = 2, -+ -+ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_LAST, -+ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MAX = -+ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_LAST - 1, -+}; -+ -+ -+ -+/** -+ * enum qca_wlan_vendor_attr_btcoex_config - Used by the vendor command -+ * The use can enable/disable BTCOEX and configure WLAN priority for -+ * different traffic type over BT. -+ * QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE, enable/disable BTCOEX -+ * QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY, This is a nested -+ * attribute pass the attributes in %qca_wlan_vendor_attr_wlan_prio. -+ */ -+enum qca_wlan_vendor_attr_btcoex_config { -+ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_INVALID = 0, -+ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE = 1, -+ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY = 2, -+ -+ /* keep last */ -+ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_LAST, -+ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_MAX = -+ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_LAST - 1 -+}; -+ -+int ath11k_vendor_register(struct ath11k *ar); -+#endif /* QCA_VENDOR_H */ ---- a/drivers/net/wireless/ath/ath11k/wmi.c -+++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -1743,6 +1743,71 @@ int ath11k_wmi_vdev_set_param_cmd(struct - return ret; - } - -+static void ath11k_wmi_copy_coex_config(struct ath11k *ar, struct wmi_coex_config_cmd *cmd, -+ struct coex_config_arg *coex_config) -+{ -+ if (coex_config->config_type == WMI_COEX_CONFIG_BTC_ENABLE) { -+ cmd->coex_enable = coex_config->coex_enable; -+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, -+ "WMI coex config type %u vdev id %d coex_enable %u\n", -+ coex_config->config_type, coex_config->vdev_id, -+ coex_config->coex_enable); -+ } -+ -+ if (coex_config->config_type == WMI_COEX_CONFIG_WLAN_PKT_PRIORITY) { -+ cmd->wlan_pkt_type = coex_config->wlan_pkt_type; -+ cmd->wlan_pkt_weight = coex_config->wlan_pkt_weight; -+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, -+ "WMI coex config type %u vdev id %d wlan pkt type 0x%x wlan pkt weight %u\n", -+ coex_config->config_type, coex_config->vdev_id, -+ coex_config->wlan_pkt_type, coex_config->wlan_pkt_weight); -+ } -+ -+ if (coex_config->config_type == WMI_COEX_CONFIG_PTA_INTERFACE) { -+ cmd->pta_num = coex_config->pta_num; -+ cmd->coex_mode = coex_config->coex_mode; -+ cmd->bt_txrx_time = coex_config->bt_txrx_time; -+ cmd->bt_priority_time = coex_config->bt_priority_time; -+ cmd->pta_algorithm = coex_config->pta_algorithm; -+ cmd->pta_priority = coex_config->pta_priority; -+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, -+ "WMI coex config type %u vdev id %d pta num %u coex mode %u bt_txrx_time %u bt_priority_time %u pta alogrithm %u pta priority %u\n", -+ coex_config->config_type, coex_config->vdev_id, -+ coex_config->pta_num, coex_config->coex_mode, -+ coex_config->bt_txrx_time, coex_config->bt_priority_time, -+ coex_config->pta_algorithm, coex_config->pta_priority); -+ } -+} -+ -+int ath11k_send_coex_config_cmd(struct ath11k *ar, -+ struct coex_config_arg *coex_config) -+{ -+ struct ath11k_pdev_wmi *wmi = ar->wmi; -+ struct wmi_coex_config_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_coex_config_cmd *)skb->data; -+ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_COEX_CONFIG_CMD) | -+ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); -+ -+ cmd->vdev_id = coex_config->vdev_id; -+ cmd->config_type = coex_config->config_type; -+ ath11k_wmi_copy_coex_config(ar, cmd, coex_config); -+ -+ ret = ath11k_wmi_cmd_send(wmi, skb, WMI_COEX_CONFIG_CMDID); -+ if (ret) { -+ ath11k_warn(ar->ab, "failed to send WMI_COEX_CONFIG_CMD cmd\n"); -+ dev_kfree_skb(skb); -+ } -+ -+ return ret; -+} -+ - int ath11k_wmi_send_stats_request_cmd(struct ath11k *ar, - struct stats_request_params *param) - { ---- a/drivers/net/wireless/ath/ath11k/wmi.h -+++ b/drivers/net/wireless/ath/ath11k/wmi.h -@@ -5333,6 +5333,79 @@ struct wmi_wmm_params_arg { - u8 no_ack; - }; - -+enum wmi_coex_config_type { -+ WMI_COEX_CONFIG_PAGE_P2P_TDM = 1, -+ WMI_COEX_CONFIG_PAGE_STA_TDM = 2, -+ WMI_COEX_CONFIG_PAGE_SAP_TDM = 3, -+ WMI_COEX_CONFIG_DURING_WLAN_CONN = 4, -+ WMI_COEX_CONFIG_BTC_ENABLE = 5, -+ WMI_COEX_CONFIG_COEX_DBG = 6, -+ WMI_COEX_CONFIG_PAGE_P2P_STA_TDM = 7, -+ WMI_COEX_CONFIG_INQUIRY_P2P_TDM = 8, -+ WMI_COEX_CONFIG_INQUIRY_STA_TDM = 9, -+ WMI_COEX_CONFIG_INQUIRY_SAP_TDM = 10, -+ WMI_COEX_CONFIG_INQUIRY_P2P_STA_TDM = 11, -+ WMI_COEX_CONFIG_TX_POWER = 12, -+ WMI_COEX_CONFIG_PTA_CONFIG = 13, -+ WMI_COEX_CONFIG_AP_TDM = 14, -+ WMI_COEX_CONFIG_WLAN_SCAN_PRIORITY = 15, -+ WMI_COEX_CONFIG_WLAN_PKT_PRIORITY = 16, -+ WMI_COEX_CONFIG_PTA_INTERFACE = 17, -+}; -+ -+struct coex_config_arg { -+ u32 vdev_id; -+ u32 config_type; -+ union { -+ struct { -+ u32 coex_enable; -+ }; -+ -+ struct { -+ u32 pta_num; -+ u32 coex_mode; -+ u32 bt_txrx_time; -+ u32 bt_priority_time; -+ u32 pta_algorithm; -+ u32 pta_priority; -+ }; -+ -+ struct { -+ u32 wlan_pkt_type; -+ u32 wlan_pkt_type_continued; -+ u32 wlan_pkt_weight; -+ u32 bt_pkt_weight; -+ }; -+ }; -+}; -+ -+struct wmi_coex_config_cmd { -+ u32 tlv_header; -+ u32 vdev_id; -+ u32 config_type; -+ union { -+ struct { -+ u32 coex_enable; -+ } __packed; -+ -+ struct { -+ u32 pta_num; -+ u32 coex_mode; -+ u32 bt_txrx_time; -+ u32 bt_priority_time; -+ u32 pta_algorithm; -+ u32 pta_priority; -+ } __packed; -+ -+ struct { -+ u32 wlan_pkt_type; -+ u32 wlan_pkt_type_continued; -+ u32 wlan_pkt_weight; -+ u32 bt_pkt_weight; -+ } __packed; -+ } __packed; -+} __packed; -+ - struct wmi_vdev_set_wmm_params_cmd { - u32 tlv_header; - u32 vdev_id; -@@ -6553,6 +6626,8 @@ int ath11k_wmi_pdev_non_srg_obss_color_e - u32 *bitmap); - int ath11k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(struct ath11k *ar, - u32 *bitmap); -+int ath11k_send_coex_config_cmd(struct ath11k *ar, -+ struct coex_config_arg *coex_config); - 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/nss/ath11k/902-022-ath11k-add-ap-ps-support.patch b/package/kernel/mac80211/patches/nss/ath11k/902-022-ath11k-add-ap-ps-support.patch deleted file mode 100644 index 88c6d85aff1e02..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/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; -@@ -6564,6 +6600,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); -@@ -6971,7 +7008,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); -@@ -7118,6 +7154,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; -@@ -7225,6 +7265,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/nss/ath11k/902-069-ath11k-add-HE-stats-in-peer-stats.patch b/package/kernel/mac80211/patches/nss/ath11k/902-069-ath11k-add-HE-stats-in-peer-stats.patch index 7bdd430721203f..4831424fa40810 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/902-069-ath11k-add-HE-stats-in-peer-stats.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/902-069-ath11k-add-HE-stats-in-peer-stats.patch @@ -21,9 +21,9 @@ Signed-off-by: Miles Hu #include "wow.h" +#include "rx_desc.h" #include "nss.h" - #include "vendor.h" -@@ -478,6 +479,8 @@ struct ath11k_htt_data_stats { + #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) +@@ -476,6 +477,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 { -@@ -485,6 +488,9 @@ struct ath11k_htt_tx_stats { +@@ -483,6 +486,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 { -@@ -617,11 +623,16 @@ struct ath11k_per_peer_tx_stats { +@@ -615,11 +621,16 @@ struct ath11k_per_peer_tx_stats { u32 succ_bytes; u32 retry_bytes; u32 failed_bytes; diff --git a/package/kernel/mac80211/patches/nss/ath11k/903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch b/package/kernel/mac80211/patches/nss/ath11k/903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch index bfc938986e149b..f5af428e338e5e 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch @@ -33,20 +33,17 @@ Signed-off-by: Sathishkumar Muruganandam --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -387,9 +387,8 @@ struct ath11k_vif { - #endif /* CPTCFG_ATH11K_DEBUGFS */ - - struct ath11k_mgmt_frame_stats mgmt_stats; --#ifdef CPTCFG_ATH11K_NSS_SUPPORT +@@ -377,6 +377,7 @@ struct ath11k_vif { + #ifdef CPTCFG_ATH11K_NSS_SUPPORT struct arvif_nss nss; --#endif + #endif + struct list_head ap_vlan_arvifs; }; struct ath11k_vif_iter { --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -4739,6 +4739,11 @@ static void ath11k_sta_rc_update_wk(stru +@@ -4737,6 +4737,11 @@ static void ath11k_sta_rc_update_wk(stru arvif = arsta->arvif; ar = arvif->ar; @@ -58,7 +55,7 @@ Signed-off-by: Sathishkumar Muruganandam if (WARN_ON(ath11k_mac_vif_chan(arvif->vif, &def))) return; -@@ -4910,17 +4915,28 @@ err_rc_bw_changed: +@@ -4908,17 +4913,28 @@ err_rc_bw_changed: static void ath11k_sta_set_4addr_wk(struct work_struct *wk) { struct ath11k *ar; @@ -89,7 +86,7 @@ Signed-off-by: Sathishkumar Muruganandam "setting USE_4ADDR for peer %pM\n", sta->addr); ret = ath11k_wmi_set_peer_param(ar, sta->addr, -@@ -4928,8 +4944,93 @@ static void ath11k_sta_set_4addr_wk(stru +@@ -4926,8 +4942,93 @@ static void ath11k_sta_set_4addr_wk(stru WMI_PEER_USE_4ADDR, 1); if (ret) @@ -184,7 +181,7 @@ Signed-off-by: Sathishkumar Muruganandam } static int ath11k_mac_inc_num_stations(struct ath11k_vif *arvif, -@@ -5314,9 +5415,32 @@ static void ath11k_mac_op_sta_set_4addr( +@@ -5276,9 +5377,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; } -@@ -6708,6 +6832,9 @@ static int ath11k_mac_op_update_vif_offl +@@ -6658,6 +6782,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 && -@@ -6928,7 +7055,8 @@ static int ath11k_mac_op_add_interface(s +@@ -6878,7 +7005,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; -@@ -6948,6 +7076,28 @@ static int ath11k_mac_op_add_interface(s +@@ -6898,6 +7026,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); -@@ -6977,6 +7127,7 @@ static int ath11k_mac_op_add_interface(s +@@ -6927,6 +7077,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; -@@ -7202,13 +7353,30 @@ static void ath11k_mac_op_remove_interfa +@@ -7149,13 +7300,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); -@@ -7225,6 +7393,14 @@ static void ath11k_mac_op_remove_interfa +@@ -7172,6 +7340,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); -@@ -7269,8 +7445,7 @@ err_vdev_del: +@@ -7215,8 +7391,7 @@ err_vdev_del: ath11k_debugfs_remove_interface(arvif); @@ -332,7 +329,7 @@ Signed-off-by: Sathishkumar Muruganandam mutex_unlock(&ar->conf_mutex); } -@@ -7330,16 +7505,17 @@ static int ath11k_mac_op_ampdu_action(st +@@ -7276,16 +7451,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: -@@ -8862,6 +9038,7 @@ static void ath11k_mac_op_sta_statistics +@@ -8808,6 +8984,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); -@@ -8918,7 +9095,8 @@ static void ath11k_mac_op_sta_statistics +@@ -8864,7 +9041,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 -@@ -5075,6 +5075,8 @@ enum wmi_vdev_subtype { +@@ -5070,6 +5070,8 @@ enum wmi_vdev_subtype { WMI_VDEV_SUBTYPE_MESH_11S, }; @@ -497,7 +494,7 @@ Signed-off-by: Sathishkumar Muruganandam ATH11K_WDS_WMI_MAX }; -@@ -126,6 +127,8 @@ int ath11k_peer_rhash_delete(struct ath1 +@@ -112,6 +113,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 +@@ -131,6 +134,12 @@ static inline struct ath11k_ast_entry *a { return NULL; } diff --git a/package/kernel/mac80211/patches/nss/ath11k/905-ath11k-add-support-memory-stats.patch b/package/kernel/mac80211/patches/nss/ath11k/905-ath11k-add-support-memory-stats.patch index fc64af54958996..fabfbaba24ecdf 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/905-ath11k-add-support-memory-stats.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/905-ath11k-add-support-memory-stats.patch @@ -141,7 +141,7 @@ Signed-off-by: Maharaja Kennadyrajan } --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c -@@ -2145,6 +2145,8 @@ int ath11k_core_pre_init(struct ath11k_b +@@ -2144,6 +2144,8 @@ int ath11k_core_pre_init(struct ath11k_b if (nss_offload) ab->nss.stats_enabled = 1; @@ -152,7 +152,7 @@ Signed-off-by: Maharaja Kennadyrajan EXPORT_SYMBOL(ath11k_core_pre_init); --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -939,6 +939,23 @@ struct ath11k_num_vdevs_peers { +@@ -909,6 +909,23 @@ struct ath11k_num_vdevs_peers { u32 num_peers; }; @@ -176,7 +176,7 @@ Signed-off-by: Maharaja Kennadyrajan /* Master structure to hold the hw data which may be used in core module */ struct ath11k_base { enum ath11k_hw_rev hw_rev; -@@ -1028,6 +1045,7 @@ struct ath11k_base { +@@ -998,6 +1015,7 @@ struct ath11k_base { enum ath11k_dfs_region dfs_region; #ifdef CPTCFG_ATH11K_DEBUGFS struct dentry *debugfs_soc; @@ -184,14 +184,14 @@ Signed-off-by: Maharaja Kennadyrajan #endif struct ath11k_soc_dp_stats soc_stats; -@@ -1094,6 +1112,7 @@ struct ath11k_base { +@@ -1064,6 +1082,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; + + u32 max_ast_index; --- 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 @@ -231,7 +231,7 @@ Signed-off-by: Maharaja Kennadyrajan return retval; } -@@ -1094,6 +1098,106 @@ static const struct file_operations fops +@@ -1045,6 +1049,106 @@ static const struct file_operations fops .write = ath11k_write_stats_disable, }; @@ -338,9 +338,9 @@ Signed-off-by: Maharaja Kennadyrajan 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); +@@ -1060,6 +1164,12 @@ int ath11k_debugfs_pdev_create(struct at + debugfs_create_file("sram", 0400, ab->debugfs_soc, ab, + &fops_sram_dump); + debugfs_create_file("enable_memory_stats", 0600, ab->debugfs_soc, + ab, &fops_enable_memory_stats); @@ -348,10 +348,10 @@ Signed-off-by: Maharaja Kennadyrajan + debugfs_create_file("memory_stats", 0600, ab->debugfs_soc, ab, + &fops_memory_stats); + - return 0; } -@@ -1739,6 +1849,8 @@ static ssize_t ath11k_dump_mgmt_stats(st + +@@ -1686,6 +1796,8 @@ static ssize_t ath11k_dump_mgmt_stats(st if (!buf) return -ENOMEM; @@ -360,16 +360,6 @@ Signed-off-by: Maharaja Kennadyrajan mutex_lock(&ar->conf_mutex); spin_lock_bh(&ar->data_lock); -@@ -1789,6 +1901,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 @@ @@ -431,7 +421,7 @@ Signed-off-by: Maharaja Kennadyrajan 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 +@@ -333,6 +333,8 @@ static ssize_t ath11k_dbg_sta_dump_rx_st retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); kfree(buf); @@ -616,7 +606,7 @@ Signed-off-by: Maharaja Kennadyrajan --- 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 +@@ -4052,6 +4052,8 @@ static int ath11k_mac_op_hw_scan(struct goto exit; } @@ -625,7 +615,7 @@ Signed-off-by: Maharaja Kennadyrajan 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 +@@ -4065,6 +4067,8 @@ static int ath11k_mac_op_hw_scan(struct arg->extraie.len = req->ie_len; } @@ -634,7 +624,7 @@ Signed-off-by: Maharaja Kennadyrajan 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 +@@ -4151,9 +4155,16 @@ static int ath11k_mac_op_hw_scan(struct exit: if (arg) { kfree(arg->chan_list); @@ -654,7 +644,7 @@ Signed-off-by: Maharaja Kennadyrajan mutex_unlock(&ar->conf_mutex); -@@ -8152,6 +8163,8 @@ ath11k_mac_update_active_vif_chan(struct +@@ -8105,6 +8116,8 @@ ath11k_mac_update_active_vif_chan(struct if (!arg.vifs) return; @@ -663,7 +653,7 @@ Signed-off-by: Maharaja Kennadyrajan ieee80211_iterate_active_interfaces_atomic(ar->hw, IEEE80211_IFACE_ITER_NORMAL, ath11k_mac_change_chanctx_fill_iter, -@@ -8159,6 +8172,8 @@ ath11k_mac_update_active_vif_chan(struct +@@ -8112,6 +8125,8 @@ ath11k_mac_update_active_vif_chan(struct ath11k_mac_update_vif_chan(ar, arg.vifs, arg.n_vifs); @@ -908,7 +898,7 @@ Signed-off-by: Maharaja Kennadyrajan ar->num_peers--; return 0; -@@ -902,6 +905,8 @@ int ath11k_peer_create(struct ath11k *ar +@@ -901,6 +904,8 @@ int ath11k_peer_create(struct ath11k *ar arsta->tcl_metadata &= ~HTT_TCL_META_DATA_VALID_HTT; } @@ -928,7 +918,7 @@ Signed-off-by: Maharaja Kennadyrajan skb_reserve(skb, WMI_SKB_HEADROOM); if (!IS_ALIGNED((unsigned long)skb->data, 4)) ath11k_warn(ab, "unaligned WMI skb data\n"); -@@ -7346,6 +7348,7 @@ static void ath11k_wmi_htc_tx_complete(s +@@ -7242,6 +7244,7 @@ static void ath11k_wmi_htc_tx_complete(s u8 eid; eid = ATH11K_SKB_CB(skb)->eid; @@ -936,7 +926,7 @@ Signed-off-by: Maharaja Kennadyrajan dev_kfree_skb(skb); if (eid >= ATH11K_HTC_EP_COUNT) -@@ -9139,6 +9142,7 @@ static void ath11k_wmi_tlv_op_rx(struct +@@ -9035,6 +9038,7 @@ static void ath11k_wmi_tlv_op_rx(struct } out: diff --git a/package/kernel/mac80211/patches/nss/ath11k/907-068-ath11k-add-rx-histogram-stats.patch b/package/kernel/mac80211/patches/nss/ath11k/907-068-ath11k-add-rx-histogram-stats.patch deleted file mode 100644 index 17ded34963fd0f..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/907-068-ath11k-add-rx-histogram-stats.patch +++ /dev/null @@ -1,608 +0,0 @@ -From 4635ca1f29bc5838d556b09e3c186b76a5198ddb Mon Sep 17 00:00:00 2001 -From: Manikanta Pubbisetty -Date: Fri, 18 Aug 2023 11:43:33 +0530 -Subject: [PATCH] ath11k: add rx histogram stats - -Adding rx rate table and byte level peer rx statistics. Also, -adding a debugfs knob to reset rx stats specific to the peer. - -Signed-off-by: Manikanta Pubbisetty ---- - drivers/net/wireless/ath/ath11k/core.h | 19 ++- - drivers/net/wireless/ath/ath11k/debugfs_sta.c | 152 ++++++++++++++++-- - drivers/net/wireless/ath/ath11k/dp_rx.c | 95 +++++++++-- - drivers/net/wireless/ath/ath11k/dp_rx.h | 19 +++ - drivers/net/wireless/ath/ath11k/hal_rx.c | 85 +++++++--- - drivers/net/wireless/ath/ath11k/hal_rx.h | 21 +++ - drivers/net/wireless/ath/ath11k/hw.c | 18 +++ - drivers/net/wireless/ath/ath11k/hw.h | 1 + - 8 files changed, 351 insertions(+), 59 deletions(-) - ---- a/drivers/net/wireless/ath/ath11k/core.h -+++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -44,6 +44,8 @@ - - #define ATH11K_INVALID_HW_MAC_ID 0xFF - #define ATH11K_CONNECTION_LOSS_HZ (3 * HZ) -+#define ATH11K_RX_RATE_TABLE_NUM 320 -+#define ATH11K_RX_RATE_TABLE_11AX_NUM 576 - - /* SMBIOS type containing Board Data File Name Extension */ - #define ATH11K_SMBIOS_BDF_EXT_TYPE 0xF8 -@@ -420,6 +422,17 @@ struct ath11k_vif_iter { - struct ath11k_vif *arvif; - }; - -+struct ath11k_rx_peer_rate_stats { -+ u64 ht_mcs_count[HAL_RX_MAX_MCS_HT + 1]; -+ u64 vht_mcs_count[HAL_RX_MAX_MCS_VHT + 1]; -+ u64 he_mcs_count[HAL_RX_MAX_MCS_HE + 1]; -+ u64 nss_count[HAL_RX_MAX_NSS]; -+ u64 bw_count[HAL_RX_BW_MAX]; -+ u64 gi_count[HAL_RX_GI_MAX]; -+ u64 legacy_count[HAL_RX_MAX_NUM_LEGACY_RATES]; -+ u64 rx_rate[ATH11K_RX_RATE_TABLE_11AX_NUM]; -+}; -+ - struct ath11k_rx_peer_stats { - u64 num_msdu; - u64 num_mpdu_fcs_ok; -@@ -431,10 +444,6 @@ struct ath11k_rx_peer_stats { - u64 non_ampdu_msdu_count; - u64 stbc_count; - u64 beamformed_count; -- u64 mcs_count[HAL_RX_MAX_MCS + 1]; -- u64 nss_count[HAL_RX_MAX_NSS]; -- u64 bw_count[HAL_RX_BW_MAX]; -- u64 gi_count[HAL_RX_GI_MAX]; - 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 { - u64 rx_duration; - u64 dcm_count; - u64 ru_alloc_cnt[HAL_RX_RU_ALLOC_TYPE_MAX]; -+ struct ath11k_rx_peer_rate_stats pkt_stats; -+ struct ath11k_rx_peer_rate_stats byte_stats; - }; - - #define ATH11K_HE_MCS_NUM 12 ---- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c -+++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c -@@ -10,6 +10,7 @@ - #include "peer.h" - #include "debug.h" - #include "dp_tx.h" -+#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 - struct ath11k *ar = arsta->arvif->ar; - struct ath11k_rx_peer_stats *rx_stats = arsta->rx_stats; - int len = 0, i, retval = 0; -- const int size = 4096; -+ const int size = 4 * 4096; - char *buf; -+ int he_rates_avail = (rx_stats->pream_cnt[HAL_RX_PREAMBLE_11AX] > 1) ? 1 : 0; -+ int rate_table_len = he_rates_avail ? ATH11K_RX_RATE_TABLE_11AX_NUM : -+ ATH11K_RX_RATE_TABLE_NUM; -+ char *legacy_rate_str[] = {"1Mbps", "2Mbps", "5.5Mbps", "6Mbps", -+ "9Mbps", "11Mbps", "12Mbps", "18Mbps", -+ "24Mbps", "36 Mbps", "48Mbps", "54Mbps"}; - - if (!rx_stats) - return -ENOENT; -@@ -422,14 +429,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); -- len += scnprintf(buf + len, size - len, -- "GI: 0.8us %llu 0.4us %llu 1.6us %llu 3.2us %llu\n", -- rx_stats->gi_count[0], rx_stats->gi_count[1], -- rx_stats->gi_count[2], rx_stats->gi_count[3]); -- len += scnprintf(buf + len, size - len, -- "BW: 20Mhz %llu 40Mhz %llu 80Mhz %llu 160Mhz %llu\n", -- rx_stats->bw_count[0], rx_stats->bw_count[1], -- rx_stats->bw_count[2], rx_stats->bw_count[3]); - 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 - 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]); -- len += scnprintf(buf + len, size - len, "\nMCS(0-11) Legacy MCS(12):"); -- for (i = 0; i < HAL_RX_MAX_MCS + 1; i++) -- len += scnprintf(buf + len, size - len, "%llu ", rx_stats->mcs_count[i]); -- len += scnprintf(buf + len, size - len, "\nNSS(1-8):"); -- for (i = 0; i < HAL_RX_MAX_NSS; i++) -- len += scnprintf(buf + len, size - len, "%llu ", rx_stats->nss_count[i]); -- len += scnprintf(buf + len, size - len, "\nRX Duration:%llu ", -+ len += scnprintf(buf + len, size - len, "\nRX Duration:%llu\n", - rx_stats->rx_duration); -+ -+ len += scnprintf(buf + len, size - len, "\nRX success packet stats:\n"); -+ len += scnprintf(buf + len, size - len, "\nHE packet stats:\n"); -+ for (i = 0; i <= HAL_RX_MAX_MCS_HE; i++) -+ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, -+ rx_stats->pkt_stats.he_mcs_count[i], -+ (i + 1) % 6 ? "\t" : "\n"); -+ len += scnprintf(buf + len, size - len, "\nVHT packet stats:\n"); -+ for (i = 0; i <= HAL_RX_MAX_MCS_VHT; i++) -+ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, -+ rx_stats->pkt_stats.vht_mcs_count[i], -+ (i + 1) % 5 ? "\t" : "\n"); -+ len += scnprintf(buf + len, size - len, "\nHT packet stats:\n"); -+ for (i = 0; i <= HAL_RX_MAX_MCS_HT; i++) -+ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, -+ rx_stats->pkt_stats.ht_mcs_count[i], -+ (i + 1) % 8 ? "\t" : "\n"); -+ len += scnprintf(buf + len, size - len, "\nLegacy rate packet stats:\n"); -+ for (i = 0; i < HAL_RX_MAX_NUM_LEGACY_RATES; i++) -+ len += scnprintf(buf + len, size - len, "%s: %llu%s", legacy_rate_str[i], -+ rx_stats->pkt_stats.legacy_count[i], -+ (i + 1) % 4 ? "\t" : "\n"); -+ len += scnprintf(buf + len, size - len, "\nNSS packet stats:\n"); -+ for (i = 0; i < HAL_RX_MAX_NSS; i++) -+ len += scnprintf(buf + len, size - len, "%dx%d: %llu ", i + 1, i + 1, -+ rx_stats->pkt_stats.nss_count[i]); -+ len += scnprintf(buf + len, size - len, -+ "\n\nGI: 0.8us %llu 0.4us %llu 1.6us %llu 3.2us %llu\n", -+ rx_stats->pkt_stats.gi_count[0], -+ rx_stats->pkt_stats.gi_count[1], -+ rx_stats->pkt_stats.gi_count[2], -+ rx_stats->pkt_stats.gi_count[3]); -+ len += scnprintf(buf + len, size - len, -+ "BW: 20Mhz %llu 40Mhz %llu 80Mhz %llu 160Mhz %llu\n", -+ rx_stats->pkt_stats.bw_count[0], -+ rx_stats->pkt_stats.bw_count[1], -+ rx_stats->pkt_stats.bw_count[2], -+ rx_stats->pkt_stats.bw_count[3]); -+ len += scnprintf(buf + len, size - len, "\nRate Table (packets):\n"); -+ for (i = 0; i < rate_table_len; i++) -+ len += scnprintf(buf + len, size - len, "%10llu%s", -+ rx_stats->pkt_stats.rx_rate[i], -+ (i + 1) % (he_rates_avail ? 12 : 8) ? "\t" : "\n"); -+ -+ len += scnprintf(buf + len, size - len, "\nRX success byte stats:\n"); -+ len += scnprintf(buf + len, size - len, "\nHE byte stats:\n"); -+ for (i = 0; i <= HAL_RX_MAX_MCS_HE; i++) -+ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, -+ rx_stats->byte_stats.he_mcs_count[i], -+ (i + 1) % 6 ? "\t" : "\n"); -+ -+ len += scnprintf(buf + len, size - len, "\nVHT byte stats:\n"); -+ for (i = 0; i <= HAL_RX_MAX_MCS_VHT; i++) -+ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, -+ rx_stats->byte_stats.vht_mcs_count[i], -+ (i + 1) % 5 ? "\t" : "\n"); -+ len += scnprintf(buf + len, size - len, "\nHT byte stats:\n"); -+ for (i = 0; i <= HAL_RX_MAX_MCS_HT; i++) -+ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, -+ rx_stats->byte_stats.ht_mcs_count[i], -+ (i + 1) % 8 ? "\t" : "\n"); -+ len += scnprintf(buf + len, size - len, "\nLegacy rate byte stats:\n"); -+ for (i = 0; i < HAL_RX_MAX_NUM_LEGACY_RATES; i++) -+ len += scnprintf(buf + len, size - len, "%s: %llu%s", legacy_rate_str[i], -+ rx_stats->byte_stats.legacy_count[i], -+ (i + 1) % 4 ? "\t" : "\n"); -+ len += scnprintf(buf + len, size - len, "\nNSS byte stats:\n"); -+ for (i = 0; i < HAL_RX_MAX_NSS; i++) -+ len += scnprintf(buf + len, size - len, "%dx%d: %llu ", i + 1, i + 1, -+ rx_stats->byte_stats.nss_count[i]); -+ len += scnprintf(buf + len, size - len, -+ "\n\nGI: 0.8us %llu 0.4us %llu 1.6us %llu 3.2us %llu\n", -+ rx_stats->byte_stats.gi_count[0], -+ rx_stats->byte_stats.gi_count[1], -+ rx_stats->byte_stats.gi_count[2], -+ rx_stats->byte_stats.gi_count[3]); -+ len += scnprintf(buf + len, size - len, -+ "BW: 20Mhz %llu 40Mhz %llu 80Mhz %llu 160Mhz %llu\n", -+ rx_stats->byte_stats.bw_count[0], -+ rx_stats->byte_stats.bw_count[1], -+ rx_stats->byte_stats.bw_count[2], -+ rx_stats->byte_stats.bw_count[3]); -+ len += scnprintf(buf + len, size - len, "\nRate Table (bytes):\n"); -+ for (i = 0; i < rate_table_len; i++) -+ len += scnprintf(buf + len, size - len, "%10llu%s", -+ 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], ---- a/drivers/net/wireless/ath/ath11k/dp_rx.c -+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -3221,10 +3221,43 @@ exit: - return total_msdu_reaped; - } - -+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, -+ u32 num_msdu) -+{ -+ u32 rate_idx = 0; -+ u32 mcs_idx = ppdu_info->mcs; -+ u32 nss_idx = ppdu_info->nss - 1; -+ u32 bw_idx = ppdu_info->bw; -+ u32 gi_idx = ppdu_info->gi; -+ -+ if ((mcs_idx > HAL_RX_MAX_MCS_HE) || (nss_idx >= HAL_RX_MAX_NSS) || -+ (bw_idx >= HAL_RX_BW_MAX) || (gi_idx >= HAL_RX_GI_MAX)) { -+ return; -+ } -+ -+ if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11N || -+ ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC) { -+ rate_idx = mcs_idx * 8 + 8 * 10 * nss_idx; -+ rate_idx += bw_idx * 2 + gi_idx; -+ } else if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AX) { -+ gi_idx = ath11k_he_gi_to_nl80211_he_gi(ppdu_info->gi); -+ rate_idx = mcs_idx * 12 + 12 * 12 * nss_idx; -+ rate_idx += bw_idx * 3 + gi_idx; -+ } else { -+ return; -+ } -+ -+ rx_stats->pkt_stats.rx_rate[rate_idx] += num_msdu; -+ rx_stats->byte_stats.rx_rate[rate_idx] += ppdu_info->mpdu_len; -+} -+ - static void ath11k_dp_rx_update_peer_stats(struct ath11k_sta *arsta, - struct hal_rx_mon_ppdu_info *ppdu_info) - { - struct ath11k_rx_peer_stats *rx_stats = arsta->rx_stats; -+ struct ath11k *ar = arsta->arvif->ar; - u32 num_msdu; - int i; - -@@ -3234,6 +3267,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); - -+ if (!ath11k_debugfs_is_extd_rx_stats_enabled(ar)) -+ return; - num_msdu = ppdu_info->tcp_msdu_count + ppdu_info->tcp_ack_msdu_count + - ppdu_info->udp_msdu_count + ppdu_info->other_msdu_count; - -@@ -3250,18 +3285,6 @@ static void ath11k_dp_rx_update_peer_sta - ppdu_info->tid = IEEE80211_NUM_TIDS; - } - -- if (ppdu_info->nss > 0 && ppdu_info->nss <= HAL_RX_MAX_NSS) -- rx_stats->nss_count[ppdu_info->nss - 1] += num_msdu; -- -- if (ppdu_info->mcs <= HAL_RX_MAX_MCS) -- rx_stats->mcs_count[ppdu_info->mcs] += num_msdu; -- -- if (ppdu_info->gi < HAL_RX_GI_MAX) -- rx_stats->gi_count[ppdu_info->gi] += num_msdu; -- -- if (ppdu_info->bw < HAL_RX_BW_MAX) -- rx_stats->bw_count[ppdu_info->bw] += num_msdu; -- - if (ppdu_info->ldpc < HAL_RX_SU_MU_CODING_MAX) - rx_stats->coding_count[ppdu_info->ldpc] += num_msdu; - -@@ -3290,8 +3313,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; - -- arsta->rssi_comb = ppdu_info->rssi_comb; -- - BUILD_BUG_ON(ARRAY_SIZE(arsta->chain_signal) > - ARRAY_SIZE(ppdu_info->rssi_chain_pri20)); - -@@ -3300,6 +3321,52 @@ static void ath11k_dp_rx_update_peer_sta - - rx_stats->rx_duration += ppdu_info->rx_duration; - arsta->rx_duration = rx_stats->rx_duration; -+ -+ if (ppdu_info->nss > 0 && ppdu_info->nss <= HAL_RX_MAX_NSS) { -+ rx_stats->pkt_stats.nss_count[ppdu_info->nss - 1] += num_msdu; -+ rx_stats->byte_stats.nss_count[ppdu_info->nss - 1] += ppdu_info->mpdu_len; -+ } -+ -+ if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11N && -+ ppdu_info->mcs <= HAL_RX_MAX_MCS_HT) { -+ rx_stats->pkt_stats.ht_mcs_count[ppdu_info->mcs] += num_msdu; -+ rx_stats->byte_stats.ht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len; -+ /* To fit into rate table for HT packets */ -+ ppdu_info->mcs = ppdu_info->mcs % 8; -+ } -+ -+ if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC && -+ ppdu_info->mcs <= HAL_RX_MAX_MCS_VHT) { -+ rx_stats->pkt_stats.vht_mcs_count[ppdu_info->mcs] += num_msdu; -+ rx_stats->byte_stats.vht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len; -+ } -+ -+ if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AX && -+ ppdu_info->mcs <= HAL_RX_MAX_MCS_HE) { -+ rx_stats->pkt_stats.he_mcs_count[ppdu_info->mcs] += num_msdu; -+ rx_stats->byte_stats.he_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len; -+ } -+ -+ -+ if ((ppdu_info->preamble_type == HAL_RX_PREAMBLE_11A || -+ ppdu_info->preamble_type == HAL_RX_PREAMBLE_11B) && -+ ppdu_info->rate < HAL_RX_LEGACY_RATE_INVALID) { -+ rx_stats->pkt_stats.legacy_count[ppdu_info->rate] += num_msdu; -+ rx_stats->byte_stats.legacy_count[ppdu_info->rate] += ppdu_info->mpdu_len; -+ } -+ -+ if (ppdu_info->gi < HAL_RX_GI_MAX) { -+ rx_stats->pkt_stats.gi_count[ppdu_info->gi] += num_msdu; -+ rx_stats->byte_stats.gi_count[ppdu_info->gi] += ppdu_info->mpdu_len; -+ } -+ -+ if (ppdu_info->bw < HAL_RX_BW_MAX) { -+ rx_stats->pkt_stats.bw_count[ppdu_info->bw] += num_msdu; -+ rx_stats->byte_stats.bw_count[ppdu_info->bw] += ppdu_info->mpdu_len; -+ } -+ -+ ath11k_dp_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, num_msdu); -+ - } - - 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 { - __be16 snap_type; - } __packed; - -+static inline u32 ath11k_he_gi_to_nl80211_he_gi(u8 sgi) -+{ -+ u32 ret = 0; -+ -+ switch (sgi) { -+ case RX_MSDU_START_SGI_0_8_US: -+ ret = NL80211_RATE_INFO_HE_GI_0_8; -+ break; -+ case RX_MSDU_START_SGI_1_6_US: -+ ret = NL80211_RATE_INFO_HE_GI_1_6; -+ break; -+ case RX_MSDU_START_SGI_3_2_US: -+ ret = NL80211_RATE_INFO_HE_GI_3_2; -+ break; -+ } -+ -+ return ret; -+} -+ - int ath11k_dp_rx_ampdu_start(struct ath11k_vif *arvif, - struct ieee80211_ampdu_params *params); - int ath11k_dp_rx_ampdu_stop(struct ath11k_vif *arvif, ---- 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 - 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); -- ppdu_info->gi = info1 & HAL_RX_HT_SIG_INFO_INFO1_GI; -- -- switch (ppdu_info->mcs) { -- case 0 ... 7: -- ppdu_info->nss = 1; -- break; -- case 8 ... 15: -- ppdu_info->nss = 2; -- break; -- case 16 ... 23: -- ppdu_info->nss = 3; -- break; -- case 24 ... 31: -- ppdu_info->nss = 4; -- break; -- } -- -- if (ppdu_info->nss > 1) -- ppdu_info->mcs = ppdu_info->mcs % 8; -- -+ ppdu_info->gi = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO1_GI, info1); -+ ppdu_info->nss = (ppdu_info->mcs >> 3) + 1; - ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; - break; - } - case HAL_PHYRX_L_SIG_B: { - struct hal_rx_lsig_b_info *lsigb = - (struct hal_rx_lsig_b_info *)tlv_data; -+ u8 rate; -+ -+ rate = FIELD_GET(HAL_RX_LSIG_B_INFO_INFO0_RATE, -+ __le32_to_cpu(lsigb->info0)); - -- ppdu_info->rate = FIELD_GET(HAL_RX_LSIG_B_INFO_INFO0_RATE, -- __le32_to_cpu(lsigb->info0)); -+ switch (rate) { -+ case 1: -+ rate = HAL_RX_LEGACY_RATE_1_MBPS; -+ break; -+ case 2: -+ case 5: -+ rate = HAL_RX_LEGACY_RATE_2_MBPS; -+ break; -+ case 3: -+ case 6: -+ rate = HAL_RX_LEGACY_RATE_5_5_MBPS; -+ break; -+ case 4: -+ case 7: -+ rate = HAL_RX_LEGACY_RATE_11_MBPS; -+ break; -+ default: -+ rate = HAL_RX_LEGACY_RATE_INVALID; -+ } -+ ppdu_info->rate = rate; - ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; - break; - } - case HAL_PHYRX_L_SIG_A: { - struct hal_rx_lsig_a_info *lsiga = - (struct hal_rx_lsig_a_info *)tlv_data; -+ u8 rate; - -- ppdu_info->rate = FIELD_GET(HAL_RX_LSIG_A_INFO_INFO0_RATE, -- __le32_to_cpu(lsiga->info0)); -+ rate = FIELD_GET(HAL_RX_LSIG_A_INFO_INFO0_RATE, -+ __le32_to_cpu(lsiga->info0)); -+ switch (rate) { -+ case 8: -+ rate = HAL_RX_LEGACY_RATE_48_MBPS; -+ break; -+ case 9: -+ rate = HAL_RX_LEGACY_RATE_24_MBPS; -+ break; -+ case 10: -+ rate = HAL_RX_LEGACY_RATE_12_MBPS; -+ break; -+ case 11: -+ rate = HAL_RX_LEGACY_RATE_6_MBPS; -+ break; -+ case 12: -+ rate = HAL_RX_LEGACY_RATE_54_MBPS; -+ break; -+ case 13: -+ rate = HAL_RX_LEGACY_RATE_36_MBPS; -+ break; -+ case 14: -+ rate = HAL_RX_LEGACY_RATE_18_MBPS; -+ break; -+ case 15: -+ rate = HAL_RX_LEGACY_RATE_9_MBPS; -+ break; -+ default: -+ rate = HAL_RX_LEGACY_RATE_INVALID; -+ } -+ ppdu_info->rate = rate; - ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; - break; - } -@@ -1473,6 +1507,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; -+ -+ ppdu_info->mpdu_len += ab->hw_params.hw_ops->rx_desc_get_hal_mpdu_len(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 -@@ -19,7 +19,11 @@ struct hal_rx_wbm_rel_info { - #define VHT_SIG_SU_NSS_MASK 0x7 - - #define HAL_RX_MAX_MCS 12 -+#define HAL_RX_MAX_MCS_HT 31 -+#define HAL_RX_MAX_MCS_VHT 9 -+#define HAL_RX_MAX_MCS_HE 11 - #define HAL_RX_MAX_NSS 8 -+#define HAL_RX_MAX_NUM_LEGACY_RATES 12 - - struct hal_rx_mon_status_tlv_hdr { - u32 hdr; -@@ -104,6 +108,22 @@ struct hal_rx_user_status { - u32 mpdu_err_byte_count; - }; - -+enum hal_rx_legacy_rate { -+ HAL_RX_LEGACY_RATE_1_MBPS, -+ HAL_RX_LEGACY_RATE_2_MBPS, -+ HAL_RX_LEGACY_RATE_5_5_MBPS, -+ HAL_RX_LEGACY_RATE_6_MBPS, -+ HAL_RX_LEGACY_RATE_9_MBPS, -+ HAL_RX_LEGACY_RATE_11_MBPS, -+ HAL_RX_LEGACY_RATE_12_MBPS, -+ HAL_RX_LEGACY_RATE_18_MBPS, -+ HAL_RX_LEGACY_RATE_24_MBPS, -+ HAL_RX_LEGACY_RATE_36_MBPS, -+ HAL_RX_LEGACY_RATE_48_MBPS, -+ HAL_RX_LEGACY_RATE_54_MBPS, -+ HAL_RX_LEGACY_RATE_INVALID, -+}; -+ - #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 { - u32 num_mpdu_fcs_ok; - u32 num_mpdu_fcs_err; - u32 preamble_type; -+ u32 mpdu_len; - u16 chan_num; - u16 tcp_msdu_count; - 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 - return skb_get_hash(skb); - } - -+static u32 ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len(struct hal_rx_mpdu_info *mpdu_info) -+{ -+ return FIELD_GET(HAL_RX_MPDU_INFO_INFO1_MPDU_LEN, -+ __le32_to_cpu(mpdu_info->u.ipq8074.info1)); -+} -+ -+static u32 ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_len(struct hal_rx_mpdu_info *mpdu_info) -+{ -+ return FIELD_GET(HAL_RX_MPDU_INFO_INFO1_MPDU_LEN, -+ __le32_to_cpu(mpdu_info->u.qcn9074.info1)); -+} - 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 = - .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 = - .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, - }; - - const struct ath11k_hw_ops qca6390_ops = { -@@ -1177,6 +1190,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, -+ .rx_desc_get_hal_mpdu_len = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len, - }; - - 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, - .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 = - .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, - }; - - #define ATH11K_TX_RING_MASK_0 BIT(0) ---- a/drivers/net/wireless/ath/ath11k/hw.h -+++ b/drivers/net/wireless/ath/ath11k/hw.h -@@ -313,6 +313,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 diff --git a/package/kernel/mac80211/patches/nss/ath11k/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch b/package/kernel/mac80211/patches/nss/ath11k/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch deleted file mode 100644 index 609e78be7357e7..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch +++ /dev/null @@ -1,453 +0,0 @@ ---- 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 - len += scnprintf(buf + len, size - len, "%10llu%s", - rx_stats->byte_stats.rx_rate[i], - (i + 1) % (he_rates_avail ? 12 : 8) ? "\t" : "\n"); -+ len += scnprintf(buf + len, size - len, -+ "\nDCM: %llu\nRU26: %llu \nRU52: %llu \nRU106: %llu \nRU242: %llu \nRU484: %llu \nRU996: %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, - "\nDCM: %llu\nRU: 26 %llu 52: %llu 106: %llu 242: %llu 484: %llu 996: %llu\n", ---- a/drivers/net/wireless/ath/ath11k/dp_rx.c -+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -3224,11 +3224,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, -+ struct hal_rx_user_status* user_stats, - u32 num_msdu) - { - u32 rate_idx = 0; -- u32 mcs_idx = ppdu_info->mcs; -- u32 nss_idx = ppdu_info->nss - 1; -+ u32 mcs_idx = (user_stats) ? user_stats->mcs : ppdu_info->mcs; -+ u32 nss_idx = (user_stats) ? user_stats->nss - 1 : ppdu_info->nss - 1; - u32 bw_idx = ppdu_info->bw; - u32 gi_idx = ppdu_info->gi; - -@@ -3250,10 +3251,13 @@ ath11k_dp_rx_update_peer_rate_table_stat - } - - rx_stats->pkt_stats.rx_rate[rate_idx] += num_msdu; -- rx_stats->byte_stats.rx_rate[rate_idx] += ppdu_info->mpdu_len; -+ if (user_stats) -+ rx_stats->byte_stats.rx_rate[rate_idx] += user_stats->mpdu_ok_byte_count; -+ else -+ rx_stats->byte_stats.rx_rate[rate_idx] += ppdu_info->mpdu_len; - } - --static void ath11k_dp_rx_update_peer_stats(struct ath11k_sta *arsta, -+static void ath11k_dp_rx_update_peer_su_stats(struct ath11k_sta *arsta, - struct hal_rx_mon_ppdu_info *ppdu_info) - { - struct ath11k_rx_peer_stats *rx_stats = arsta->rx_stats; -@@ -3311,7 +3315,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; -- rx_stats->ru_alloc_cnt[ppdu_info->ru_alloc] += num_msdu; - - BUILD_BUG_ON(ARRAY_SIZE(arsta->chain_signal) > - ARRAY_SIZE(ppdu_info->rssi_chain_pri20)); -@@ -3329,10 +3332,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) { -- rx_stats->pkt_stats.ht_mcs_count[ppdu_info->mcs] += num_msdu; -- rx_stats->byte_stats.ht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len; -- /* To fit into rate table for HT packets */ -- ppdu_info->mcs = ppdu_info->mcs % 8; -+ rx_stats->pkt_stats.ht_mcs_count[ppdu_info->mcs] += num_msdu; -+ rx_stats->byte_stats.ht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len; -+ /* To fit into rate table for HT packets */ -+ ppdu_info->mcs = ppdu_info->mcs % 8; - } - - if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC && -@@ -3365,7 +3368,120 @@ static void ath11k_dp_rx_update_peer_sta - rx_stats->byte_stats.bw_count[ppdu_info->bw] += ppdu_info->mpdu_len; - } - -- ath11k_dp_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, num_msdu); -+ ath11k_dp_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, NULL, num_msdu); -+ -+} -+ -+static void ath11k_dp_rx_update_user_stats(struct ath11k *ar, -+ struct hal_rx_mon_ppdu_info *ppdu_info, -+ u32 uid) -+{ -+ struct ath11k_sta *arsta = NULL; -+ struct ath11k_rx_peer_stats *rx_stats = NULL; -+ struct hal_rx_user_status* user_stats = &ppdu_info->userstats[uid]; -+ struct ath11k_peer *peer; -+ u32 num_msdu; -+ -+ if (user_stats->ast_index == 0 || user_stats->ast_index == 0xFFFF) -+ return; -+ -+ peer = ath11k_peer_find_by_ast(ar->ab, user_stats->ast_index); -+ -+ if (peer == NULL) { -+ ath11k_warn(ar->ab, "peer ast idx %d can't be found\n", -+ user_stats->ast_index); -+ return; -+ } -+ -+ arsta = (struct ath11k_sta *)peer->sta->drv_priv; -+ rx_stats = arsta->rx_stats; -+ -+ if (!rx_stats) -+ return; -+ -+ arsta->rssi_comb = ppdu_info->rssi_comb; -+ -+ num_msdu = user_stats->tcp_msdu_count + user_stats->tcp_ack_msdu_count + -+ user_stats->udp_msdu_count + user_stats->other_msdu_count; -+ -+ rx_stats->num_msdu += num_msdu; -+ rx_stats->tcp_msdu_count += user_stats->tcp_msdu_count + -+ user_stats->tcp_ack_msdu_count; -+ rx_stats->udp_msdu_count += user_stats->udp_msdu_count; -+ rx_stats->other_msdu_count += user_stats->other_msdu_count; -+ -+ if (ppdu_info->ldpc < HAL_RX_SU_MU_CODING_MAX) -+ rx_stats->coding_count[ppdu_info->ldpc] += num_msdu; -+ -+ if (user_stats->tid <= IEEE80211_NUM_TIDS) -+ rx_stats->tid_count[user_stats->tid] += num_msdu; -+ -+ if (user_stats->preamble_type < HAL_RX_PREAMBLE_MAX) -+ rx_stats->pream_cnt[user_stats->preamble_type] += num_msdu; -+ -+ if (ppdu_info->reception_type < HAL_RX_RECEPTION_TYPE_MAX) -+ rx_stats->reception_type[ppdu_info->reception_type] += num_msdu; -+ -+ if (ppdu_info->is_stbc) -+ rx_stats->stbc_count += num_msdu; -+ -+ if (ppdu_info->beamformed) -+ rx_stats->beamformed_count += num_msdu; -+ -+ if (user_stats->mpdu_cnt_fcs_ok > 1) -+ rx_stats->ampdu_msdu_count += num_msdu; -+ else -+ rx_stats->non_ampdu_msdu_count += num_msdu; -+ -+ rx_stats->num_mpdu_fcs_ok += user_stats->mpdu_cnt_fcs_ok; -+ rx_stats->num_mpdu_fcs_err += user_stats->mpdu_cnt_fcs_err; -+ rx_stats->dcm_count += ppdu_info->dcm; -+ if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA || -+ ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO) -+ rx_stats->ru_alloc_cnt[user_stats->ul_ofdma_ru_size] += num_msdu; -+ -+ rx_stats->rx_duration += ppdu_info->rx_duration; -+ arsta->rx_duration = rx_stats->rx_duration; -+ -+ if (user_stats->nss > 0 && user_stats->nss <= HAL_RX_MAX_NSS) { -+ rx_stats->pkt_stats.nss_count[user_stats->nss - 1] += num_msdu; -+ rx_stats->byte_stats.nss_count[user_stats->nss - 1] += user_stats->mpdu_ok_byte_count; -+ } -+ -+ if (user_stats->preamble_type == HAL_RX_PREAMBLE_11AX && -+ user_stats->mcs <= HAL_RX_MAX_MCS_HE) { -+ rx_stats->pkt_stats.he_mcs_count[user_stats->mcs] += num_msdu; -+ rx_stats->byte_stats.he_mcs_count[user_stats->mcs] += user_stats->mpdu_ok_byte_count; -+ } -+ -+ if (ppdu_info->gi < HAL_RX_GI_MAX) { -+ rx_stats->pkt_stats.gi_count[ppdu_info->gi] += num_msdu; -+ rx_stats->byte_stats.gi_count[ppdu_info->gi] += user_stats->mpdu_ok_byte_count; -+ } -+ -+ if (ppdu_info->bw < HAL_RX_BW_MAX) { -+ rx_stats->pkt_stats.bw_count[ppdu_info->bw] += num_msdu; -+ rx_stats->byte_stats.bw_count[ppdu_info->bw] += user_stats->mpdu_ok_byte_count; -+ } -+ -+ ath11k_dp_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, user_stats, num_msdu); -+} -+ -+static void ath11k_dp_rx_update_peer_mu_stats(struct ath11k *ar, -+ struct hal_rx_mon_ppdu_info *ppdu_info) -+{ -+ u32 num_users, i; -+ -+ if (!ath11k_debugfs_is_extd_rx_stats_enabled(ar)) -+ return; -+ -+ num_users = ppdu_info->num_users; -+ if (num_users > HAL_MAX_UL_MU_USERS) -+ num_users = HAL_MAX_UL_MU_USERS; -+ -+ for (i = 0; i < num_users; i++) { -+ ath11k_dp_rx_update_user_stats(ar, ppdu_info, i); -+ } - - } - -@@ -5834,6 +5950,55 @@ static void ath11k_dp_rx_mon_dest_proces - } - } - -+void ath11k_dp_rx_mon_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info) -+{ -+ struct hal_rx_user_status *rx_user_status; -+ u32 num_users; -+ uint32_t i; -+ uint32_t mu_ul_user_v0_word0; -+ uint32_t mu_ul_user_v0_word1; -+ uint32_t ru_size; -+ -+ if (!(ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA || -+ ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO)) -+ return; -+ -+ num_users = ppdu_info->num_users; -+ if (num_users > HAL_MAX_UL_MU_USERS) -+ num_users = HAL_MAX_UL_MU_USERS; -+ -+ for (i = 0; i < num_users; i++) { -+ rx_user_status = &ppdu_info->userstats[i]; -+ mu_ul_user_v0_word0 = -+ rx_user_status->ul_ofdma_user_v0_word0; -+ mu_ul_user_v0_word1 = -+ rx_user_status->ul_ofdma_user_v0_word1; -+ -+ if (FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID, -+ mu_ul_user_v0_word0) && -+ !FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VER, -+ mu_ul_user_v0_word0)) { -+ rx_user_status->mcs = -+ FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_MCS, -+ mu_ul_user_v0_word1); -+ rx_user_status->nss = -+ FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_NSS, -+ mu_ul_user_v0_word1) + 1; -+ -+ rx_user_status->ofdma_info_valid = 1; -+ rx_user_status->ul_ofdma_ru_start_index = -+ FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_START, -+ mu_ul_user_v0_word1); -+ -+ ru_size = FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE, -+ mu_ul_user_v0_word1); -+ rx_user_status->ul_ofdma_ru_width = ru_size; -+ rx_user_status->ul_ofdma_ru_size = ru_size; -+ } -+ } -+ -+} -+ - int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id, - struct napi_struct *napi, int budget) - { -@@ -5905,10 +6070,13 @@ int ath11k_dp_rx_process_mon_status(stru - goto next_skb; - } - -- 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; -- 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 (ath11k_debugfs_is_pktlog_peer_valid(ar, peer->addr)) ---- a/drivers/net/wireless/ath/ath11k/hal_rx.c -+++ b/drivers/net/wireless/ath/ath11k/hal_rx.c -@@ -804,7 +804,6 @@ void ath11k_hal_reo_init_cmd_ring(struct - } - } - --#define HAL_MAX_UL_MU_USERS 37 - static inline void - ath11k_hal_rx_handle_ofdma_info(void *rx_tlv, - struct hal_rx_user_status *rx_user_status) -@@ -836,6 +835,8 @@ ath11k_hal_rx_populate_mu_user_info(void - { - rx_user_status->ast_index = ppdu_info->ast_index; - rx_user_status->tid = ppdu_info->tid; -+ rx_user_status->tcp_ack_msdu_count = -+ ppdu_info->tcp_ack_msdu_count; - rx_user_status->tcp_msdu_count = - ppdu_info->tcp_msdu_count; - rx_user_status->udp_msdu_count = -@@ -859,6 +860,9 @@ ath11k_hal_rx_populate_mu_user_info(void - ppdu_info->num_mpdu_fcs_ok; - rx_user_status->mpdu_cnt_fcs_err = - ppdu_info->num_mpdu_fcs_err; -+ memcpy(&rx_user_status->mpdu_fcs_ok_bitmap[0], &ppdu_info->mpdu_fcs_ok_bitmap[0], -+ HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * -+ sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0])); - - ath11k_hal_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status); - } -@@ -888,6 +892,14 @@ ath11k_hal_rx_parse_mon_status_tlv(struc - __le32_to_cpu(ppdu_start->info0)); - ppdu_info->chan_num = __le32_to_cpu(ppdu_start->chan_num); - ppdu_info->ppdu_ts = __le32_to_cpu(ppdu_start->ppdu_start_ts); -+ -+ if (ppdu_info->ppdu_id != ppdu_info->last_ppdu_id) { -+ ppdu_info->last_ppdu_id = ppdu_info->ppdu_id; -+ ppdu_info->num_users = 0; -+ memset(&ppdu_info->mpdu_fcs_ok_bitmap, 0, -+ HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * -+ sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0])); -+ } - break; - } - case HAL_RX_PPDU_END_USER_STATS: { -@@ -942,15 +954,16 @@ ath11k_hal_rx_parse_mon_status_tlv(struc - - if (userid < HAL_MAX_UL_MU_USERS) { - struct hal_rx_user_status *rxuser_stats = -- &ppdu_info->userstats; -+ &ppdu_info->userstats[userid]; -+ ppdu_info->num_users += 1; - - ath11k_hal_rx_handle_ofdma_info(tlv_data, rxuser_stats); - ath11k_hal_rx_populate_mu_user_info(tlv_data, ppdu_info, - rxuser_stats); - } -- ppdu_info->userstats.mpdu_fcs_ok_bitmap[0] = -+ ppdu_info->mpdu_fcs_ok_bitmap[0] = - __le32_to_cpu(eu_stats->rsvd1[0]); -- ppdu_info->userstats.mpdu_fcs_ok_bitmap[1] = -+ ppdu_info->mpdu_fcs_ok_bitmap[1] = - __le32_to_cpu(eu_stats->rsvd1[1]); - - break; -@@ -958,12 +971,12 @@ ath11k_hal_rx_parse_mon_status_tlv(struc - case HAL_RX_PPDU_END_USER_STATS_EXT: { - struct hal_rx_ppdu_end_user_stats_ext *eu_stats = - (struct hal_rx_ppdu_end_user_stats_ext *)tlv_data; -- ppdu_info->userstats.mpdu_fcs_ok_bitmap[2] = eu_stats->info1; -- ppdu_info->userstats.mpdu_fcs_ok_bitmap[3] = eu_stats->info2; -- ppdu_info->userstats.mpdu_fcs_ok_bitmap[4] = eu_stats->info3; -- ppdu_info->userstats.mpdu_fcs_ok_bitmap[5] = eu_stats->info4; -- ppdu_info->userstats.mpdu_fcs_ok_bitmap[6] = eu_stats->info5; -- ppdu_info->userstats.mpdu_fcs_ok_bitmap[7] = eu_stats->info6; -+ ppdu_info->mpdu_fcs_ok_bitmap[2] = eu_stats->info1; -+ ppdu_info->mpdu_fcs_ok_bitmap[3] = eu_stats->info2; -+ ppdu_info->mpdu_fcs_ok_bitmap[4] = eu_stats->info3; -+ ppdu_info->mpdu_fcs_ok_bitmap[5] = eu_stats->info4; -+ ppdu_info->mpdu_fcs_ok_bitmap[6] = eu_stats->info5; -+ ppdu_info->mpdu_fcs_ok_bitmap[7] = eu_stats->info6; - break; - } - case HAL_PHYRX_HT_SIG: { ---- a/drivers/net/wireless/ath/ath11k/hal_rx.h -+++ b/drivers/net/wireless/ath/ath11k/hal_rx.h -@@ -72,6 +72,10 @@ enum hal_rx_reception_type { - #define HAL_RX_FCS_LEN 4 - #define HAL_AST_IDX_INVALID 0xFFFF - -+#define HAL_MAX_UL_MU_USERS 37 -+#define HAL_RX_MAX_MPDU 256 -+#define HAL_RX_NUM_WORDS_PER_PPDU_BITMAP (HAL_RX_MAX_MPDU >> 5) -+ - enum hal_rx_mon_status { - HAL_RX_MON_STATUS_PPDU_NOT_DONE, - HAL_RX_MON_STATUS_PPDU_DONE, -@@ -82,14 +86,15 @@ struct hal_rx_user_status { - u32 mcs:4, - nss:3, - ofdma_info_valid:1, -- dl_ofdma_ru_start_index:7, -- dl_ofdma_ru_width:7, -- dl_ofdma_ru_size:8; -+ ul_ofdma_ru_start_index:7, -+ ul_ofdma_ru_width:7, -+ ul_ofdma_ru_size:8; - u32 ul_ofdma_user_v0_word0; - u32 ul_ofdma_user_v0_word1; - u32 ast_index; - u32 tid; - u16 tcp_msdu_count; -+ u16 tcp_ack_msdu_count; - u16 udp_msdu_count; - u16 other_msdu_count; - u16 frame_control; -@@ -103,7 +108,7 @@ struct hal_rx_user_status { - u8 rs_flags; - u32 mpdu_cnt_fcs_ok; - u32 mpdu_cnt_fcs_err; -- u32 mpdu_fcs_ok_bitmap[8]; -+ u32 mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP]; - u32 mpdu_ok_byte_count; - u32 mpdu_err_byte_count; - }; -@@ -144,6 +149,7 @@ struct hal_sw_mon_ring_entries { - - struct hal_rx_mon_ppdu_info { - u32 ppdu_id; -+ u32 last_ppdu_id; - u32 ppdu_ts; - u32 num_mpdu_fcs_ok; - u32 num_mpdu_fcs_err; -@@ -212,9 +218,20 @@ struct hal_rx_mon_ppdu_info { - u8 ltf_size; - u8 rxpcu_filter_pass; - char rssi_chain[8][8]; -- struct hal_rx_user_status userstats; -+ 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]; - }; - -+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID BIT(30) -+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VER BIT(31) -+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_NSS GENMASK(2, 0) -+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_MCS GENMASK(6, 3) -+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_LDPC BIT(7) -+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_DCM BIT(8) -+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_START GENMASK(15, 9) -+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE GENMASK(18, 16) -+ - #define HAL_RX_PPDU_START_INFO0_PPDU_ID GENMASK(15, 0) - - 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_ - return NULL; - } - -+struct ath11k_peer *ath11k_peer_find_by_ast(struct ath11k_base *ab, -+ int ast_hash) -+{ -+ struct ath11k_peer *peer; -+ -+ lockdep_assert_held(&ab->base_lock); -+ -+ list_for_each_entry(peer, &ab->peers, list) -+ if (ast_hash == peer->ast_hash) -+ return peer; -+ -+ 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, ---- 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 - 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); -+struct ath11k_peer *ath11k_peer_find_by_ast(struct ath11k_base *ab, int ast_hash); - void ath11k_peer_cleanup(struct ath11k *ar, u32 vdev_id); - int ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, u8 *addr); - int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, diff --git a/package/kernel/mac80211/patches/nss/ath11k/907-ath11k-remove-error-on-soc-debugfs-fail.patch b/package/kernel/mac80211/patches/nss/ath11k/907-ath11k-remove-error-on-soc-debugfs-fail.patch index 1533203bec17d5..c23618f506dd78 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/907-ath11k-remove-error-on-soc-debugfs-fail.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/907-ath11k-remove-error-on-soc-debugfs-fail.patch @@ -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", -@@ -1929,6 +1947,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, -@@ -2229,6 +2250,9 @@ int ath11k_debugfs_register(struct ath11 +@@ -1834,6 +1852,9 @@ int ath11k_debugfs_register(struct ath11 char pdev_name[10]; char buf[100] = {0}; @@ -117,6 +107,16 @@ 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); +@@ -1908,6 +1929,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 { \ diff --git a/package/kernel/mac80211/patches/nss/ath11k/908-330-ath11k-sync-wds_ast_entry-updates.patch b/package/kernel/mac80211/patches/nss/ath11k/908-330-ath11k-sync-wds_ast_entry-updates.patch index f1cbcfc9321e6b..bb27ff31a47d43 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/908-330-ath11k-sync-wds_ast_entry-updates.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/908-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 -@@ -2210,6 +2210,7 @@ struct ath11k_base *ath11k_core_alloc(st +@@ -2209,6 +2209,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); -@@ -2223,6 +2224,8 @@ struct ath11k_base *ath11k_core_alloc(st +@@ -2222,6 +2223,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,15 +75,15 @@ 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) -@@ -1130,6 +1131,11 @@ struct ath11k_base { +@@ -1098,6 +1099,11 @@ struct ath11k_base { u32 max_ast_index; u32 num_ast_entries; @@ -195,7 +195,7 @@ Signed-off-by: Rameshkumar Sundaram --- a/drivers/net/wireless/ath/ath11k/peer.c +++ b/drivers/net/wireless/ath/ath11k/peer.c -@@ -160,49 +160,68 @@ struct ath11k_ast_entry *ath11k_peer_ast +@@ -146,49 +146,68 @@ struct ath11k_ast_entry *ath11k_peer_ast void ath11k_peer_ast_wds_wmi_wk(struct work_struct *wk) { @@ -299,7 +299,7 @@ Signed-off-by: Rameshkumar Sundaram } int ath11k_peer_add_ast(struct ath11k *ar, struct ath11k_peer *peer, -@@ -211,6 +230,8 @@ int ath11k_peer_add_ast(struct ath11k *a +@@ -197,6 +216,8 @@ int ath11k_peer_add_ast(struct ath11k *a struct ath11k_ast_entry *ast_entry = NULL; struct ath11k_base *ab = ar->ab; @@ -308,7 +308,7 @@ Signed-off-by: Rameshkumar Sundaram if (ab->num_ast_entries == ab->max_ast_index) { ath11k_warn(ab, "failed to add ast for %pM due to insufficient ast entry resource %d in target\n", mac_addr, ab->max_ast_index); -@@ -226,6 +247,9 @@ int ath11k_peer_add_ast(struct ath11k *a +@@ -212,6 +233,9 @@ int ath11k_peer_add_ast(struct ath11k *a } } @@ -318,7 +318,7 @@ Signed-off-by: Rameshkumar Sundaram ast_entry = kzalloc(sizeof(*ast_entry), GFP_ATOMIC); if (!ast_entry) { ath11k_warn(ab, "failed to alloc ast_entry for %pM\n", -@@ -257,7 +281,7 @@ int ath11k_peer_add_ast(struct ath11k *a +@@ -243,7 +267,7 @@ int ath11k_peer_add_ast(struct ath11k *a } INIT_LIST_HEAD(&ast_entry->ase_list); @@ -327,7 +327,7 @@ Signed-off-by: Rameshkumar Sundaram ast_entry->vdev_id = peer->vdev_id; ast_entry->pdev_idx = peer->pdev_idx; ast_entry->is_mapped = false; -@@ -271,16 +295,12 @@ int ath11k_peer_add_ast(struct ath11k *a +@@ -257,16 +281,12 @@ int ath11k_peer_add_ast(struct ath11k *a ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_add_ast peer %pM ast_entry %pM, ast_type %d\n", peer->addr, mac_addr, ast_entry->type); @@ -346,7 +346,7 @@ Signed-off-by: Rameshkumar Sundaram } ab->num_ast_entries++; -@@ -293,6 +313,8 @@ int ath11k_peer_update_ast(struct ath11k +@@ -279,6 +299,8 @@ int ath11k_peer_update_ast(struct ath11k struct ath11k_peer *old_peer = ast_entry->peer; struct ath11k_base *ab = ar->ab; @@ -355,7 +355,7 @@ Signed-off-by: Rameshkumar Sundaram if (!ast_entry->is_mapped) { ath11k_warn(ab, "ath11k_peer_update_ast: ast_entry %pM not mapped yet\n", ast_entry->addr); -@@ -305,6 +327,9 @@ int ath11k_peer_update_ast(struct ath11k +@@ -291,6 +313,9 @@ int ath11k_peer_update_ast(struct ath11k (ast_entry->is_active)) return 0; @@ -365,7 +365,7 @@ Signed-off-by: Rameshkumar Sundaram ast_entry->vdev_id = peer->vdev_id; ast_entry->pdev_idx = peer->pdev_idx; ast_entry->type = ATH11K_AST_TYPE_WDS; -@@ -317,7 +342,14 @@ int ath11k_peer_update_ast(struct ath11k +@@ -303,7 +328,14 @@ int ath11k_peer_update_ast(struct ath11k old_peer->addr, peer->addr, ast_entry->addr); ast_entry->action = ATH11K_WDS_WMI_UPDATE; @@ -381,7 +381,7 @@ Signed-off-by: Rameshkumar Sundaram return 0; } -@@ -363,16 +395,23 @@ void ath11k_peer_del_ast(struct ath11k * +@@ -349,16 +381,23 @@ void ath11k_peer_del_ast(struct ath11k * ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_del_ast pdev:%d peer %pM ast_entry %pM\n", ar->pdev->pdev_id, peer->addr, ast_entry->addr); @@ -410,7 +410,7 @@ Signed-off-by: Rameshkumar Sundaram ab->num_ast_entries--; } -@@ -681,6 +720,10 @@ void ath11k_peer_cleanup(struct ath11k * +@@ -667,6 +706,10 @@ void ath11k_peer_cleanup(struct ath11k * lockdep_assert_held(&ar->conf_mutex); @@ -421,7 +421,7 @@ Signed-off-by: Rameshkumar Sundaram mutex_lock(&ab->tbl_mtx_lock); spin_lock_bh(&ab->base_lock); list_for_each_entry_safe(peer, tmp_peer, &ab->peers, list) { -@@ -709,6 +752,9 @@ void ath11k_peer_cleanup(struct ath11k * +@@ -695,6 +738,9 @@ void ath11k_peer_cleanup(struct ath11k * spin_unlock_bh(&ab->base_lock); mutex_unlock(&ab->tbl_mtx_lock); @@ -431,7 +431,7 @@ Signed-off-by: Rameshkumar Sundaram } static int ath11k_wait_for_peer_deleted(struct ath11k *ar, int vdev_id, const u8 *addr) -@@ -743,12 +789,18 @@ static int __ath11k_peer_delete(struct a +@@ -729,12 +775,18 @@ static int __ath11k_peer_delete(struct a int ret; struct ath11k_peer *peer; struct ath11k_base *ab = ar->ab; @@ -450,7 +450,7 @@ Signed-off-by: Rameshkumar Sundaram mutex_lock(&ab->tbl_mtx_lock); spin_lock_bh(&ab->base_lock); -@@ -771,17 +823,35 @@ static int __ath11k_peer_delete(struct a +@@ -757,17 +809,35 @@ static int __ath11k_peer_delete(struct a return -EINVAL; } @@ -504,15 +504,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; +@@ -44,9 +42,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 { +@@ -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/nss/ath11k/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch b/package/kernel/mac80211/patches/nss/ath11k/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch deleted file mode 100644 index fcf9930f222fbd..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch +++ /dev/null @@ -1,384 +0,0 @@ -From 17d1895bad45ec2ef4c8c430ac0fbaff2ff1cf39 Mon Sep 17 00:00:00 2001 -From: Manish Dharanenthiran -Date: Tue, 18 Apr 2023 15:01:42 +0530 -Subject: [PATCH 2/3] CHROMIUM: ath11k: Add retry mechanism for update_rx_queue - reo cmd - -While reo_cmd ring is full, peer delete update rx queue -will be failed as there is no space to send the command -in ring. During the failure scenario, host will do -dma_unmap and free the allocated address but the HW -still have that particular vaddr. So, on next alloc -cycle kernel will allocated the freed addr but HW will -still have the address. This will result in memory -corruption as the host will try to access/write that -memory which is already in-use. - -To avoid this corruption, added new retry mechanism -for HAL_REO_CMD_UPDATE_RX_QUEUE by adding new list to -dp struct and protecting with new lock for access. -This avoids the host free in failure case and will -be freed only when HW freed that particular vaddr. - -Also, updated below changes -1) reo_flush command for sending 1K desc in one -command instead of sending 11 command for single -TID. - -2) Set FWD_MPDU and valid bit flag so that reo -flush will happen soon instead of waiting to -flush the queue. - -Signed-off-by: Manish Dharanenthiran -Signed-off-by: Tamizh Chelvam Raja ---- - drivers/net/wireless/ath/ath11k/core.h | 3 + - drivers/net/wireless/ath/ath11k/debugfs.c | 12 ++ - drivers/net/wireless/ath/ath11k/dp.c | 2 + - drivers/net/wireless/ath/ath11k/dp.h | 15 ++ - drivers/net/wireless/ath/ath11k/dp_rx.c | 167 +++++++++++++++++----- - 5 files changed, 161 insertions(+), 38 deletions(-) - ---- a/drivers/net/wireless/ath/ath11k/core.h -+++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -935,6 +935,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]; -+ u32 hal_reo_cmd_drain; -+ u32 reo_cmd_cache_error; -+ u32 reo_cmd_update_rx_queue_error; - struct ath11k_soc_dp_tx_err_stats tx_err; - struct ath11k_dp_ring_bp_stats bp_stats; - }; ---- 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 - "\nNSS Transmit Failures: %d\n", - atomic_read(&soc_stats->tx_err.nss_tx_fail)); - -+ len += scnprintf(buf + len, size - len, -+ "\nHAL_REO_CMD_DRAIN Counter: %u\n", -+ soc_stats->hal_reo_cmd_drain); -+ -+ len += scnprintf(buf + len, size - len, -+ "\nREO_CMD_CACHE_FLUSH Failure: %u\n", -+ soc_stats->reo_cmd_cache_error); -+ -+ len += scnprintf(buf + len, size - len, -+ "\nREO_CMD_UPDATE_RX_QUEUE Failure: %u\n", -+ soc_stats->reo_cmd_update_rx_queue_error); -+ - len += ath11k_debugfs_dump_soc_ring_bp_stats(ab, buf + len, size - len); - - 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 * - - INIT_LIST_HEAD(&dp->reo_cmd_list); - INIT_LIST_HEAD(&dp->reo_cmd_cache_flush_list); -+ INIT_LIST_HEAD(&dp->reo_cmd_update_rx_queue_list); - INIT_LIST_HEAD(&dp->dp_full_mon_mpdu_list); - spin_lock_init(&dp->reo_cmd_lock); -+ spin_lock_init(&dp->reo_cmd_update_queue_lock); - - dp->reo_cmd_cache_flush_count = 0; - ---- a/drivers/net/wireless/ath/ath11k/dp.h -+++ b/drivers/net/wireless/ath/ath11k/dp.h -@@ -24,6 +24,7 @@ struct dp_rx_tid { - u32 *vaddr; - dma_addr_t paddr; - u32 size; -+ u32 pending_desc_size; - u32 ba_win_sz; - bool active; - -@@ -51,6 +52,14 @@ struct dp_reo_cache_flush_elem { - unsigned long ts; - }; - -+struct dp_reo_update_rx_queue_elem { -+ struct list_head list; -+ struct dp_rx_tid data; -+ int peer_id; -+ u8 tid; -+ bool reo_cmd_update_rx_queue_resend_flag; -+}; -+ - struct dp_reo_cmd { - struct list_head list; - struct dp_rx_tid data; -@@ -296,6 +305,12 @@ struct ath11k_dp { - * - reo_cmd_cache_flush_count - */ - spinlock_t reo_cmd_lock; -+ struct list_head reo_cmd_update_rx_queue_list; -+ /** -+ * protects access to below field, -+ * - reo_cmd_update_rx_queue_list -+ */ -+ spinlock_t reo_cmd_update_queue_lock; - struct ath11k_hp_update_timer reo_cmd_timer; - struct ath11k_hp_update_timer tx_ring_timer[DP_TCL_NUM_RING_MAX]; - }; ---- a/drivers/net/wireless/ath/ath11k/dp_rx.c -+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -21,6 +21,9 @@ - - #define ATH11K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ) - -+static void ath11k_dp_rx_tid_del_func(struct ath11k_dp *dp, void *ctx, -+ enum hal_reo_cmd_status status); -+ - 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( - return 0; - } - -+static int ath11k_peer_rx_tid_delete_handler(struct ath11k_base *ab, -+ struct dp_rx_tid *rx_tid, u8 tid) -+{ -+ struct ath11k_hal_reo_cmd cmd = {0}; -+ struct ath11k_dp *dp = &ab->dp; -+ -+ lockdep_assert_held(&dp->reo_cmd_update_queue_lock); -+ -+ rx_tid->active = false; -+ cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; -+ cmd.addr_lo = lower_32_bits(rx_tid->paddr); -+ cmd.addr_hi = upper_32_bits(rx_tid->paddr); -+ cmd.upd0 |= HAL_REO_CMD_UPD0_VLD; -+ -+ return ath11k_dp_tx_send_reo_cmd(ab, rx_tid, -+ HAL_REO_CMD_UPDATE_RX_QUEUE, -+ &cmd, -+ ath11k_dp_rx_tid_del_func); -+} -+ - void ath11k_dp_reo_cmd_list_cleanup(struct ath11k_base *ab) - { - struct ath11k_dp *dp = &ab->dp; - struct dp_reo_cmd *cmd, *tmp; - struct dp_reo_cache_flush_elem *cmd_cache, *tmp_cache; -+ struct dp_reo_update_rx_queue_elem *cmd_queue, *tmp_queue; - struct dp_rx_tid *rx_tid; - -+ spin_lock_bh(&dp->reo_cmd_update_queue_lock); -+ list_for_each_entry_safe(cmd_queue, tmp_queue, -+ &dp->reo_cmd_update_rx_queue_list, -+ list) { -+ list_del(&cmd_queue->list); -+ rx_tid = &cmd_queue->data; -+ if (rx_tid->vaddr) { -+ dma_unmap_single(ab->dev, rx_tid->paddr, -+ rx_tid->size, DMA_BIDIRECTIONAL); -+ kfree(rx_tid->vaddr); -+ rx_tid->vaddr = NULL; -+ } -+ kfree(cmd_queue); -+ } -+ spin_unlock_bh(&dp->reo_cmd_update_queue_lock); -+ - 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 - } - } - --static void ath11k_dp_reo_cache_flush(struct ath11k_base *ab, -+static int ath11k_dp_reo_cache_flush(struct ath11k_base *ab, - struct dp_rx_tid *rx_tid) - { - struct ath11k_hal_reo_cmd cmd = {0}; - unsigned long tot_desc_sz, desc_sz; - int ret; - -- tot_desc_sz = rx_tid->size; -+ if (rx_tid->pending_desc_size) -+ tot_desc_sz = rx_tid->pending_desc_size; -+ else -+ tot_desc_sz = rx_tid->size; -+ - 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 - HAL_REO_CMD_FLUSH_CACHE, &cmd, - NULL); - if (ret) -- ath11k_warn(ab, -- "failed to send HAL_REO_CMD_FLUSH_CACHE, tid %d (%d)\n", -- rx_tid->tid, ret); -+ rx_tid->pending_desc_size = tot_desc_sz + desc_sz; -+ -+ /* If this fails with ring full condition, then -+ * no need to retry below as it is expected to -+ * fail within short time -+ */ -+ if (ret == -ENOBUFS) -+ goto exit; - } - -+ rx_tid->pending_desc_size = desc_sz; - 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 - ret = ath11k_dp_tx_send_reo_cmd(ab, rx_tid, - HAL_REO_CMD_FLUSH_CACHE, - &cmd, ath11k_dp_reo_cmd_free); -- if (ret) { -- ath11k_err(ab, "failed to send HAL_REO_CMD_FLUSH_CACHE cmd, tid %d (%d)\n", -- rx_tid->tid, ret); -- dma_unmap_single(ab->dev, rx_tid->paddr, rx_tid->size, -- DMA_BIDIRECTIONAL); -- kfree(rx_tid->vaddr); -- rx_tid->vaddr = NULL; -- } -+ -+exit: -+ return ret; - } - - static void ath11k_dp_rx_tid_del_func(struct ath11k_dp *dp, void *ctx, - enum hal_reo_cmd_status status) - { - struct ath11k_base *ab = dp->ab; -- struct dp_rx_tid *rx_tid = ctx; -+ struct dp_rx_tid *rx_tid = ctx, *update_rx_tid; - struct dp_reo_cache_flush_elem *elem, *tmp; -+ struct dp_reo_update_rx_queue_elem *qelem, *qtmp; - - if (status == HAL_REO_CMD_DRAIN) { -+ ab->soc_stats.hal_reo_cmd_drain++; - 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 - return; - } - -+ /* Check if there is any pending rx_queue, if yes then update it */ -+ spin_lock_bh(&dp->reo_cmd_update_queue_lock); -+ list_for_each_entry_safe(qelem, qtmp, &dp->reo_cmd_update_rx_queue_list, -+ list) { -+ if (qelem->reo_cmd_update_rx_queue_resend_flag && -+ qelem->data.active) { -+ update_rx_tid = &qelem->data; -+ -+ if (ath11k_peer_rx_tid_delete_handler(ab, update_rx_tid, qelem->tid)) { -+ update_rx_tid->active = true; -+ break; -+ } -+ update_rx_tid->vaddr = NULL; -+ update_rx_tid->paddr = 0; -+ update_rx_tid->size = 0; -+ update_rx_tid->pending_desc_size = 0; -+ -+ list_del(&qelem->list); -+ kfree(qelem); -+ } -+ } -+ spin_unlock_bh(&dp->reo_cmd_update_queue_lock); -+ - elem = kzalloc(sizeof(*elem), GFP_ATOMIC); - if (!elem) - goto free_desc; -@@ -832,13 +902,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))) { -+ spin_unlock_bh(&dp->reo_cmd_lock); -+ if (ath11k_dp_reo_cache_flush(ab, &elem->data)) { -+ ab->soc_stats.reo_cmd_cache_error++; -+ /* In failure case, just update the timestamp -+ * for flush cache elem and continue -+ */ -+ spin_lock_bh(&dp->reo_cmd_lock); -+ elem->ts = jiffies; -+ break; -+ } -+ spin_lock_bh(&dp->reo_cmd_lock); - list_del(&elem->list); - dp->reo_cmd_cache_flush_count--; -- spin_unlock_bh(&dp->reo_cmd_lock); -- -- ath11k_dp_reo_cache_flush(ab, &elem->data); - kfree(elem); -- spin_lock_bh(&dp->reo_cmd_lock); - } - } - spin_unlock_bh(&dp->reo_cmd_lock); -@@ -854,34 +931,48 @@ free_desc: - void ath11k_peer_rx_tid_delete(struct ath11k *ar, - struct ath11k_peer *peer, u8 tid) - { -- struct ath11k_hal_reo_cmd cmd = {0}; - struct dp_rx_tid *rx_tid = &peer->rx_tid[tid]; -- int ret; -+ struct dp_reo_update_rx_queue_elem *elem, *tmp; -+ struct ath11k_base *ab = ar->ab; -+ struct ath11k_dp *dp = &ab->dp; - - if (!rx_tid->active) - return; - -- rx_tid->active = false; -+ elem = kzalloc(sizeof(*elem), GFP_ATOMIC); -+ if (!elem) { -+ ath11k_warn(ar->ab, "failed to alloc reo_update_rx_queue_elem, rx tid %d\n", -+ rx_tid->tid); -+ return; -+ } -+ elem->reo_cmd_update_rx_queue_resend_flag = false; -+ elem->peer_id = peer->peer_id; -+ elem->tid = tid; -+ memcpy(&elem->data, rx_tid, sizeof(*rx_tid)); -+ spin_lock_bh(&dp->reo_cmd_update_queue_lock); -+ list_add_tail(&elem->list, &dp->reo_cmd_update_rx_queue_list); - -- cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; -- cmd.addr_lo = lower_32_bits(rx_tid->paddr); -- cmd.addr_hi = upper_32_bits(rx_tid->paddr); -- cmd.upd0 |= HAL_REO_CMD_UPD0_VLD; -- ret = ath11k_dp_tx_send_reo_cmd(ar->ab, rx_tid, -- HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, -- ath11k_dp_rx_tid_del_func); -- if (ret) { -- if (ret != -ESHUTDOWN) -- ath11k_err(ar->ab, "failed to send HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n", -- tid, ret); -- dma_unmap_single(ar->ab->dev, rx_tid->paddr, rx_tid->size, -- DMA_BIDIRECTIONAL); -- kfree(rx_tid->vaddr); -+ list_for_each_entry_safe(elem, tmp, &dp->reo_cmd_update_rx_queue_list, -+ list) { -+ rx_tid = &elem->data; -+ -+ if (ath11k_peer_rx_tid_delete_handler(ab, rx_tid, elem->tid)) { -+ rx_tid->active = true; -+ ab->soc_stats.reo_cmd_update_rx_queue_error++; -+ elem->reo_cmd_update_rx_queue_resend_flag = true; -+ break; -+ } - rx_tid->vaddr = NULL; -+ rx_tid->paddr = 0; -+ rx_tid->size = 0; -+ rx_tid->pending_desc_size = 0; -+ -+ list_del(&elem->list); -+ kfree(elem); - } -+ spin_unlock_bh(&dp->reo_cmd_update_queue_lock); - -- rx_tid->paddr = 0; -- rx_tid->size = 0; -+ return; - } - - static int ath11k_dp_rx_link_desc_return(struct ath11k_base *ab, diff --git a/package/kernel/mac80211/patches/nss/ath11k/913-353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch b/package/kernel/mac80211/patches/nss/ath11k/913-353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch deleted file mode 100644 index e8ac589acfc8ec..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/913-353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 0ab84604de1db0f589f7303507f38148ba8f3f04 Mon Sep 17 00:00:00 2001 -From: Nagarajan Maran -Date: Tue, 28 Jun 2022 11:31:50 +0530 -Subject: [PATCH] ath11k: Ignore frags from uninitialized peer in dp - -In certain scenario, fragmented packet is received for self peer, -for which rx_tid and rx_frags are not initialized in datapath. -While handling this fragment, crash is observed as the -rx_frag list is uninitialised and when we walk in -ath11k_dp_rx_h_sort_frags, skb null leads to exception. - -To address this, before processing received fragments we -check dp_setup_done flag is set to ensure that peer -has completed its dp peer setup for fragment queue, -else ignore processing the fragments. - -Also, __fls would have an undefined behavior if the argument -is passed as "0". Hence, added changes to handle the same. - -Below is the call trace of the crash: - - CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.4.164 #0 - Hardware name: Qualcomm Technologies, Inc. IPQ6018/AP-CP01-C1 (DT) - pstate: a0400005 (NzCv daif +PAN -UAO) - pc : ath11k_dp_process_rx_err+0x550/0x1084 [ath11k] - lr : ath11k_dp_process_rx_err+0x4e0/0x1084 [ath11k] - - Call trace: - ath11k_dp_process_rx_err+0x550/0x1084 [ath11k] - ath11k_dp_service_srng+0x70/0x370 [ath11k] - 0xffffffc009693a04 - __napi_poll+0x30/0xa4 - net_rx_action+0x118/0x270 - __do_softirq+0x10c/0x244 - irq_exit+0x64/0xb4 - __handle_domain_irq+0x88/0xac - gic_handle_irq+0x74/0xbc - el1_irq+0xf0/0x1c0 - arch_cpu_idle+0x10/0x18 - do_idle+0x104/0x248 - cpu_startup_entry+0x20/0x64 - rest_init+0xd0/0xdc - arch_call_rest_init+0xc/0x14 - start_kernel+0x480/0x4b8 - Code: f9400281 f94066a2 91405021 b94a0023 (f9406401) - -Signed-off-by: Harshitha Prem -Signed-off-by: Nagarajan Maran ---- - drivers/net/wireless/ath/ath11k/dp.c | 3 ++- - drivers/net/wireless/ath/ath11k/dp_rx.c | 11 ++++++++++- - drivers/net/wireless/ath/ath11k/peer.h | 2 ++ - 3 files changed, 14 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/ath/ath11k/dp.c -+++ b/drivers/net/wireless/ath/ath11k/dp.c -@@ -38,6 +38,7 @@ void ath11k_dp_peer_cleanup(struct ath11 - ath11k_peer_rx_tid_cleanup(ar, peer); - peer->dp_setup_done = false; - crypto_free_shash(peer->tfm_mmic); -+ peer->dp_setup_done = false; - spin_unlock_bh(&ab->base_lock); - } - ---- a/drivers/net/wireless/ath/ath11k/peer.h -+++ b/drivers/net/wireless/ath/ath11k/peer.h -@@ -93,6 +93,7 @@ struct ath11k_peer { - u16 sec_type; - u16 sec_type_grp; - bool is_authorized; -+ /* Peer's datapath set flag */ - bool dp_setup_done; - struct ppdu_user_delayba ppdu_stats_delayba; - bool delayba_flag; diff --git a/package/kernel/mac80211/patches/nss/ath11k/913-356-ath11k-invalid-desc-sanity-check.patch b/package/kernel/mac80211/patches/nss/ath11k/913-356-ath11k-invalid-desc-sanity-check.patch deleted file mode 100644 index 5f01d21384ec1c..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/913-356-ath11k-invalid-desc-sanity-check.patch +++ /dev/null @@ -1,74 +0,0 @@ -From c7e37aebbe19056eb7b61299e75c863263acf2b9 Mon Sep 17 00:00:00 2001 -From: Nagarajan Maran -Date: Tue, 9 Aug 2022 13:22:43 +0530 -Subject: [PATCH] Fix SKB corruption in REO destination ring - -In the traffic cases, randomly, invalid RX descriptor -from REO destination ring is received. This -invalid descriptor causes wrong SKB to be fetched -which in turn causes SKB memory corruption issue. - -Introduced Sanity check to validate the descriptor, -before processing the SKB. - -During the failure scenario, invalid RX descriptor -filled with values "0" is received which in-turn -corrupts the SKB stored in the ldr lookup -with buffer id "0". Changed the start id for -idr allocation to "1" and the buffer id "0" is -reserved for error validation. - - -Crash Signature : - -Unable to handle kernel paging request at virtual address 3f004900 -During the crash, -PC points to "b15_dma_inv_range+0x30/0x50" -LR points to "dma_cache_maint_page+0x8c/0x128". -The Backtrace obtained is as follows: -[<8031716c>] (b15_dma_inv_range) from [<80313a4c>] (dma_cache_maint_page+0x8c/0x128) -[<80313a4c>] (dma_cache_maint_page) from [<80313b90>] (__dma_page_dev_to_cpu+0x28/0xcc) -[<80313b90>] (__dma_page_dev_to_cpu) from [<7fb5dd68>] (ath11k_dp_process_rx+0x1e8/0x4a4 [ath11k]) -[<7fb5dd68>] (ath11k_dp_process_rx [ath11k]) from [<7fb53c20>] (ath11k_dp_service_srng+0xb0/0x2ac [ath11k]) -[<7fb53c20>] (ath11k_dp_service_srng [ath11k]) from [<7f67bba4>] (ath11k_pci_ext_grp_napi_poll+0x1c/0x78 [ath11k_pci]) -[<7f67bba4>] (ath11k_pci_ext_grp_napi_poll [ath11k_pci]) from [<807d5cf4>] (__napi_poll+0x28/0xb8) -[<807d5cf4>] (__napi_poll) from [<807d5f28>] (net_rx_action+0xf0/0x280) -[<807d5f28>] (net_rx_action) from [<80302148>] (__do_softirq+0xd0/0x280) -[<80302148>] (__do_softirq) from [<80320408>] (irq_exit+0x74/0xd4) -[<80320408>] (irq_exit) from [<803638a4>] (__handle_domain_irq+0x90/0xb4) -[<803638a4>] (__handle_domain_irq) from [<805bedec>] (gic_handle_irq+0x58/0x90) -[<805bedec>] (gic_handle_irq) from [<80301a78>] (__irq_svc+0x58/0x8c) - -Signed-off-by: Nagarajan Maran ---- - drivers/net/wireless/ath/ath11k/dp_rx.c | 18 ++++++++++++++---- - 1 file changed, 14 insertions(+), 4 deletions(-) - ---- a/drivers/net/wireless/ath/ath11k/dp_rx.c -+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -3216,6 +3216,16 @@ try_again: - while (likely(desc = - (struct hal_reo_dest_ring *)ath11k_hal_srng_dst_get_next_entry(ab, - srng))) { -+ -+ push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON, -+ desc->info0); -+ if (unlikely(push_reason == -+ HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED)) { -+ ath11k_warn(ab,"Received invalid desc\n"); -+ ab->soc_stats.hal_reo_error[dp->reo_dst_ring[ring_id].ring_id]++; -+ continue; -+ } -+ - cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, - desc->buf_addr_info.info1); - buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID, -@@ -3246,8 +3256,6 @@ try_again: - - num_buffs_reaped[mac_id]++; - -- push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON, -- desc->info0); - if (unlikely(push_reason != - HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION)) { - dev_kfree_skb_any(msdu); diff --git a/package/kernel/mac80211/patches/nss/ath11k/913-374-ath11k-Check-skb_headroom-before-using-skb_push.patch b/package/kernel/mac80211/patches/nss/ath11k/913-374-ath11k-Check-skb_headroom-before-using-skb_push.patch deleted file mode 100644 index 48d768d519bd43..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/913-374-ath11k-Check-skb_headroom-before-using-skb_push.patch +++ /dev/null @@ -1,263 +0,0 @@ -From efecc6e8355d02aeac7bf1a43397551440a8d0d8 Mon Sep 17 00:00:00 2001 -From: Tamizh Chelvam Raja -Date: Thu, 30 Mar 2023 22:12:56 +0530 -Subject: [PATCH] ath11k: Check skb_headroom before using skb_push - -Below kernel panic may occur if there is no -skb_headroom available for performing skb_push. - -<4>[67506.565072] CPU: 1 PID: 1741 Comm: ap-wireless-opt Not tainted 5.4.89+ #0 -<4>[67506.578860] Hardware name: Generic DT based system -<4>[67506.585728] PC is at fortify_panic+0x10/0x18 -<4>[67506.590406] LR is at fortify_panic+0x10/0x18 - -(fortify_panic) from [<7f2cd3cc>] (ath11k_dp_rx_crypto_icv_len+0x1e0/0x161c [ath11k]) -(ath11k_dp_rx_crypto_icv_len [ath11k]) from [<7f2cdbac>] (ath11k_dp_rx_crypto_icv_len+0x9c0/0x161c [ath11k]) -(ath11k_dp_rx_crypto_icv_len [ath11k]) from [<7f2ce0e8>] (ath11k_dp_rx_crypto_icv_len+0xefc/0x161c [ath11k]) -(ath11k_dp_rx_crypto_icv_len [ath11k]) from [<7f2cedb0>] (ath11k_dp_process_rx+0x4ec/0x544 [ath11k]) -(ath11k_dp_process_rx [ath11k]) from [<7f2c417c>] (ath11k_dp_service_srng+0xdc/0x2a0 [ath11k]) -(ath11k_dp_service_srng [ath11k]) from [<7f0d78c8>] (ath11k_pci_ext_grp_napi_poll+0x20/0x50 [ath11k_pci]) -(ath11k_pci_ext_grp_napi_poll [ath11k_pci]) from [<806a6a74>] (__napi_poll+0x28/0xb8) -(__napi_poll) from [<806a6c9c>] (net_rx_action+0xec/0x280) -(net_rx_action) from [<8010226c>] (__do_softirq+0xc4/0x248) -(__do_softirq) from [<8011f230>] (irq_exit+0x6c/0xcc) -(irq_exit) from [<80162a08>] (__handle_domain_irq+0x8c/0xb0) -(__handle_domain_irq) from [<803f0188>] (gic_handle_irq+0x54/0x8c) -(gic_handle_irq) from [<80101a8c>] (__irq_svc+0x6c/0xa8) - -Fix this by checking skb_headroom and expand the -headroom if required size is not available. - -Signed-off-by: Tamizh Chelvam Raja ---- - drivers/net/wireless/ath/ath11k/dp_rx.c | 70 +++++++++++++++++++++++++ - 1 file changed, 70 insertions(+) - ---- 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 - size_t hdr_len, crypto_len; - struct ieee80211_hdr *hdr; - u16 fc, qos_ctl = 0; -+ int expand_by = 0; - u8 *crypto_hdr; - - if (!(status->flag & RX_FLAG_IV_STRIPPED)) { - crypto_len = ath11k_dp_rx_crypto_param_len(ar, enctype); -+ if (skb_headroom(msdu) < crypto_len) { -+ expand_by = crypto_len - skb_headroom(msdu); -+ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) -+ return; -+ } - crypto_hdr = skb_push(msdu, crypto_len); - ath11k_dp_rx_desc_get_crypto_header(ab, rx_desc, crypto_hdr, enctype); - } - - fc = ath11k_dp_rxdesc_get_mpdu_frame_ctrl(ab, rx_desc); - hdr_len = ieee80211_hdrlen(fc); -+ 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; -+ } - 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 - u8 da[ETH_ALEN]; - u8 sa[ETH_ALEN]; - u16 qos_ctl = 0; -+ int expand_by = 0; - u8 *qos, *crypto_hdr; - bool add_qos_ctrl = false; - -@@ -2359,26 +2371,46 @@ static void ath11k_dp_rx_h_undecap_nwifi - } - - if (!(status->flag & RX_FLAG_IV_STRIPPED)) { -+ 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; -+ } - if (first_hdr) { -- memcpy(skb_push(msdu, -- ath11k_dp_rx_crypto_param_len(ar, enctype)), -- (void *)hdr + hdr_len, -- ath11k_dp_rx_crypto_param_len(ar, enctype)); -+ memcpy(skb_push(msdu, crypto_param_len), -+ (void *)hdr + hdr_len, crypto_param_len); - } else { -- crypto_hdr = skb_push(msdu, ath11k_dp_rx_crypto_param_len(ar, enctype)); -+ crypto_hdr = skb_push(msdu, crypto_param_len); - ath11k_dp_rx_desc_get_crypto_header(ar->ab, - rxcb->rx_desc, crypto_hdr, enctype); - } - } - - if (!rxcb->is_first_msdu || add_qos_ctrl) { -+ if (skb_headroom(msdu) < IEEE80211_QOS_CTL_LEN) { -+ expand_by = IEEE80211_QOS_CTL_LEN - skb_headroom(msdu); -+ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) -+ return; -+ } - memcpy(skb_push(msdu, - IEEE80211_QOS_CTL_LEN), &qos_ctl, - IEEE80211_QOS_CTL_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), decap_hdr, hdr_len); - return; - } - -+ 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); - - /* original 802.11 header has a different DA and in -@@ -2487,6 +2519,7 @@ static void ath11k_dp_rx_h_undecap_eth(s - u8 da[ETH_ALEN]; - u8 sa[ETH_ALEN]; - void *rfc1042; -+ int expand_by = 0; - 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 - ether_addr_copy(sa, eth->h_source); - rfc.snap_type = eth->h_proto; - skb_pull(msdu, sizeof(struct ethhdr)); -+ if (skb_headroom(msdu) < sizeof(struct ath11k_dp_rfc1042_hdr)) { -+ expand_by = sizeof(struct ath11k_dp_rfc1042_hdr) - skb_headroom(msdu); -+ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) -+ return; -+ } - 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 - skb_pull(msdu, sizeof(struct ethhdr)); - - /* push rfc1042/llc/snap */ -+ if (skb_headroom(msdu) < sizeof(struct ath11k_dp_rfc1042_hdr)) { -+ expand_by = sizeof(struct ath11k_dp_rfc1042_hdr) - skb_headroom(msdu); -+ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) -+ return; -+ } - 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 - 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); - - exit: -@@ -2547,6 +2600,7 @@ static void ath11k_dp_rx_h_undecap_snap( - struct ieee80211_hdr *hdr; - size_t hdr_len; - u8 l3_pad_bytes; -+ int expand_by = 0; - struct hal_rx_desc *rx_desc; - struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); - -@@ -2571,12 +2625,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); - } - -@@ -2706,7 +2770,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; -@@ -2721,7 +2785,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) { -@@ -2942,10 +3007,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; -+ int expand_by = 0; - - if (status->encoding == RX_ENC_HE && - !(status->flag & RX_FLAG_RADIOTAP_HE) && - !(status->flag & RX_FLAG_SKIP_MONITOR)) { -+ if (skb_headroom(msdu) < sizeof(known)) { -+ expand_by = sizeof(known) - skb_headroom(msdu); -+ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) -+ goto exit; -+ } - he = skb_push(msdu, sizeof(known)); - memcpy(he, &known, sizeof(known)); - status->flag |= RX_FLAG_RADIOTAP_HE; -@@ -3001,6 +3072,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/913-830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch b/package/kernel/mac80211/patches/nss/ath11k/913-830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch deleted file mode 100644 index 28b4fdf6468337..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/913-830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 5b4a0de1356558f58df9c6a1f46c7c0ce2fadb03 Mon Sep 17 00:00:00 2001 -From: Yuvasree Sivasankaran -Date: Mon, 28 Aug 2023 14:48:41 +0530 -Subject: [PATCH] ath11k: Avoiding memset of ppdu-info for next skb - -While parsing mon status from skb, ppdu_info got memset with zero during -next skb fetch from queue or mon ring in case a single PPDU is more than -RX_BUFFER_SIZE. Because of this nss value got override for respective -ppdu and leads to warn_on in mac80211.Removed memset from next skb fetch -and added flag to track discontinued skb in case of fetch from skb. - -WARN_ON Reason: - -Rate marked as an HE rate but data is invalid: MCS: 0, NSS: 0 - -Below the call trace observed: - - Call trace: - ieee80211_rx_list+0x1d4/0xcc4 [mac80211] - ieee80211_rx_napi+0x58/0xcc [mac80211] - ath11k_dp_rx_deliver_msdu+0x358/0x3e4 [ath11k] - ath11k_dp_rx_mon_deliver.isra.27+0x470/0x4cc [ath11k] - ath11k_dp_rx_mon_dest_process+0x1cc/0x2bc [ath11k] - ath11k_dp_rx_process_mon_status+0x5ec/0xf90 [ath11k] - ath11k_dp_rx_process_mon_rings+0x40c/0x44c [ath11k] - ath11k_dp_service_srng+0x114/0x2c0 [ath11k] - ath11k_ahb_ext_grp_napi_poll+0x30/0xa0 [ath11k_ahb] - __napi_poll+0x30/0xa4 - net_rx_action+0x118/0x270 - __do_softirq+0x10c/0x244 - irq_exit+0x64/0xb4 - __handle_domain_irq+0x88/0xac - gic_handle_irq+0x74/0xbc - el1_irq+0xf0/0x1c0 - arch_cpu_idle+0x10/0x18 - do_idle+0x104/0x248 - cpu_startup_entry+0x20/0x64 - rest_init+0xd0/0xdc - arch_call_rest_init+0xc/0x14 - start_kernel+0x46c/0x4a4 - --[ end trace e754e9088a240857 ]--- - -Signed-off-by: Yuvasree Sivasankaran ---- - drivers/net/wireless/ath/ath11k/dp_rx.c | 6 ++++-- - drivers/net/wireless/ath/ath11k/hal_rx.h | 1 + - 2 files changed, 5 insertions(+), 2 deletions(-) - ---- 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 - if (!num_buffs_reaped) - goto exit; - -- memset(ppdu_info, 0, sizeof(*ppdu_info)); -+ if (!ppdu_info->ppdu_continuation) -+ memset(ppdu_info, 0, sizeof(*ppdu_info)); -+ - 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 - if (log_type != ATH11K_PKTLOG_TYPE_INVALID) - trace_ath11k_htt_rxdesc(ar, skb->data, log_type, rx_buf_sz); - -- memset(ppdu_info, 0, sizeof(*ppdu_info)); - 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) { - dev_kfree_skb_any(skb); -+ ppdu_info->ppdu_continuation = true; - continue; - } - ---- 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]; - 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]; - }; - diff --git a/package/kernel/mac80211/patches/nss/subsys/235-002-mac80211-Add-support-for-beacon-tx-mode.patch b/package/kernel/mac80211/patches/nss/subsys/235-002-mac80211-Add-support-for-beacon-tx-mode.patch deleted file mode 100644 index 6fb460f6b4f740..00000000000000 --- a/package/kernel/mac80211/patches/nss/subsys/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/nss/subsys/300-mac80211-nss-mesh-offload-support.patch b/package/kernel/mac80211/patches/nss/subsys/300-mac80211-nss-mesh-offload-support.patch index e0b275fc5af664..f1dc602953c69e 100644 --- a/package/kernel/mac80211/patches/nss/subsys/300-mac80211-nss-mesh-offload-support.patch +++ b/package/kernel/mac80211/patches/nss/subsys/300-mac80211-nss-mesh-offload-support.patch @@ -66,10 +66,10 @@ Signed-off-by: Gautham Kumar Senthilkumaran }; /* -@@ -794,6 +803,11 @@ struct ieee80211_bss_conf { +@@ -792,6 +801,11 @@ struct ieee80211_bss_conf { + bool eht_su_beamformee; bool eht_mu_beamformer; bool nss_ap_isolate; - enum nl80211_beacon_tx_mode beacon_tx_mode; + + /* Mesh configuration for nss offload */ + u8 nss_offld_ttl; @@ -78,7 +78,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran }; /** -@@ -1273,6 +1287,8 @@ struct ieee80211_rate_status { +@@ -1271,6 +1285,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 { +@@ -1281,6 +1297,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 { +@@ -1773,6 +1791,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 { +@@ -1780,6 +1799,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 { +@@ -2763,6 +2783,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 { +@@ -4263,6 +4284,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 { +@@ -4646,6 +4669,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 +@@ -7479,4 +7508,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( +@@ -2512,6 +2512,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( +@@ -2528,8 +2529,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( +@@ -2543,8 +2547,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( +@@ -2579,8 +2587,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( +@@ -2622,6 +2634,7 @@ static int ieee80211_update_mesh_config( conf->dot11MeshConnectedToAuthServer = nconf->dot11MeshConnectedToAuthServer; ieee80211_mbss_info_change_notify(sdata, BSS_CHANGED_BEACON); diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index 76896c8fc046ca..6614d8d496b354 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 @@ -73,48 +73,48 @@ 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_ - if (mpath->flags & MESH_PATH_RESOLVED) - pinfo->flags |= NL80211_MPATH_FLAG_RESOLVED; - pinfo->hop_count = mpath->hop_count; + if (mpath->flags & MESH_PATH_RESOLVED) + pinfo->flags |= NL80211_MPATH_FLAG_RESOLVED; + pinfo->hop_count = mpath->hop_count; - pinfo->path_change_count = mpath->path_change_count; + pinfo->path_change_count = atomic_read(&mpath->path_change_count); } - + static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev, --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -126,7 +126,7 @@ struct mesh_path { - unsigned long fast_tx_check; - bool is_root; - bool is_gate; + unsigned long fast_tx_check; + bool is_root; + bool is_gate; - u32 path_change_count; + atomic_t path_change_count; }; - + #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 - if (next_hop) - ether_addr_copy(old_next_hop_addr, next_hop->sta.addr); - if (next_hop != sta) { + 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); + flush_mpath = true; + } + mesh_path_assign_nexthop(mpath, sta); @@ -565,7 +568,10 @@ 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) { + 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); + flush_mpath = true; + } + mesh_path_assign_nexthop(mpath, sta); diff --git a/package/kernel/mac80211/patches/nss/subsys/913-726-mac80211-fix-crash-when-accessing-null-pointer.patch b/package/kernel/mac80211/patches/nss/subsys/913-726-mac80211-fix-crash-when-accessing-null-pointer.patch deleted file mode 100644 index 8e60a5f6b255f7..00000000000000 --- a/package/kernel/mac80211/patches/nss/subsys/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) { From 69830c2b422208a9ad841dffdce73129ee886439 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 27 Jan 2024 20:11:51 -0500 Subject: [PATCH 101/225] ath11k_nss: Remove superfluous patches Remove patches unrelated to NSS offloading to minimize bloat and better track NSS related issues. --- package/kernel/mac80211/Makefile | 2 +- ...-adding-support-for-mgmt-frame-stats.patch | 2 +- ...91-ath11k-add-mgmt-and-data-ack-rssi.patch | 48 - .../211-ath11k-add-obss-pd-support.patch | 64 -- ...14-ath11k-qos-null-frame-tx-over-wmi.patch | 32 +- .../905-ath11k-add-support-memory-stats.patch | 936 ------------------ ...se-DECLARE_BITMAP-for-idr-operations.patch | 16 +- ...1k-add-simple-tx-handler-for-AP-mode.patch | 185 ---- .../911-335-ath11k-fix-ar-ops-crash.patch | 71 -- 9 files changed, 40 insertions(+), 1316 deletions(-) delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/191-ath11k-add-mgmt-and-data-ack-rssi.patch delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/211-ath11k-add-obss-pd-support.patch delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/905-ath11k-add-support-memory-stats.patch delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/911-335-0006-ath11k-add-simple-tx-handler-for-AP-mode.patch delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/911-335-ath11k-fix-ar-ops-crash.patch diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 6098a81eb1baf5..fa18ff92424564 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 PKG_VERSION:=6.5 -PKG_RELEASE:=9 +PKG_RELEASE:=10 # PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.15.58/ PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/ PKG_HASH:=908c22dceba185eab83caa5a1e58ce6b3ebdc58f099c3fd3e11c7352ebfab2d7 diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 7a2c473b57a963..11205fa770ac7c 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -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/nss/ath11k/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 deleted file mode 100644 index dea5600324f536..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/191-ath11k-add-mgmt-and-data-ack-rssi.patch +++ /dev/null @@ -1,48 +0,0 @@ ---- 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 - 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/wmi.c -+++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -4065,6 +4065,7 @@ 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; -@@ -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/nss/ath11k/211-ath11k-add-obss-pd-support.patch b/package/kernel/mac80211/patches/nss/ath11k/211-ath11k-add-obss-pd-support.patch deleted file mode 100644 index 0fdb80c33fa961..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/211-ath11k-add-obss-pd-support.patch +++ /dev/null @@ -1,64 +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 -@@ -22,7 +22,6 @@ - #include "testmode.h" - #include "peer.h" - #include "debugfs_sta.h" --#include "hif.h" - #include "wow.h" - #include "nss.h" - -@@ -3272,7 +3271,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; -+ u8 non_srg_th = ATH11K_OBSS_PD_THRESHOLD_DISABLED; -+ s8 srg_th = 0; - - pdev_id = ar->pdev->pdev_id; - -@@ -3301,8 +3301,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 +3315,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/nss/ath11k/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 index 642c14ea4b9f59..5e77b6f44bd272 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -270,7 +270,37 @@ Signed-off-by: Sowmiya Sree Elavalagan { struct sk_buff *msdu; struct ieee80211_tx_info *info; -@@ -5937,12 +5987,13 @@ skip_mgmt_stats: +@@ -5894,6 +5944,11 @@ static int wmi_process_mgmt_tx_comp(stru + info->status.ack_signal = tx_compl_param->ack_rssi; + } + ++ /* dont update rates in this path, qos null data tx completions also can ++ * take this path in case of nss offload and can update invalid rates. ++ */ ++ info->status.rates[0].idx = -1; ++ + hdr = (struct ieee80211_hdr *)msdu->data; + frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, hdr->frame_control); + +@@ -5912,10 +5967,13 @@ static int wmi_process_mgmt_tx_comp(stru + 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]++; ++ 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: +@@ -5937,12 +5995,13 @@ skip_mgmt_stats: return 0; } diff --git a/package/kernel/mac80211/patches/nss/ath11k/905-ath11k-add-support-memory-stats.patch b/package/kernel/mac80211/patches/nss/ath11k/905-ath11k-add-support-memory-stats.patch deleted file mode 100644 index fabfbaba24ecdf..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/905-ath11k-add-support-memory-stats.patch +++ /dev/null @@ -1,936 +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 -@@ -909,6 +909,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; -@@ -998,6 +1015,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; - -@@ -1064,6 +1082,7 @@ struct ath11k_base { - - atomic_t num_max_allowed; - struct ath11k_num_vdevs_peers *num_vdevs_peers; -+ bool enable_memory_stats; - bool stats_disable; - - u32 max_ast_index; ---- 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; - } - -@@ -1045,6 +1049,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)) -@@ -1060,6 +1164,12 @@ int ath11k_debugfs_pdev_create(struct at - debugfs_create_file("sram", 0400, ab->debugfs_soc, ab, - &fops_sram_dump); - -+ 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; - } - -@@ -1686,6 +1796,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); - ---- 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 -@@ -333,6 +333,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 -@@ -4052,6 +4052,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; -@@ -4065,6 +4067,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++) { -@@ -4151,9 +4155,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); - -@@ -8105,6 +8116,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, -@@ -8112,6 +8125,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 -@@ -1061,6 +1061,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 - */ -@@ -1091,6 +1094,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; - } -@@ -1107,6 +1111,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; -@@ -1142,6 +1149,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; -@@ -1366,6 +1375,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); -@@ -1390,6 +1402,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; - } -@@ -1413,6 +1427,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), -@@ -1432,6 +1448,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; - } -@@ -1884,6 +1902,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; - -@@ -1915,6 +1936,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; - } -@@ -2602,6 +2625,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"); -@@ -2633,6 +2657,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); -@@ -2804,6 +2830,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; -@@ -2923,6 +2951,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; - } -@@ -3040,6 +3069,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; -@@ -3086,6 +3117,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 */ -@@ -3104,6 +3137,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); -@@ -3126,6 +3160,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 */ -@@ -3166,6 +3202,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; - } -@@ -3184,6 +3221,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 */ -@@ -3222,6 +3261,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); - } - -@@ -3237,6 +3277,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 */ -@@ -3276,6 +3318,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; - } -@@ -3301,6 +3345,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; - -@@ -3346,6 +3392,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; -@@ -901,6 +904,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"); -@@ -7242,6 +7244,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) -@@ -9035,6 +9038,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/nss/ath11k/911-335-0002-ath11k-use-DECLARE_BITMAP-for-idr-operations.patch b/package/kernel/mac80211/patches/nss/ath11k/911-335-0002-ath11k-use-DECLARE_BITMAP-for-idr-operations.patch index 7b87edb0ae6baa..33a5167cf41c2b 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/911-335-0002-ath11k-use-DECLARE_BITMAP-for-idr-operations.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/911-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 @@ diff --git a/package/kernel/mac80211/patches/nss/ath11k/911-335-0006-ath11k-add-simple-tx-handler-for-AP-mode.patch b/package/kernel/mac80211/patches/nss/ath11k/911-335-0006-ath11k-add-simple-tx-handler-for-AP-mode.patch deleted file mode 100644 index c61c206c417de7..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/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/nss/ath11k/911-335-ath11k-fix-ar-ops-crash.patch b/package/kernel/mac80211/patches/nss/ath11k/911-335-ath11k-fix-ar-ops-crash.patch deleted file mode 100644 index ffae27277d7316..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/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; - } - } From c71108b00864e7be7ebac300aad4298b3471bfc4 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 27 Jan 2024 23:34:23 -0500 Subject: [PATCH 102/225] ath11k_nss: Refactor patches to use upstream names Reworked patches to use upstream QSDK names. Allows for better tracking --- ...9-ath11k-add-HE-stats-in-peer-stats.patch} | 58 ++++----- ...dma-counter-increamenting-improperly.patch | 2 +- .../113-ath11k-add-8023-undecap-support.patch | 4 +- ...-adding-support-for-mgmt-frame-stats.patch | 20 ++-- ...1k-remove-error-on-soc-debugfs-fail.patch} | 22 ++-- ...> 188-ath11k-m3-ssr-dump-collection.patch} | 0 ...-ath11k_nss-add-nss-driver-interface.patch | 6 +- .../199-003-ath11k-add-nss-support.patch | 56 ++++----- ...-ath11k-Add-support-for-dynamic-vlan.patch | 4 +- ...207-ath11k-Enable-256_512MB-profiles.patch | 4 +- ...oad-changes-to-NSS-driver-interface.patch} | 30 ++--- ...support-on-NSS-offload-for-STA-mode.patch} | 61 +++++----- ...14-ath11k-qos-null-frame-tx-over-wmi.patch | 49 ++++---- ...11k-Disable-rx_header-tlv-for-2K-SKB.patch | 56 ++++----- ...01-ath11k-account-tx-rx-packets-flow.patch | 34 +++--- ...dev-in-NSS-for-AP_VLAN-vif-handling.patch} | 46 +++---- ...port-for-WDS-offload-in-NSS-offload.patch} | 52 ++++---- ...ev-in-NSS-for-dynamic-VLAN-handling.patch} | 18 +-- ...dynamic-VLAN-support-in-NSS-offload.patch} | 56 ++++----- ...dst-ring-descriptors-from-cacheable-.patch | 2 +- ...ow-fast-rx-by-bypassing-stats-update.patch | 32 ++--- ...perf.patch => 244-ath11k-dp-tx-perf.patch} | 85 ++++++------- ...ch => 301-ath11k-nss-mcbc-exception.patch} | 42 +++---- ...-nss-thread-priority-during-pdev_ini.patch | 20 ++-- ...e-free-of-peer-rx_tid-during-reo-cmd.patch | 2 +- ...0-ath11k-sync-wds_ast_entry-updates.patch} | 24 ++-- ...0001-ath11k-optimize-tx-completions.patch} | 22 ++-- ...e-DECLARE_BITMAP-for-idr-operations.patch} | 14 +-- ...TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch | 19 +-- ...1k-skip-status-ring-entry-processing.patch | 10 +- ...t-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch} | 2 +- ...-fix-clear-peer-keys-during-disassoc.patch | 4 +- ...-fix-tkip-encryption-traffic-failure.patch | 2 +- ...t-ast-index-assignment-for-wds-peer.patch} | 15 +-- ...-event-handler-support-for-link-desc.patch | 6 +- .../702-ath11k-fix-memory-leak-in-dp-rx.patch | 4 +- ...04-300-ath11k-nss_get_arvif_from_dev.patch | 113 ------------------ ...support-to-send-the-QoS-Null-Data-fr.patch | 2 +- ...ath11k-Add-support-for-dynamic-vlan.patch} | 0 ...-iftype-support-on-NSS-offload-case.patch} | 14 +-- ...dynamic-VLAN-support-on-NSS-offload.patch} | 4 +- .../nss/subsys/245-compilation_fix.patch | 8 +- ...300-ath11k-nss-mesh-offload-support.patch} | 22 ++-- ...CL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch} | 4 +- ...-0005-mac80211-simple-tx-for-AP-mode.patch | 4 +- .../336-mac80211-Mesh-Fast-rx-support.patch | 10 +- ...mac80211-fix-unconditional-sta-usage.patch | 2 +- ...rning-with-monitor-interface-restart.patch | 2 +- ...ncapsulation-of-EAPOL-frames-if-OFFL.patch | 18 +-- ...fix-RCU-stall-in-mesh-fast-xmit-path.patch | 2 +- ...-the-frame-to-driver-tx-ops-directly.patch | 2 +- ...se-HW-checksum-offload-only-for-ethm.patch | 6 +- .../829-mac80211-fix-mesh-ping-issue.patch | 8 +- 53 files changed, 485 insertions(+), 619 deletions(-) rename package/kernel/mac80211/patches/nss/ath11k/{902-069-ath11k-add-HE-stats-in-peer-stats.patch => 069-ath11k-add-HE-stats-in-peer-stats.patch} (94%) rename package/kernel/mac80211/patches/nss/ath11k/{907-ath11k-remove-error-on-soc-debugfs-fail.patch => 181-ath11k-remove-error-on-soc-debugfs-fail.patch} (88%) rename package/kernel/mac80211/patches/nss/ath11k/{906-ath11k-m3-ssr-dump-collection.patch => 188-ath11k-m3-ssr-dump-collection.patch} (100%) rename package/kernel/mac80211/patches/nss/ath11k/{902-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch => 211-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch} (96%) rename package/kernel/mac80211/patches/nss/ath11k/{902-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch => 211-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch} (94%) rename package/kernel/mac80211/patches/nss/ath11k/{903-002-ath11k-add-support-for-ext-vdev-in-NSS-for-AP_VLAN-vif-handling.patch => 235-002-ath11k-add-support-for-ext-vdev-in-NSS-for-AP_VLAN-vif-handling.patch} (94%) rename package/kernel/mac80211/patches/nss/ath11k/{903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch => 235-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch} (92%) rename package/kernel/mac80211/patches/nss/ath11k/{904-002-ath11k-extend-ext-vdev-in-NSS-for-dynamic-VLAN-handling.patch => 236-002-ath11k-extend-ext-vdev-in-NSS-for-dynamic-VLAN-handling.patch} (92%) rename package/kernel/mac80211/patches/nss/ath11k/{904-003-ath11k-add-dynamic-VLAN-support-in-NSS-offload.patch => 236-003-ath11k-add-dynamic-VLAN-support-in-NSS-offload.patch} (90%) rename package/kernel/mac80211/patches/nss/ath11k/{911-244-ath11k-dp-tx-perf.patch => 244-ath11k-dp-tx-perf.patch} (89%) rename package/kernel/mac80211/patches/nss/ath11k/{908-301-ath11k-nss-mcbc-exception.patch => 301-ath11k-nss-mcbc-exception.patch} (86%) rename package/kernel/mac80211/patches/nss/ath11k/{908-330-ath11k-sync-wds_ast_entry-updates.patch => 330-ath11k-sync-wds_ast_entry-updates.patch} (96%) rename package/kernel/mac80211/patches/nss/ath11k/{911-335-0001-ath11k-optimize-tx-completions.patch => 335-0001-ath11k-optimize-tx-completions.patch} (93%) rename package/kernel/mac80211/patches/nss/ath11k/{911-335-0002-ath11k-use-DECLARE_BITMAP-for-idr-operations.patch => 335-0002-ath11k-use-DECLARE_BITMAP-for-idr-operations.patch} (95%) rename package/kernel/mac80211/patches/nss/ath11k/{913-341-ath11k-fix-support-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch => 341-ath11k-fix-support-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch} (97%) rename package/kernel/mac80211/patches/nss/ath11k/{908-362-ath11k-fix-incorrect-ast-index-assignment-for-wds-peer.patch => 362-ath11k-fix-incorrect-ast-index-assignment-for-wds-peer.patch} (84%) delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/904-300-ath11k-nss_get_arvif_from_dev.patch rename package/kernel/mac80211/patches/nss/subsys/{207-mac80211-Add-support-for-dynamic-vlan.patch => 207-ath11k-Add-support-for-dynamic-vlan.patch} (100%) rename package/kernel/mac80211/patches/nss/subsys/{902-000-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch => 235-001-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch} (94%) rename package/kernel/mac80211/patches/nss/subsys/{902-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch => 236-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch} (97%) rename package/kernel/mac80211/patches/nss/subsys/{300-mac80211-nss-mesh-offload-support.patch => 300-ath11k-nss-mesh-offload-support.patch} (98%) rename package/kernel/mac80211/patches/nss/subsys/{335-0003-mac80211-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch => 335-0003-ath11k-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch} (94%) diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 94% rename from package/kernel/mac80211/patches/nss/ath11k/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 4831424fa40810..c0ecee94867c73 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 { + +@@ -458,6 +459,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 { +@@ -465,6 +468,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 { +@@ -581,11 +587,16 @@ struct ath11k_per_peer_tx_stats { u32 succ_bytes; u32 retry_bytes; u32 failed_bytes; @@ -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; +@@ -162,45 +237,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 +@@ -209,10 +285,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 +@@ -220,6 +354,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,87 @@ struct htt_ppdu_stats_info *ath11k_dp_ht return ppdu_info; } @@ -684,7 +684,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 +1694,47 @@ static int ath11k_htt_pull_ppdu_stats(st goto out_unlock_data; } @@ -734,7 +734,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 +748,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 +766,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/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 index 326db09145b342..1365bff54c1bbe 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 +@@ -5376,8 +5376,11 @@ int ath11k_dp_rx_process_mon_status(stru goto next_skb; } diff --git a/package/kernel/mac80211/patches/nss/ath11k/113-ath11k-add-8023-undecap-support.patch b/package/kernel/mac80211/patches/nss/ath11k/113-ath11k-add-8023-undecap-support.patch index 8ef3d9ba7c4d91..0dfdd6a297a7a1 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 +@@ -2297,6 +2297,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 +@@ -2338,7 +2374,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/nss/ath11k/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 index 11205fa770ac7c..9b74a712452d8b 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 { +@@ -312,6 +312,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 { +@@ -370,6 +380,8 @@ struct ath11k_vif { #ifdef CPTCFG_ATH11K_DEBUGFS struct dentry *debugfs_twt; #endif /* CPTCFG_ATH11K_DEBUGFS */ @@ -128,7 +128,7 @@ debugfs_create_file("dfs_simulate_radar", 0200, --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6148,9 +6148,9 @@ static int ath11k_mac_mgmt_tx(struct ath +@@ -6151,9 +6151,9 @@ static int ath11k_mac_mgmt_tx(struct ath */ if (is_prb_rsp && atomic_read(&ar->num_pending_mgmt_tx) > ATH11K_PRB_RSP_DROP_THRESHOLD) { @@ -140,7 +140,7 @@ } if (skb_queue_len_lockless(q) >= ATH11K_TX_MGMT_NUM_PENDING_MAX) { -@@ -6176,9 +6176,11 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6179,9 +6179,11 @@ static void ath11k_mac_op_tx(struct ieee struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_key_conf *key = info->control.hw_key; @@ -152,7 +152,7 @@ int ret; memset(skb_cb, 0, sizeof(*skb_cb)); -@@ -6192,12 +6194,21 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6195,12 +6197,21 @@ static void ath11k_mac_op_tx(struct ieee if (info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { skb_cb->flags |= ATH11K_SKB_HW_80211_ENCAP; } else if (ieee80211_is_mgmt(hdr->frame_control)) { @@ -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; @@ -198,7 +198,7 @@ int peer_id; --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -5823,6 +5823,12 @@ static int wmi_process_mgmt_tx_comp(stru +@@ -5825,6 +5825,12 @@ static int wmi_process_mgmt_tx_comp(stru struct sk_buff *msdu; struct ieee80211_tx_info *info; struct ath11k_skb_cb *skb_cb; @@ -211,7 +211,7 @@ int num_mgmt; spin_lock_bh(&ar->txmgmt_idr_lock); -@@ -5850,6 +5856,31 @@ static int wmi_process_mgmt_tx_comp(stru +@@ -5852,6 +5858,31 @@ static int wmi_process_mgmt_tx_comp(stru info->status.ack_signal = tx_compl_param->ack_rssi; } @@ -243,7 +243,7 @@ ieee80211_tx_status_irqsafe(ar->hw, msdu); num_mgmt = atomic_dec_if_positive(&ar->num_pending_mgmt_tx); -@@ -7519,6 +7550,11 @@ static void ath11k_mgmt_rx_event(struct +@@ -7521,6 +7552,11 @@ static void ath11k_mgmt_rx_event(struct struct ieee80211_hdr *hdr; u16 fc; struct ieee80211_supported_band *sband; @@ -255,7 +255,7 @@ if (ath11k_pull_mgmt_rx_params_tlv(ab, skb, &rx_ev) != 0) { ath11k_warn(ab, "failed to extract mgmt rx event"); -@@ -7584,7 +7620,34 @@ static void ath11k_mgmt_rx_event(struct +@@ -7586,7 +7622,34 @@ static void ath11k_mgmt_rx_event(struct hdr = (struct ieee80211_hdr *)skb->data; fc = le16_to_cpu(hdr->frame_control); diff --git a/package/kernel/mac80211/patches/nss/ath11k/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/nss/ath11k/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 c23618f506dd78..ca21c0b14297b2 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -2240,5 +2240,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,7 +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", -@@ -1834,6 +1852,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}; @@ -107,7 +107,7 @@ 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); -@@ -1908,6 +1929,9 @@ void ath11k_debugfs_unregister(struct at +@@ -1752,6 +1773,9 @@ void ath11k_debugfs_unregister(struct at kfree(dbr_debug); ar->debug.dbr_debug[i] = NULL; } @@ -119,8 +119,8 @@ Signed-off-by: Anilkumar Kolli 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/nss/ath11k/906-ath11k-m3-ssr-dump-collection.patch b/package/kernel/mac80211/patches/nss/ath11k/188-ath11k-m3-ssr-dump-collection.patch similarity index 100% rename from package/kernel/mac80211/patches/nss/ath11k/906-ath11k-m3-ssr-dump-collection.patch rename to package/kernel/mac80211/patches/nss/ath11k/188-ath11k-m3-ssr-dump-collection.patch diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 79f8190d5b990f..32f261cfb8de76 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -2841,7 +2841,7 @@ Signed-off-by: Sriram R enum hal_pn_type pn_type) --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -1164,6 +1164,44 @@ int ath11k_wmi_send_pdev_set_regdomain(s +@@ -1166,6 +1166,44 @@ int ath11k_wmi_send_pdev_set_regdomain(s return ret; } @@ -2991,7 +2991,7 @@ Signed-off-by: Sriram R int ath11k_dp_pdev_reo_setup(struct ath11k_base *ab); --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6367,6 +6367,16 @@ static int ath11k_mac_op_start(struct ie +@@ -6370,6 +6370,16 @@ static int ath11k_mac_op_start(struct ie goto err; } @@ -3010,7 +3010,7 @@ 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 { +@@ -924,6 +924,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/nss/ath11k/199-003-ath11k-add-nss-support.patch b/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch index ddfe25a4395de4..7d10aaf6e9cedb 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 { +@@ -382,6 +383,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 { +@@ -526,6 +530,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 { +@@ -621,6 +628,9 @@ struct ath11k { struct ieee80211_hw *hw; struct ieee80211_ops *ops; struct ath11k_pdev_wmi *wmi; @@ -194,7 +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 { +@@ -838,6 +848,7 @@ struct ath11k_soc_dp_tx_err_stats { * idr unavailable etc. */ atomic_t misc_fail; @@ -202,7 +202,7 @@ Signed-off-by: Sriram R }; struct ath11k_soc_dp_stats { -@@ -868,9 +879,11 @@ struct ath11k_base { +@@ -879,9 +890,11 @@ struct ath11k_base { struct ath11k_htc htc; struct ath11k_dp dp; @@ -365,7 +365,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( +@@ -2027,7 +2030,7 @@ static void ath11k_dp_rx_h_csum_offload( CHECKSUM_NONE : CHECKSUM_UNNECESSARY; } @@ -374,7 +374,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 +@@ -2054,7 +2057,7 @@ static int ath11k_dp_rx_crypto_mic_len(s return 0; } @@ -383,7 +383,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 +@@ -2082,7 +2085,7 @@ static int ath11k_dp_rx_crypto_param_len return 0; } @@ -392,7 +392,7 @@ Signed-off-by: Sriram R enum hal_encrypt_type enctype) { switch (enctype) { -@@ -5239,7 +5242,7 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -5373,7 +5376,7 @@ int ath11k_dp_rx_process_mon_status(stru struct sk_buff *skb; struct sk_buff_head skb_list; struct ath11k_peer *peer; @@ -557,7 +557,7 @@ Signed-off-by: Sriram R exit: mutex_unlock(&ar->conf_mutex); return ret; -@@ -6216,10 +6279,14 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6219,10 +6282,14 @@ static void ath11k_mac_op_tx(struct ieee if (control->sta) arsta = ath11k_sta_to_arsta(control->sta); @@ -573,7 +573,7 @@ Signed-off-by: Sriram R } } -@@ -6241,6 +6308,8 @@ static int ath11k_mac_config_mon_status_ +@@ -6244,6 +6311,8 @@ static int ath11k_mac_config_mon_status_ if (enable) { tlv_filter = ath11k_mac_mon_status_filter_default; @@ -582,7 +582,7 @@ Signed-off-by: Sriram R if (ath11k_debugfs_rx_filter(ar)) tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar); } -@@ -6539,7 +6608,7 @@ static int ath11k_mac_setup_vdev_create_ +@@ -6542,7 +6611,7 @@ static int ath11k_mac_setup_vdev_create_ return 0; } @@ -591,7 +591,7 @@ Signed-off-by: Sriram R struct ieee80211_vif *vif) { struct ath11k *ar = hw->priv; -@@ -6585,6 +6654,8 @@ static void ath11k_mac_op_update_vif_off +@@ -6588,6 +6657,8 @@ static void ath11k_mac_op_update_vif_off arvif->vdev_id, ret); vif->offload_flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED; } @@ -600,7 +600,7 @@ Signed-off-by: Sriram R } static bool ath11k_mac_vif_ap_active_any(struct ath11k_base *ab) -@@ -6715,6 +6786,8 @@ static int ath11k_mac_vdev_delete(struct +@@ -6718,6 +6789,8 @@ static int ath11k_mac_vdev_delete(struct reinit_completion(&ar->vdev_delete_done); @@ -609,7 +609,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 +6928,34 @@ static int ath11k_mac_op_add_interface(s +@@ -6858,7 +6931,34 @@ static int ath11k_mac_op_add_interface(s list_add(&arvif->list, &ar->arvifs); spin_unlock_bh(&ar->data_lock); @@ -645,7 +645,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 +7079,7 @@ err_peer_del: +@@ -6982,6 +7082,7 @@ err_peer_del: } err_vdev_del: @@ -653,7 +653,7 @@ Signed-off-by: Sriram R ath11k_mac_vdev_delete(ar, arvif); spin_lock_bh(&ar->data_lock); list_del(&arvif->list); -@@ -7489,6 +7590,10 @@ ath11k_mac_update_vif_chan(struct ath11k +@@ -7492,6 +7593,10 @@ ath11k_mac_update_vif_chan(struct ath11k arvif->vdev_id, ret); continue; } @@ -664,7 +664,7 @@ Signed-off-by: Sriram R } /* Restart the internal monitor vdev on new channel */ -@@ -8717,6 +8822,8 @@ static void ath11k_mac_op_sta_statistics +@@ -8720,6 +8825,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 +673,7 @@ Signed-off-by: Sriram R } #if IS_ENABLED(CONFIG_IPV6) -@@ -9136,6 +9243,7 @@ static const struct ieee80211_ops ath11k +@@ -9139,6 +9246,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 +681,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 +9629,8 @@ static int __ath11k_mac_register(struct +@@ -9524,7 +9632,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 +691,7 @@ Signed-off-by: Sriram R } ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; -@@ -9634,6 +9743,9 @@ static int __ath11k_mac_register(struct +@@ -9637,6 +9746,9 @@ static int __ath11k_mac_register(struct ab->hw_params.bios_sar_capa) ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa; @@ -770,7 +770,7 @@ Signed-off-by: Sriram R 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 +801,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,7 +811,7 @@ Signed-off-by: Sriram R } ar->debug.rx_filter = tlv_filter.rx_filter; -@@ -1977,6 +1977,75 @@ static const struct file_operations ath1 +@@ -2001,6 +2001,75 @@ static const struct file_operations ath1 .open = simple_open }; diff --git a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Add-support-for-dynamic-vlan.patch b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Add-support-for-dynamic-vlan.patch index 2fd5374354ca61..d90c39c77c9a4f 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 { +@@ -117,6 +117,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 -@@ -9762,6 +9762,9 @@ static int __ath11k_mac_register(struct +@@ -9763,6 +9763,9 @@ static int __ath11k_mac_register(struct */ ar->hw->wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MONITOR); diff --git a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch index 0e7e5899d4ba03..d43143c76e8017 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch @@ -149,7 +149,7 @@ Signed-off-by: Ramya Gnanasekar ATH11K_TRACING= --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -853,6 +853,11 @@ struct ath11k_msi_config { +@@ -875,6 +875,11 @@ struct ath11k_msi_config { u16 hw_rev; }; @@ -161,7 +161,7 @@ Signed-off-by: Ramya Gnanasekar /* Master structure to hold the hw data which may be used in core module */ struct ath11k_base { enum ath11k_hw_rev hw_rev; -@@ -1006,6 +1011,9 @@ struct ath11k_base { +@@ -1028,6 +1033,9 @@ struct ath11k_base { } testmode; #endif diff --git a/package/kernel/mac80211/patches/nss/ath11k/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/nss/ath11k/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 cb04a47e0a0409..0d2de0ae895d6f 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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); +@@ -306,6 +306,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 +474,6 @@ static void ath11k_nss_vdev_event_receiv +@@ -416,13 +432,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 +597,239 @@ static int ath11k_nss_undecap_nwifi(stru +@@ -546,11 +555,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 +869,16 @@ ath11k_nss_vdev_data_receive(struct net_ +@@ -590,28 +827,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 +1587,7 @@ void ath11k_nss_update_sta_rxrate(struct +@@ -1320,7 +1545,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 +1601,10 @@ int ath11k_nss_peer_delete(struct ath11k +@@ -1334,9 +1559,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 +1677,9 @@ free_peer: +@@ -1409,8 +1635,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 +1736,23 @@ int ath11k_nss_peer_create(struct ath11k +@@ -1467,17 +1694,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 +1771,199 @@ msg_free: +@@ -1496,6 +1729,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 +2357,7 @@ static int ath11k_nss_init(struct ath11k +@@ -1886,7 +2312,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 +2411,8 @@ static int ath11k_nss_stats_cfg(struct a +@@ -1940,7 +2366,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/nss/ath11k/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 94% rename from package/kernel/mac80211/patches/nss/ath11k/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 e39057c781c3a6..6bf3cb5c797e60 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -624,6 +624,7 @@ struct ath11k { +@@ -631,6 +631,7 @@ struct ath11k { struct ath11k_pdev_wmi *wmi; #ifdef CPTCFG_ATH11K_NSS_SUPPORT struct ath11k_nss nss; @@ -34,9 +34,9 @@ Signed-off-by: Sathishkumar Muruganandam #endif struct ath11k_pdev_dp dp; u8 mac_addr[ETH_ALEN]; -@@ -1032,6 +1033,8 @@ struct ath11k_base { - u32 rx_hash; - bool stats_disable; +@@ -1036,6 +1037,8 @@ struct ath11k_base { + atomic_t num_max_allowed; + struct ath11k_num_vdevs_peers *num_vdevs_peers; + u32 max_ast_index; + u32 num_ast_entries; @@ -45,7 +45,7 @@ Signed-off-by: Sathishkumar Muruganandam }; --- 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 +66,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 +@@ -1849,6 +1849,8 @@ void ath11k_dp_htt_htc_t2h_msg_handler(s u16 peer_mac_h16; u16 ast_hash; u16 hw_peer_id; @@ -75,7 +75,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 +@@ -1884,15 +1886,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 +110,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 -@@ -477,7 +477,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 @@ -612,9 +612,9 @@ Signed-off-by: Sathishkumar Muruganandam struct ath11k_sta *arsta; int ret, fbret; -@@ -451,6 +866,12 @@ int ath11k_peer_create(struct ath11k *ar - peer->sec_type = HAL_ENCRYPT_TYPE_OPEN; +@@ -452,6 +867,12 @@ int ath11k_peer_create(struct ath11k *ar peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; + peer->vif = arvif->vif; +#ifdef CPTCFG_ATH11K_NSS_SUPPORT + if (vif->type == NL80211_IFTYPE_STATION && ar->ab->nss.enabled) @@ -627,9 +627,9 @@ Signed-off-by: Sathishkumar Muruganandam arsta = ath11k_sta_to_arsta(sta); --- 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 */ @@ -675,7 +675,7 @@ Signed-off-by: Sathishkumar Muruganandam struct ath11k_peer { struct list_head list; struct ieee80211_sta *sta; -@@ -17,6 +58,10 @@ struct ath11k_peer { +@@ -29,6 +70,10 @@ struct ath11k_peer { u8 pdev_idx; u16 hw_peer_id; struct ath11k_nss_peer nss; @@ -686,7 +686,7 @@ Signed-off-by: Sathishkumar Muruganandam /* protected by ab->data_lock */ struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; -@@ -40,8 +85,13 @@ struct ath11k_peer { +@@ -54,8 +99,13 @@ struct ath11k_peer { }; void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id); @@ -700,7 +700,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, -@@ -58,4 +108,71 @@ struct ath11k_peer *ath11k_peer_find_by_ +@@ -72,4 +122,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); @@ -774,15 +774,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" }, +@@ -154,6 +154,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; } @@ -834,7 +835,7 @@ Signed-off-by: Sathishkumar Muruganandam int ath11k_wmi_send_pdev_set_regdomain(struct ath11k *ar, struct pdev_set_regdomain_params *param) { -@@ -6380,6 +6426,36 @@ static int ath11k_pull_peer_assoc_conf_e +@@ -6362,6 +6409,36 @@ static int ath11k_pull_peer_assoc_conf_e return 0; } @@ -871,7 +872,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) { -@@ -7295,6 +7371,7 @@ static int ath11k_wmi_tlv_rdy_parse(stru +@@ -7277,6 +7354,7 @@ static int ath11k_wmi_tlv_rdy_parse(stru ether_addr_copy(ab->mac_addr, fixed_param.ready_event_min.mac_addr.addr); @@ -879,7 +880,7 @@ Signed-off-by: Sathishkumar Muruganandam ab->pktlog_defs_checksum = fixed_param.pktlog_defs_checksum; break; case WMI_TAG_ARRAY_FIXED_STRUCT: -@@ -8734,6 +8811,22 @@ static void ath11k_wmi_gtk_offload_statu +@@ -8717,6 +8795,22 @@ static void ath11k_wmi_gtk_offload_statu kfree(tb); } @@ -902,9 +903,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; -@@ -8864,6 +8957,9 @@ static void ath11k_wmi_tlv_op_rx(struct - case WMI_QOS_NULL_FRAME_TX_COMPLETION_EVENTID: - ath11k_qos_null_compl_event(ab, skb); +@@ -8844,6 +8938,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); @@ -914,7 +915,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 { +@@ -3009,6 +3009,21 @@ struct wmi_peer_delete_cmd { struct wmi_mac_addr peer_macaddr; } __packed; @@ -936,7 +937,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 { +@@ -4611,6 +4626,21 @@ struct wmi_probe_resp_tx_status_event { u32 tx_status; } __packed; @@ -958,7 +959,7 @@ Signed-off-by: Sathishkumar Muruganandam /* * PDEV statistics */ -@@ -6431,6 +6461,9 @@ int ath11k_wmi_set_sta_ps_param(struct a +@@ -6400,6 +6430,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/nss/ath11k/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 index 5e77b6f44bd272..f8ebc65fbaa3cc 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -22,7 +22,7 @@ Signed-off-by: Sowmiya Sree Elavalagan --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6129,6 +6129,16 @@ static int ath11k_mac_mgmt_tx_wmi(struct +@@ -6132,6 +6132,16 @@ static int ath11k_mac_mgmt_tx_wmi(struct ATH11K_SKB_CB(skb)->paddr = paddr; @@ -39,7 +39,7 @@ Signed-off-by: Sowmiya Sree Elavalagan ret = ath11k_wmi_mgmt_send(ar, arvif->vdev_id, buf_id, skb); if (ret) { ath11k_warn(ar->ab, "failed to send mgmt frame: %d\n", ret); -@@ -6196,8 +6206,8 @@ static void ath11k_mgmt_over_wmi_tx_work +@@ -6199,8 +6209,8 @@ static void ath11k_mgmt_over_wmi_tx_work } } @@ -50,7 +50,7 @@ Signed-off-by: Sowmiya Sree Elavalagan { struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue; -@@ -6259,7 +6269,7 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6262,7 +6272,7 @@ static void ath11k_mac_op_tx(struct ieee } else if (ieee80211_is_mgmt(hdr->frame_control)) { frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, hdr->frame_control); is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control); @@ -59,7 +59,7 @@ Signed-off-by: Sowmiya Sree Elavalagan if (ret) { if (ret != -EBUSY) ath11k_warn(ar->ab, "failed to queue management frame %d\n", -@@ -6274,6 +6284,20 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6277,6 +6287,20 @@ static void ath11k_mac_op_tx(struct ieee spin_unlock_bh(&ar->data_lock); } return; @@ -90,7 +90,7 @@ Signed-off-by: Sowmiya Sree Elavalagan }; struct wmi_tlv_svc_ready_parse { -@@ -91,69 +92,69 @@ struct wmi_tlv_mgmt_rx_parse { +@@ -91,71 +92,71 @@ struct wmi_tlv_mgmt_rx_parse { static const struct wmi_tlv_policy wmi_tlv_policies[] = { [WMI_TAG_ARRAY_BYTE] @@ -189,10 +189,13 @@ Signed-off-by: Sowmiya Sree Elavalagan [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" }, + [WMI_TAG_WDS_ADDR_EVENT] = { +- .min_len = sizeof(struct wmi_wds_addr_event) }, ++ .min_len = sizeof(struct wmi_wds_addr_event), .policy = "wmi_wds_addr_event" }, }; #define PRIMAP(_hw_mode_) \ -@@ -203,8 +204,8 @@ ath11k_wmi_tlv_iter(struct ath11k_base * +@@ -205,8 +206,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) { @@ -203,7 +206,7 @@ Signed-off-by: Sowmiya Sree Elavalagan wmi_tlv_policies[tlv_tag].min_len); return -EINVAL; } -@@ -697,6 +698,55 @@ int ath11k_wmi_mgmt_send(struct ath11k * +@@ -701,6 +702,55 @@ int ath11k_wmi_mgmt_send(struct ath11k * return ret; } @@ -259,7 +262,7 @@ Signed-off-by: Sowmiya Sree Elavalagan int ath11k_wmi_vdev_create(struct ath11k *ar, u8 *macaddr, struct vdev_create_params *param) { -@@ -5855,8 +5905,8 @@ static int ath11k_pull_mgmt_rx_params_tl +@@ -5904,8 +5954,8 @@ static int ath11k_pull_mgmt_rx_params_tl return 0; } @@ -270,7 +273,7 @@ Signed-off-by: Sowmiya Sree Elavalagan { struct sk_buff *msdu; struct ieee80211_tx_info *info; -@@ -5894,6 +5944,11 @@ static int wmi_process_mgmt_tx_comp(stru +@@ -5943,6 +5993,11 @@ static int wmi_process_mgmt_tx_comp(stru info->status.ack_signal = tx_compl_param->ack_rssi; } @@ -282,7 +285,7 @@ Signed-off-by: Sowmiya Sree Elavalagan hdr = (struct ieee80211_hdr *)msdu->data; frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, hdr->frame_control); -@@ -5912,10 +5967,13 @@ static int wmi_process_mgmt_tx_comp(stru +@@ -5961,10 +6016,13 @@ static int wmi_process_mgmt_tx_comp(stru arvif = ath11k_vif_to_arvif(vif); mgmt_stats = &arvif->mgmt_stats; @@ -300,7 +303,7 @@ Signed-off-by: Sowmiya Sree Elavalagan spin_unlock_bh(&ar->data_lock); skip_mgmt_stats: -@@ -5937,12 +5995,13 @@ skip_mgmt_stats: +@@ -5986,12 +6044,13 @@ skip_mgmt_stats: return 0; } @@ -318,7 +321,7 @@ Signed-off-by: Sowmiya Sree Elavalagan int ret; tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); -@@ -5952,7 +6003,7 @@ static int ath11k_pull_mgmt_tx_compl_par +@@ -6001,7 +6060,7 @@ static int ath11k_pull_mgmt_tx_compl_par return ret; } @@ -327,7 +330,7 @@ Signed-off-by: Sowmiya Sree Elavalagan if (!ev) { ath11k_warn(ab, "failed to fetch mgmt tx compl ev"); kfree(tb); -@@ -7729,10 +7780,11 @@ exit: +@@ -7809,10 +7868,11 @@ exit: static void ath11k_mgmt_tx_compl_event(struct ath11k_base *ab, struct sk_buff *skb) { @@ -341,7 +344,7 @@ Signed-off-by: Sowmiya Sree Elavalagan ath11k_warn(ab, "failed to extract mgmt tx compl event"); return; } -@@ -7745,7 +7797,7 @@ static void ath11k_mgmt_tx_compl_event(s +@@ -7825,7 +7885,7 @@ static void ath11k_mgmt_tx_compl_event(s goto exit; } @@ -350,7 +353,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", -@@ -7756,6 +7808,36 @@ exit: +@@ -7836,6 +7896,36 @@ exit: rcu_read_unlock(); } @@ -387,9 +390,9 @@ 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) -@@ -8842,6 +8924,9 @@ static void ath11k_wmi_tlv_op_rx(struct - case WMI_GTK_OFFLOAD_STATUS_EVENTID: - ath11k_wmi_gtk_offload_status_event(ab, skb); +@@ -8941,6 +9031,9 @@ 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); @@ -444,7 +447,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 { +@@ -3829,6 +3845,7 @@ struct wmi_scan_prob_req_oui_cmd { } __packed; #define WMI_MGMT_SEND_DOWNLD_LEN 64 @@ -452,7 +455,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 { +@@ -3839,9 +3856,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) @@ -465,7 +468,7 @@ Signed-off-by: Sowmiya Sree Elavalagan u32 tlv_header; u32 tx_params_dword0; u32 tx_params_dword1; -@@ -4917,7 +4935,7 @@ struct wmi_rssi_ctl_ext { +@@ -4947,7 +4965,7 @@ struct wmi_rssi_ctl_ext { u32 rssi_ctl_ext[MAX_ANTENNA_EIGHT - ATH_MAX_ANTENNA]; }; @@ -474,7 +477,7 @@ Signed-off-by: Sowmiya Sree Elavalagan u32 desc_id; u32 status; u32 pdev_id; -@@ -5748,6 +5766,17 @@ struct wmi_debug_log_config_cmd_fixed_pa +@@ -5778,6 +5796,17 @@ struct wmi_debug_log_config_cmd_fixed_pa u32 value; } __packed; @@ -492,7 +495,7 @@ Signed-off-by: Sowmiya Sree Elavalagan #define WMI_MAX_MEM_REQS 32 #define MAX_RADIOS 3 -@@ -6358,6 +6387,8 @@ int ath11k_wmi_cmd_send(struct ath11k_pd +@@ -6388,6 +6417,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/nss/ath11k/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch b/package/kernel/mac80211/patches/nss/ath11k/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch index c403bca30c5c74..4ff42b80105d61 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/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 +@@ -1129,6 +1130,7 @@ static ssize_t ath11k_write_pktlog_filte } /* Clear rx filter set for monitor mode and rx status */ @@ -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 { +@@ -648,7 +649,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 { +@@ -662,6 +663,14 @@ enum htt_stats_internal_ppdu_frametype { * |-------------------------------------------------------------------| * | tlv_filter_in_flags | * |-------------------------------------------------------------------| @@ -64,7 +64,7 @@ Signed-off-by: Ramya Gnanasekar * Where: * PS = pkt_swap * SS = status_swap -@@ -636,6 +645,9 @@ enum htt_ppdu_stats_tag_type { +@@ -675,6 +684,9 @@ 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 @@ -74,7 +74,7 @@ Signed-off-by: Ramya Gnanasekar * b'26: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 { +@@ -704,6 +716,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 +117,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 { +@@ -711,8 +759,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 +134,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 { +@@ -1016,6 +1072,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 +149,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 { +@@ -1024,6 +1088,10 @@ struct htt_rx_ring_selection_cfg_cmd { u32 pkt_type_en_flags2; u32 pkt_type_en_flags3; u32 rx_filter_tlv; @@ -160,7 +160,7 @@ Signed-off-by: Ramya Gnanasekar } __packed; struct htt_rx_ring_tlv_filter { -@@ -993,6 +1061,14 @@ struct htt_rx_ring_tlv_filter { +@@ -1032,6 +1100,14 @@ struct htt_rx_ring_tlv_filter { u32 pkt_filter_flags1; /* MGMT */ u32 pkt_filter_flags2; /* CTRL */ u32 pkt_filter_flags3; /* DATA */ @@ -226,7 +226,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 +@@ -2126,6 +2161,49 @@ int ath11k_dp_rx_crypto_icv_len(struct a return 0; } @@ -276,7 +276,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 +@@ -2139,7 +2217,8 @@ static void ath11k_dp_rx_h_undecap_nwifi u8 da[ETH_ALEN]; u8 sa[ETH_ALEN]; u16 qos_ctl = 0; @@ -286,7 +286,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 +@@ -2148,7 +2227,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 +295,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 +@@ -2178,16 +2257,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 +324,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 +@@ -2303,6 +2389,20 @@ static void ath11k_dp_rx_h_undecap_eth(s u8 da[ETH_ALEN]; u8 sa[ETH_ALEN]; void *rfc1042; @@ -345,7 +345,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 +@@ -2331,6 +2431,7 @@ static void ath11k_dp_rx_h_undecap_eth(s memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); @@ -353,7 +353,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( +@@ -2349,6 +2450,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 +361,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( +@@ -2362,6 +2464,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 +373,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 +@@ -2758,6 +2865,20 @@ static int ath11k_dp_rx_process_msdu(str goto free_out; } @@ -394,7 +394,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 +@@ -2770,8 +2891,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 +406,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 +@@ -3433,6 +3555,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 +414,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 +@@ -3713,8 +3836,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 +424,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 +@@ -3944,8 +4067,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 +436,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 +@@ -4568,6 +4692,47 @@ void ath11k_dp_rx_pdev_free(struct ath11 ath11k_dp_rxdma_pdev_buf_free(ar); } @@ -484,7 +484,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: +@@ -4661,6 +4826,12 @@ config_refill_ring: } } @@ -825,7 +825,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 -@@ -6338,6 +6338,7 @@ static int ath11k_mac_config_mon_status_ +@@ -6341,6 +6341,7 @@ static int ath11k_mac_config_mon_status_ tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar); } @@ -871,7 +871,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 @@ -891,7 +891,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 +@@ -2226,7 +2226,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/nss/ath11k/234-001-ath11k-account-tx-rx-packets-flow.patch b/package/kernel/mac80211/patches/nss/ath11k/234-001-ath11k-account-tx-rx-packets-flow.patch index d7d2b3bab12076..f5c9b1943fb85c 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/234-001-ath11k-account-tx-rx-packets-flow.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/234-001-ath11k-account-tx-rx-packets-flow.patch @@ -79,7 +79,7 @@ Signed-off-by: Maharaja Kennadyrajan --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -495,6 +495,17 @@ struct ath11k_per_ppdu_tx_stats { +@@ -501,6 +501,17 @@ struct ath11k_per_ppdu_tx_stats { DECLARE_EWMA(avg_rssi, 10, 8) @@ -97,7 +97,7 @@ Signed-off-by: Maharaja Kennadyrajan struct ath11k_sta { struct ath11k_vif *arvif; -@@ -528,6 +539,8 @@ struct ath11k_sta { +@@ -534,6 +545,8 @@ struct ath11k_sta { #ifdef CPTCFG_ATH11K_NSS_SUPPORT struct ath11k_nss_sta_stats *nss_stats; #endif @@ -119,9 +119,9 @@ Signed-off-by: Maharaja Kennadyrajan --- 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; +@@ -221,9 +221,6 @@ static ssize_t ath11k_dbg_sta_dump_tx_st + char *buf, mu_group_id[MAX_MU_GROUP_LENGTH] = {0}; + u32 index; - if (!arsta->tx_stats) - return -ENOENT; @@ -129,7 +129,7 @@ Signed-off-by: Maharaja Kennadyrajan buf = kzalloc(size, GFP_KERNEL); if (!buf) return -ENOMEM; -@@ -156,6 +153,12 @@ static ssize_t ath11k_dbg_sta_dump_tx_st +@@ -231,6 +228,12 @@ static ssize_t ath11k_dbg_sta_dump_tx_st mutex_lock(&ar->conf_mutex); spin_lock_bh(&ar->data_lock); @@ -142,7 +142,7 @@ Signed-off-by: Maharaja Kennadyrajan 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 +@@ -364,6 +367,11 @@ static ssize_t ath11k_dbg_sta_dump_tx_st mutex_unlock(&ar->conf_mutex); return retval; @@ -154,7 +154,7 @@ Signed-off-by: Maharaja Kennadyrajan } static const struct file_operations fops_tx_stats = { -@@ -847,17 +855,211 @@ static const struct file_operations fops +@@ -982,17 +990,211 @@ static const struct file_operations fops .llseek = default_llseek, }; @@ -372,7 +372,7 @@ Signed-off-by: Maharaja Kennadyrajan &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 +@@ -2566,6 +2566,7 @@ static void ath11k_dp_rx_h_mpdu(struct a struct rx_attention *rx_attention; u32 err_bitmap; @@ -380,7 +380,7 @@ Signed-off-by: Maharaja Kennadyrajan /* 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 +@@ -2759,6 +2760,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; @@ -388,7 +388,7 @@ Signed-off-by: Maharaja Kennadyrajan 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 +@@ -2824,6 +2826,18 @@ static void ath11k_dp_rx_deliver_msdu(st rx_status->flag |= RX_FLAG_8023; ieee80211_rx_napi(ar->hw, pubsta, msdu, napi); @@ -407,7 +407,7 @@ Signed-off-by: Maharaja Kennadyrajan } static int ath11k_dp_rx_process_msdu(struct ath11k *ar, -@@ -2820,6 +2834,8 @@ int ath11k_dp_process_rx(struct ath11k_b +@@ -2970,6 +2984,8 @@ int ath11k_dp_process_rx(struct ath11k_b int total_msdu_reaped = 0; struct hal_srng *srng; struct sk_buff *msdu; @@ -416,7 +416,7 @@ Signed-off-by: Maharaja Kennadyrajan bool done = false; int buf_id, mac_id; struct ath11k *ar; -@@ -2893,6 +2909,19 @@ try_again: +@@ -3043,6 +3059,19 @@ try_again: rxcb->tid = FIELD_GET(HAL_REO_DEST_RING_INFO0_RX_QUEUE_NUM, desc->info0); @@ -436,7 +436,7 @@ Signed-off-by: Maharaja Kennadyrajan 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 +@@ -4234,7 +4263,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); @@ -447,7 +447,7 @@ Signed-off-by: Maharaja Kennadyrajan 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 +@@ -4286,6 +4318,18 @@ static int ath11k_dp_rx_h_null_q_desc(st * rx with mac80211. Need not worry about cleaning up amsdu_list. */ @@ -468,7 +468,7 @@ Signed-off-by: Maharaja Kennadyrajan --- 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 +@@ -6255,6 +6255,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; @@ -476,7 +476,7 @@ Signed-off-by: Maharaja Kennadyrajan bool is_prb_rsp; u16 frm_type = 0; int ret; -@@ -6312,6 +6313,15 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6315,6 +6316,15 @@ static void ath11k_mac_op_tx(struct ieee ieee80211_free_txskb(ar->hw, skb); return; } diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 94% rename from package/kernel/mac80211/patches/nss/ath11k/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 9fe0a189558564..fae9eb86e87c5f 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -364,6 +364,10 @@ void ath11k_nss_wifili_event_receive(str +@@ -322,6 +322,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; -@@ -597,8 +601,9 @@ static int ath11k_nss_undecap_nwifi(stru +@@ -555,8 +559,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; -@@ -620,19 +625,22 @@ static void ath11k_nss_wds_type_rx(struc +@@ -578,19 +583,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); -@@ -676,7 +684,8 @@ static void ath11k_nss_mec_handler(struc +@@ -634,7 +642,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; -@@ -697,8 +706,8 @@ static void ath11k_nss_vdev_spl_receive_ +@@ -655,8 +664,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)); -@@ -765,6 +774,7 @@ ath11k_nss_vdev_special_data_receive(str +@@ -723,6 +732,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; -@@ -820,10 +830,11 @@ ath11k_nss_vdev_special_data_receive(str +@@ -778,10 +788,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 -@@ -886,6 +897,68 @@ ath11k_nss_vdev_data_receive(struct net_ +@@ -844,6 +855,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; -@@ -908,10 +981,16 @@ int ath11k_nss_tx(struct ath11k_vif *arv +@@ -866,10 +939,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), -@@ -1252,6 +1331,7 @@ int ath11k_nss_vdev_up(struct ath11k_vif +@@ -1210,6 +1289,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; -@@ -1283,6 +1363,12 @@ int ath11k_nss_vdev_up(struct ath11k_vif +@@ -1241,6 +1321,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; -@@ -1292,6 +1378,7 @@ int ath11k_nss_vdev_down(struct ath11k_v +@@ -1250,6 +1336,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; -@@ -1319,11 +1406,362 @@ int ath11k_nss_vdev_down(struct ath11k_v +@@ -1277,11 +1364,362 @@ int ath11k_nss_vdev_down(struct ath11k_v } ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss vdev down tx msg success\n"); @@ -593,7 +593,7 @@ Signed-off-by: Sathishkumar Muruganandam /*----------------------------Peer Setup/Config -----------------------------*/ int ath11k_nss_set_peer_sec_type(struct ath11k *ar, -@@ -1417,22 +1855,22 @@ free: +@@ -1375,22 +1813,22 @@ free: return status; } @@ -623,7 +623,7 @@ Signed-off-by: Sathishkumar Muruganandam sta->addr); goto exit; } -@@ -1504,13 +1942,13 @@ void ath11k_nss_update_sta_rxrate(struct +@@ -1462,13 +1900,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) -@@ -1814,8 +2252,8 @@ int ath11k_nss_add_wds_peer(struct ath11 +@@ -1772,8 +2210,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); -@@ -1860,8 +2298,8 @@ int ath11k_nss_update_wds_peer(struct at +@@ -1818,8 +2256,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/nss/ath11k/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 92% rename from package/kernel/mac80211/patches/nss/ath11k/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 f5af428e338e5e..602899eea5228c 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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,7 +33,7 @@ Signed-off-by: Sathishkumar Muruganandam --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -377,6 +377,7 @@ struct ath11k_vif { +@@ -387,6 +387,7 @@ struct ath11k_vif { #ifdef CPTCFG_ATH11K_NSS_SUPPORT struct arvif_nss nss; #endif @@ -43,7 +43,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 -@@ -4737,6 +4737,11 @@ static void ath11k_sta_rc_update_wk(stru +@@ -4739,6 +4739,11 @@ static void ath11k_sta_rc_update_wk(stru arvif = arsta->arvif; ar = arvif->ar; @@ -55,7 +55,7 @@ Signed-off-by: Sathishkumar Muruganandam if (WARN_ON(ath11k_mac_vif_chan(arvif->vif, &def))) return; -@@ -4908,17 +4913,28 @@ err_rc_bw_changed: +@@ -4910,17 +4915,28 @@ err_rc_bw_changed: static void ath11k_sta_set_4addr_wk(struct work_struct *wk) { struct ath11k *ar; @@ -86,7 +86,7 @@ Signed-off-by: Sathishkumar Muruganandam "setting USE_4ADDR for peer %pM\n", sta->addr); ret = ath11k_wmi_set_peer_param(ar, sta->addr, -@@ -4926,8 +4942,93 @@ static void ath11k_sta_set_4addr_wk(stru +@@ -4928,8 +4944,93 @@ static void ath11k_sta_set_4addr_wk(stru WMI_PEER_USE_4ADDR, 1); if (ret) @@ -181,7 +181,7 @@ Signed-off-by: Sathishkumar Muruganandam } static int ath11k_mac_inc_num_stations(struct ath11k_vif *arvif, -@@ -5276,9 +5377,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; @@ -214,7 +214,7 @@ Signed-off-by: Sathishkumar Muruganandam ieee80211_queue_work(ar->hw, &arsta->set_4addr_wk); arsta->use_4addr_set = true; } -@@ -6658,6 +6782,9 @@ static int ath11k_mac_op_update_vif_offl +@@ -6655,6 +6779,9 @@ static int ath11k_mac_op_update_vif_offl u32 param_id, param_value; int ret; @@ -224,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 && -@@ -6878,7 +7005,8 @@ static int ath11k_mac_op_add_interface(s +@@ -6875,7 +7002,8 @@ static int ath11k_mac_op_add_interface(s goto err; } @@ -234,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; -@@ -6898,6 +7026,28 @@ static int ath11k_mac_op_add_interface(s +@@ -6895,6 +7023,28 @@ static int ath11k_mac_op_add_interface(s arvif->vif = vif; INIT_LIST_HEAD(&arvif->list); @@ -263,7 +263,7 @@ Signed-off-by: Sathishkumar Muruganandam INIT_DELAYED_WORK(&arvif->connection_loss_work, ath11k_mac_vif_sta_connection_loss_work); -@@ -6927,6 +7077,7 @@ static int ath11k_mac_op_add_interface(s +@@ -6924,6 +7074,7 @@ static int ath11k_mac_op_add_interface(s fallthrough; case NL80211_IFTYPE_AP: arvif->vdev_type = WMI_VDEV_TYPE_AP; @@ -271,7 +271,7 @@ Signed-off-by: Sathishkumar Muruganandam break; case NL80211_IFTYPE_MONITOR: arvif->vdev_type = WMI_VDEV_TYPE_MONITOR; -@@ -7149,13 +7300,30 @@ static void ath11k_mac_op_remove_interfa +@@ -7146,13 +7297,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; @@ -304,7 +304,7 @@ Signed-off-by: Sathishkumar Muruganandam ath11k_dbg(ab, ATH11K_DBG_MAC, "remove interface (vdev %d)\n", arvif->vdev_id); -@@ -7172,6 +7340,14 @@ static void ath11k_mac_op_remove_interfa +@@ -7169,6 +7337,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); @@ -319,7 +319,7 @@ Signed-off-by: Sathishkumar Muruganandam } ret = ath11k_mac_vdev_delete(ar, arvif); -@@ -7215,8 +7391,7 @@ err_vdev_del: +@@ -7212,8 +7388,7 @@ err_vdev_del: ath11k_debugfs_remove_interface(arvif); @@ -329,7 +329,7 @@ Signed-off-by: Sathishkumar Muruganandam mutex_unlock(&ar->conf_mutex); } -@@ -7276,16 +7451,17 @@ static int ath11k_mac_op_ampdu_action(st +@@ -7273,16 +7448,17 @@ static int ath11k_mac_op_ampdu_action(st struct ieee80211_ampdu_params *params) { struct ath11k *ar = hw->priv; @@ -349,7 +349,7 @@ Signed-off-by: Sathishkumar Muruganandam break; case IEEE80211_AMPDU_TX_START: case IEEE80211_AMPDU_TX_STOP_CONT: -@@ -8808,6 +8984,7 @@ static void ath11k_mac_op_sta_statistics +@@ -8805,6 +8981,7 @@ static void ath11k_mac_op_sta_statistics { struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); struct ath11k *ar = arsta->arvif->ar; @@ -357,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); -@@ -8864,7 +9041,8 @@ static void ath11k_mac_op_sta_statistics +@@ -8861,7 +9038,8 @@ static void ath11k_mac_op_sta_statistics ATH11K_DEFAULT_NOISE_FLOOR; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); @@ -380,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: +@@ -1156,12 +1156,13 @@ err_mem_free: return ret; } @@ -396,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 +@@ -1173,13 +1174,13 @@ int ath11k_dp_rx_ampdu_start(struct ath1 return ret; } @@ -486,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, @@ -494,7 +494,7 @@ Signed-off-by: Sathishkumar Muruganandam ATH11K_WDS_WMI_MAX }; -@@ -112,6 +113,8 @@ int ath11k_peer_rhash_delete(struct ath1 +@@ -126,6 +127,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); @@ -503,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, -@@ -131,6 +134,12 @@ static inline struct ath11k_ast_entry *a +@@ -145,6 +148,12 @@ static inline struct ath11k_ast_entry *a { return NULL; } @@ -518,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 -@@ -162,7 +162,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; @@ -530,7 +530,7 @@ Signed-off-by: Sathishkumar Muruganandam rx_packets = pstats->rx.rx_recvd; peer->nss.nss_stats->rx_packets += rx_packets; -@@ -172,7 +175,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; @@ -542,7 +542,7 @@ Signed-off-by: Sathishkumar Muruganandam spin_unlock_bh(&ab->base_lock); rcu_read_unlock(); -@@ -1038,6 +1044,9 @@ int ath11k_nss_vdev_set_cmd(struct ath11 +@@ -996,6 +1002,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; @@ -554,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/nss/ath11k/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/nss/ath11k/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 93adefacb0de44..bad782747c57a1 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -1568,14 +1568,11 @@ static int ath11k_nss_ext_vdev_register( +@@ -1526,14 +1526,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, -@@ -1603,7 +1600,8 @@ static void ath11k_nss_ext_vdev_free(str +@@ -1561,7 +1558,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); -@@ -1612,14 +1610,19 @@ static void ath11k_nss_ext_vdev_free(str +@@ -1570,14 +1568,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"); -@@ -1628,8 +1631,8 @@ static int ath11k_nss_ext_vdev_alloc(str +@@ -1586,8 +1589,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; } -@@ -1658,7 +1661,7 @@ int ath11k_nss_ext_vdev_create(struct at +@@ -1616,7 +1619,7 @@ int ath11k_nss_ext_vdev_create(struct at return -EINVAL; } @@ -82,7 +82,7 @@ Signed-off-by: Sathishkumar Muruganandam if (ret) return ret; -@@ -1771,6 +1774,86 @@ free: +@@ -1729,6 +1732,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/nss/ath11k/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 90% rename from package/kernel/mac80211/patches/nss/ath11k/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 850bf770d3bd1e..3687af833b5082 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -99,6 +99,11 @@ enum ath11k_crypt_mode { +@@ -97,6 +97,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 : -@@ -327,6 +332,20 @@ struct ath11k_mgmt_frame_stats { +@@ -324,6 +329,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; -@@ -389,6 +408,11 @@ struct ath11k_vif { - struct ath11k_mgmt_frame_stats mgmt_stats; +@@ -388,6 +407,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); } @@ -354,7 +354,7 @@ Signed-off-by: Sathishkumar Muruganandam switch (key->cipher) { case WLAN_CIPHER_SUITE_TKIP: -@@ -5219,6 +5393,33 @@ static u32 ath11k_mac_ieee80211_sta_bw_t +@@ -5186,6 +5360,33 @@ static u32 ath11k_mac_ieee80211_sta_bw_t return bw; } @@ -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, -@@ -5342,6 +5543,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) { -@@ -7080,7 +7309,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7027,7 +7256,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; -@@ -7093,6 +7322,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7040,6 +7269,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; } -@@ -7117,6 +7347,20 @@ static int ath11k_mac_op_add_interface(s +@@ -7064,6 +7294,20 @@ static int ath11k_mac_op_add_interface(s arvif->vdev_id = bit; arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE; @@ -461,16 +461,16 @@ Signed-off-by: Sathishkumar Muruganandam switch (vif->type) { case NL80211_IFTYPE_UNSPECIFIED: case NL80211_IFTYPE_STATION: -@@ -7157,7 +7401,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7104,7 +7348,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); - goto err; + goto err_keyid; } + ar->num_created_vdevs++; - ath11k_dbg(ab, ATH11K_DBG_MAC, "vdev %pM created, vdev_id %d\n", -@@ -7319,7 +7563,7 @@ err_peer_del: +@@ -7263,7 +7507,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 } } -@@ -7330,6 +7574,8 @@ err_vdev_del: +@@ -7274,6 +7518,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); -@@ -7427,6 +7673,7 @@ err_vdev_del: +@@ -7371,6 +7617,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, -@@ -10154,8 +10401,11 @@ static int __ath11k_mac_register(struct +@@ -9959,8 +10206,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 -@@ -2033,6 +2033,7 @@ int ath11k_wmi_vdev_install_key(struct a +@@ -1939,6 +1939,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, -@@ -4307,6 +4308,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, -@@ -4529,6 +4531,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 -@@ -3707,6 +3707,7 @@ struct wmi_vdev_install_key_arg { +@@ -3701,6 +3701,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; -@@ -5852,6 +5853,7 @@ struct target_resource_config { +@@ -5774,6 +5775,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-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 index a102c8c5cc6c56..db2bbfa0d2845d 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -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/nss/ath11k/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 index 965c44706ac55c..735ffa00cdedc2 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 { +@@ -141,6 +141,7 @@ struct ath11k_skb_rxcb { u8 tid; u16 peer_id; u16 seq_no; @@ -31,17 +31,17 @@ Signed-off-by: P Praneesh }; enum ath11k_hw_rev { -@@ -1026,6 +1027,7 @@ struct ath11k_base { +@@ -1074,6 +1075,7 @@ struct ath11k_base { atomic_t num_max_allowed; struct ath11k_num_vdevs_peers *num_vdevs_peers; + bool stats_disable; - /* must be last */ - u8 drv_priv[] __aligned(sizeof(void *)); + u32 max_ast_index; + u32 num_ast_entries; --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c -@@ -972,6 +972,79 @@ static const struct file_operations fops +@@ -974,6 +974,79 @@ static const struct file_operations fops .llseek = default_llseek, }; @@ -136,7 +136,7 @@ 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 +@@ -2553,10 +2559,60 @@ ath11k_dp_rx_h_find_peer(struct ath11k_b return peer; } @@ -198,7 +198,7 @@ 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 +@@ -2568,6 +2624,9 @@ static void ath11k_dp_rx_h_mpdu(struct a u32 err_bitmap; @@ -208,7 +208,7 @@ Signed-off-by: P Praneesh /* 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 +@@ -2581,6 +2640,30 @@ 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) { @@ -239,7 +239,7 @@ Signed-off-by: P Praneesh if (rxcb->is_mcbc) enctype = peer->sec_type_grp; else -@@ -2693,7 +2776,8 @@ static void ath11k_dp_rx_deliver_msdu(st +@@ -2844,7 +2927,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, @@ -249,7 +249,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 +@@ -2926,8 +3010,13 @@ static int ath11k_dp_rx_process_msdu(str } } @@ -264,7 +264,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 +@@ -2942,10 +3031,12 @@ static void ath11k_dp_rx_process_receive struct sk_buff_head *msdu_list, int mac_id) { @@ -277,7 +277,7 @@ Signed-off-by: P Praneesh if (skb_queue_empty(msdu_list)) return; -@@ -2811,7 +2902,12 @@ static void ath11k_dp_rx_process_receive +@@ -2962,7 +3053,12 @@ static void ath11k_dp_rx_process_receive } while ((msdu = __skb_dequeue(msdu_list))) { @@ -291,7 +291,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 +@@ -2970,7 +3066,10 @@ static void ath11k_dp_rx_process_receive continue; } @@ -303,7 +303,7 @@ Signed-off-by: P Praneesh } } -@@ -4117,6 +4216,7 @@ static int ath11k_dp_rx_h_null_q_desc(st +@@ -4268,6 +4367,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; @@ -311,7 +311,7 @@ Signed-off-by: P Praneesh 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 +@@ -4311,7 +4411,8 @@ static int ath11k_dp_rx_h_null_q_desc(st } ath11k_dp_rx_h_ppdu(ar, desc, status); @@ -385,7 +385,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 -@@ -5197,6 +5197,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/nss/ath11k/911-244-ath11k-dp-tx-perf.patch b/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch similarity index 89% rename from package/kernel/mac80211/patches/nss/ath11k/911-244-ath11k-dp-tx-perf.patch rename to package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch index e5a9c7a59b76cd..7430ded742fb14 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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_ +@@ -113,6 +113,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,7 +34,7 @@ Signed-off-by: P Praneesh }; struct ath11k_skb_cb { -@@ -919,7 +920,12 @@ struct ath11k_soc_dp_tx_err_stats { +@@ -888,7 +889,12 @@ struct ath11k_soc_dp_tx_err_stats { /* Other failures during dp_tx due to mem allocation failure * idr unavailable etc. */ @@ -49,7 +49,7 @@ Signed-off-by: P Praneesh --- 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 +58,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 +67,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 +79,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 +88,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 +97,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 +106,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 +117,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 +131,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 +142,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 +154,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 +174,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 +186,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 +205,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 +214,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 +225,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 +246,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 +254,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 +262,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 +294,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 +302,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 +323,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 +332,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; } @@ -371,7 +371,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); @@ -419,7 +419,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 +429,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 +@@ -6668,12 +6668,22 @@ static void ath11k_mac_op_tx(struct ieee if (control->sta) arsta = ath11k_sta_to_arsta(control->sta); @@ -453,7 +453,7 @@ Signed-off-by: P Praneesh ieee80211_free_txskb(ar->hw, skb); return; } -@@ -7690,7 +7700,7 @@ err_vdev_del: +@@ -7631,7 +7641,7 @@ err_vdev_del: idr_for_each(&ar->txmgmt_idr, ath11k_mac_vif_txmgmt_idr_remove, vif); @@ -464,7 +464,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 -@@ -835,10 +835,22 @@ static ssize_t ath11k_debugfs_dump_soc_d +@@ -833,10 +833,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 +489,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 +@@ -191,7 +191,6 @@ static struct ath11k_hw_params ath11k_hw .supports_regdb = false, .fix_l1ss = true, .credit_flow = false, @@ -497,7 +497,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 +@@ -216,6 +215,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 +506,7 @@ Signed-off-by: P Praneesh }, { .name = "qca6390 hw2.0", -@@ -384,6 +385,8 @@ static struct ath11k_hw_params ath11k_hw +@@ -383,6 +384,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 +515,9 @@ Signed-off-by: P Praneesh }, { .name = "wcn6855 hw2.0", -@@ -2147,6 +2150,9 @@ int ath11k_core_pre_init(struct ath11k_b - - ab->enable_memory_stats = ATH11K_DEBUG_ENABLE_MEMORY_STATS; +@@ -2144,6 +2147,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 +570,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 +581,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 +602,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 +613,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/908-301-ath11k-nss-mcbc-exception.patch b/package/kernel/mac80211/patches/nss/ath11k/301-ath11k-nss-mcbc-exception.patch similarity index 86% rename from package/kernel/mac80211/patches/nss/ath11k/908-301-ath11k-nss-mcbc-exception.patch rename to package/kernel/mac80211/patches/nss/ath11k/301-ath11k-nss-mcbc-exception.patch index 094d5b36305ac5..5202b7bf90fd02 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -637,7 +637,7 @@ static int ath11k_nss_undecap_nwifi(stru +@@ -567,7 +567,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; -@@ -673,8 +673,6 @@ static void ath11k_nss_wds_type_rx(struc +@@ -603,8 +603,6 @@ static void ath11k_nss_wds_type_rx(struc } } @@ -34,7 +34,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 } spin_unlock_bh(&ab->base_lock); -@@ -718,8 +716,7 @@ static void ath11k_nss_mec_handler(struc +@@ -648,8 +646,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; -@@ -741,7 +738,7 @@ static void ath11k_nss_vdev_spl_receive_ +@@ -671,7 +668,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)); -@@ -804,14 +801,16 @@ 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; +@@ -738,10 +735,12 @@ ath11k_nss_vdev_special_data_receive(str 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 + if (!dev) { + dev_kfree_skb_any(skb); +@@ -790,15 +789,50 @@ ath11k_nss_vdev_special_data_receive(str return; } @@ -130,7 +126,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 } static void -@@ -1058,6 +1092,9 @@ int ath11k_nss_vdev_set_cmd(struct ath11 +@@ -1005,6 +1039,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; } -@@ -1308,12 +1345,31 @@ int ath11k_nss_vdev_create(struct ath11k +@@ -1246,12 +1283,31 @@ int ath11k_nss_vdev_create(struct ath11k goto free_vdev; switch (arvif->vif->type) { @@ -173,7 +169,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 break; default: ret = -ENOTSUPP; -@@ -1472,7 +1528,7 @@ int ath11k_nss_ext_vdev_cfg_wds_peer(str +@@ -1401,7 +1457,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; @@ -182,7 +178,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 nss_wifi_ext_vdev_msg_init(ext_vdev_msg, arvif->nss.if_num, NSS_WIFI_EXT_VDEV_MSG_CONFIGURE_WDS, -@@ -1596,7 +1652,6 @@ static int ath11k_nss_ext_vdev_register( +@@ -1525,7 +1581,6 @@ static int ath11k_nss_ext_vdev_register( { struct ath11k *ar = arvif->ar; struct ath11k_base *ab = ar->ab; @@ -190,7 +186,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 u32 features = 0; if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN || arvif->nss.ctx) -@@ -1610,7 +1665,7 @@ static int ath11k_nss_ext_vdev_register( +@@ -1539,7 +1594,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,15 +197,13 @@ 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 { +@@ -109,8 +109,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 + @@ -218,7 +212,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 ATH11K_NSS_OPMODE_AP, --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -3074,6 +3074,23 @@ static void ath11k_dp_rx_process_receive +@@ -3073,6 +3073,23 @@ static void ath11k_dp_rx_process_receive } } @@ -244,7 +238,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 { --- 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 +@@ -138,4 +138,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); diff --git a/package/kernel/mac80211/patches/nss/ath11k/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch b/package/kernel/mac80211/patches/nss/ath11k/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch index 0a7dcf5e845780..ea8e6016dfa22c 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/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 +@@ -2793,6 +2794,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 +@@ -2812,6 +2814,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 +@@ -2989,11 +2993,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 +@@ -3022,6 +3028,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 +@@ -3034,6 +3049,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 +@@ -3327,6 +3343,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; +@@ -63,6 +63,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, - }; +@@ -115,6 +116,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/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 index 7ea6b471e340aa..6bf1ba225e0bd5 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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_ +@@ -1440,6 +1440,7 @@ const struct ath11k_hw_ring_mask ath11k_ ATH11K_RX_WBM_REL_RING_MASK_0, }, .reo_status = { diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 96% rename from package/kernel/mac80211/patches/nss/ath11k/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 bb27ff31a47d43..9635b4b6297a6b 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -2209,6 +2209,7 @@ struct ath11k_base *ath11k_core_alloc(st +@@ -2213,6 +2213,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); -@@ -2222,6 +2223,8 @@ struct ath11k_base *ath11k_core_alloc(st +@@ -2226,6 +2227,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); @@ -83,7 +83,7 @@ Signed-off-by: Rameshkumar Sundaram #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) -@@ -1098,6 +1099,11 @@ struct ath11k_base { +@@ -1085,6 +1086,11 @@ struct ath11k_base { u32 max_ast_index; u32 num_ast_entries; @@ -97,7 +97,7 @@ Signed-off-by: Rameshkumar Sundaram }; --- a/drivers/net/wireless/ath/ath11k/nss.c +++ b/drivers/net/wireless/ath/ath11k/nss.c -@@ -678,8 +678,9 @@ static void ath11k_nss_wds_type_rx(struc +@@ -609,8 +609,9 @@ static void ath11k_nss_wds_type_rx(struc spin_unlock_bh(&ab->base_lock); } @@ -108,7 +108,7 @@ Signed-off-by: Rameshkumar Sundaram struct ath11k_base *ab = ar->ab; struct ath11k_peer *peer = ar->bss_peer; u8 mac_addr[ETH_ALEN]; -@@ -706,7 +707,7 @@ static void ath11k_nss_mec_handler(struc +@@ -637,7 +638,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 +117,7 @@ Signed-off-by: Rameshkumar Sundaram spin_lock_bh(&ab->base_lock); ath11k_peer_add_ast(ar, peer, mac_addr, ATH11K_AST_TYPE_MEC); -@@ -741,7 +742,7 @@ static void ath11k_nss_vdev_spl_receive_ +@@ -672,7 +673,7 @@ static void ath11k_nss_vdev_spl_receive_ addr4_valid, peer_id); break; case NSS_WIFI_VDEV_WDS_TYPE_MEC: @@ -126,7 +126,7 @@ Signed-off-by: Rameshkumar Sundaram break; default: ath11k_warn(ab, "unsupported wds_type %d\n", wds_type); -@@ -2410,11 +2411,7 @@ int ath11k_nss_add_wds_peer(struct ath11 +@@ -2335,11 +2336,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 +139,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; -@@ -2537,7 +2534,7 @@ msg_free: +@@ -2462,7 +2459,7 @@ msg_free: return ret; } @@ -148,7 +148,7 @@ Signed-off-by: Rameshkumar Sundaram u8 *dest_mac) { struct ath11k_base *ab = ar->ab; -@@ -2555,8 +2552,8 @@ int ath11k_nss_del_wds_peer(struct ath11 +@@ -2480,8 +2477,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; @@ -494,7 +494,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,7 +504,7 @@ Signed-off-by: Rameshkumar Sundaram struct ath11k_peer *peer; struct ath11k *ar; bool next_hop; -@@ -44,9 +42,9 @@ struct ath11k_ast_entry { +@@ -55,9 +53,9 @@ struct ath11k_ast_entry { u16 ast_hash_value; int ref_cnt; enum ath11k_ast_entry_type type; @@ -514,7 +514,7 @@ Signed-off-by: Rameshkumar Sundaram + struct list_head wmi_list; }; - struct ppdu_user_delayba { + struct ath11k_peer { @@ -97,6 +95,7 @@ struct ath11k_peer { bool dp_setup_done; struct ppdu_user_delayba ppdu_stats_delayba; diff --git a/package/kernel/mac80211/patches/nss/ath11k/911-335-0001-ath11k-optimize-tx-completions.patch b/package/kernel/mac80211/patches/nss/ath11k/335-0001-ath11k-optimize-tx-completions.patch similarity index 93% rename from package/kernel/mac80211/patches/nss/ath11k/911-335-0001-ath11k-optimize-tx-completions.patch rename to package/kernel/mac80211/patches/nss/ath11k/335-0001-ath11k-optimize-tx-completions.patch index 3cc13d1ba98543..e34922f11df238 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/911-335-0001-ath11k-optimize-tx-completions.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/335-0001-ath11k-optimize-tx-completions.patch @@ -13,7 +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 +@@ -453,6 +453,7 @@ ath11k_dp_tx_htt_tx_complete_buf(struct return; } @@ -21,7 +21,7 @@ Signed-off-by: Venkateswara Naralasetty 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 +652,41 @@ err_out: spin_unlock_bh(&ab->base_lock); } @@ -64,7 +64,7 @@ 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 +696,12 @@ static void ath11k_dp_tx_complete_msdu(s struct ath11k_peer *peer; struct ath11k_sta *arsta; struct rate_info rate; @@ -78,7 +78,7 @@ Signed-off-by: Venkateswara Naralasetty /* Must not happen */ return; } -@@ -660,11 +696,14 @@ static void ath11k_dp_tx_complete_msdu(s +@@ -674,11 +710,14 @@ static void ath11k_dp_tx_complete_msdu(s dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); @@ -95,7 +95,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 +727,8 @@ static void ath11k_dp_tx_complete_msdu(s return; } @@ -104,7 +104,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 +@@ -698,54 +739,56 @@ static void ath11k_dp_tx_complete_msdu(s return; } @@ -173,7 +173,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,44 +810,13 @@ static void ath11k_dp_tx_complete_msdu(s ieee80211_tx_status_ext(ar->hw, &status); } @@ -219,7 +219,7 @@ Signed-off-by: Venkateswara Naralasetty /* 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 +833,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,7 +230,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 +@@ -843,7 +855,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))) { @@ -239,7 +239,7 @@ Signed-off-by: Venkateswara Naralasetty continue; memcpy(&tx_ring->tx_status[count], -@@ -849,14 +861,16 @@ void ath11k_dp_tx_completion_handler(str +@@ -863,14 +875,16 @@ void ath11k_dp_tx_completion_handler(str while (count--) { tx_status = &tx_ring->tx_status[i++]; @@ -258,7 +258,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 +908,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/nss/ath11k/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 95% rename from package/kernel/mac80211/patches/nss/ath11k/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 33a5167cf41c2b..5c5e2de6ed756f 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -144,7 +144,7 @@ Signed-off-by: Venkateswara Naralasetty #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; @@ -152,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); @@ -187,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); @@ -201,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, @@ -226,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 }; @@ -251,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 +@@ -874,6 +885,7 @@ void ath11k_dp_tx_completion_handler(str } while (count--) { @@ -259,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 +@@ -892,17 +904,19 @@ void ath11k_dp_tx_completion_handler(str continue; } diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 641f45b094a598..3b118c3fb5093c 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -9680,6 +9680,8 @@ static int __ath11k_mac_register(struct +@@ -10114,6 +10114,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-skip-status-ring-entry-processing.patch b/package/kernel/mac80211/patches/nss/ath11k/336-ath11k-skip-status-ring-entry-processing.patch index 2e874d321d0ad1..f03b4e2d7e5df6 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 +@@ -3464,6 +3464,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_ +@@ -3477,6 +3517,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_ +@@ -3496,8 +3537,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_ +@@ -3528,18 +3568,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/nss/ath11k/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/nss/ath11k/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 425bb3c70e9693..af64057faf823f 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -1840,6 +1840,11 @@ static int ath11k_core_reconfigure_on_cr +@@ -1839,6 +1839,11 @@ static int ath11k_core_reconfigure_on_cr clear_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags); diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 414cb06d87bd4b..3c765c9c2df46e 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 +@@ -4882,12 +4882,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 +@@ -5478,6 +5472,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/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch b/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch index d8c907556645cf..ec9d831abded55 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch @@ -13,7 +13,7 @@ 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 +@@ -2515,7 +2515,8 @@ static void ath11k_dp_rx_h_undecap(struc ehdr = (struct ethhdr *)msdu->data; /* mac80211 allows fast path only for authorized STA */ diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 84% rename from package/kernel/mac80211/patches/nss/ath11k/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 9111724a8344be..b4e399144ac1ae 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -803,8 +803,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; -@@ -2485,13 +2483,14 @@ msg_free: +@@ -2410,13 +2410,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); -@@ -2501,7 +2500,7 @@ int ath11k_nss_map_wds_peer(struct ath11 +@@ -2426,7 +2427,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; @@ -84,7 +75,7 @@ Signed-off-by: Raj Kumar Bhagat } --- a/drivers/net/wireless/ath/ath11k/peer.c +++ b/drivers/net/wireless/ath/ath11k/peer.c -@@ -373,8 +373,7 @@ void ath11k_peer_map_ast(struct ath11k * +@@ -359,8 +359,7 @@ void ath11k_peer_map_ast(struct ath11k * if ((ast_entry->type == ATH11K_AST_TYPE_WDS) || (ast_entry->type == ATH11K_AST_TYPE_MEC)) diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 7b3df32c05b69e..6b4433aafa4f41 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -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 */ +@@ -333,6 +370,10 @@ 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_LINK_DESC_INFO_MSG: + ath11k_nss_wifili_link_desc_return(ab, diff --git a/package/kernel/mac80211/patches/nss/ath11k/702-ath11k-fix-memory-leak-in-dp-rx.patch b/package/kernel/mac80211/patches/nss/ath11k/702-ath11k-fix-memory-leak-in-dp-rx.patch index 1bfa9b89b45c5f..250112c55a89c4 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/702-ath11k-fix-memory-leak-in-dp-rx.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/702-ath11k-fix-memory-leak-in-dp-rx.patch @@ -28,7 +28,7 @@ Signed-off-by: Hari Chandrakanthan --- 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 +@@ -2663,8 +2663,6 @@ static void ath11k_dp_rx_h_mpdu(struct a } } @@ -37,7 +37,7 @@ Signed-off-by: Hari Chandrakanthan if (rxcb->is_mcbc) enctype = peer->sec_type_grp; else -@@ -2523,6 +2521,8 @@ static void ath11k_dp_rx_h_mpdu(struct a +@@ -2674,6 +2672,8 @@ static void ath11k_dp_rx_h_mpdu(struct a } spin_unlock_bh(&ar->ab->base_lock); diff --git a/package/kernel/mac80211/patches/nss/ath11k/904-300-ath11k-nss_get_arvif_from_dev.patch b/package/kernel/mac80211/patches/nss/ath11k/904-300-ath11k-nss_get_arvif_from_dev.patch deleted file mode 100644 index fe2c45973cf6b0..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -33,6 +33,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) - { -@@ -292,6 +316,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: -@@ -300,7 +327,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; -@@ -461,7 +487,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/nss/ath11k/906-456-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch b/package/kernel/mac80211/patches/nss/ath11k/906-456-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch index 10c39288094b5f..92fb2195806f2d 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/906-456-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/906-456-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch @@ -18,7 +18,7 @@ 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,9 @@ tcl_ring_sel: switch (ti.encap_type) { case HAL_TCL_ENCAP_TYPE_NATIVE_WIFI: diff --git a/package/kernel/mac80211/patches/nss/subsys/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 100% rename from package/kernel/mac80211/patches/nss/subsys/207-mac80211-Add-support-for-dynamic-vlan.patch rename to package/kernel/mac80211/patches/nss/subsys/207-ath11k-Add-support-for-dynamic-vlan.patch diff --git a/package/kernel/mac80211/patches/nss/subsys/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 94% rename from package/kernel/mac80211/patches/nss/subsys/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 68728ea7ecf6a0..14869c1e2cb340 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -5129,6 +5129,17 @@ void ieee80211_sta_pspoll(struct ieee802 +@@ -5095,6 +5095,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 -@@ -2180,7 +2180,13 @@ static int ieee80211_change_station(stru +@@ -2176,7 +2176,13 @@ static int ieee80211_change_station(stru rcu_assign_pointer(vlansdata->u.vlan.sta, sta); __ieee80211_check_fast_rx_iface(vlansdata); @@ -91,7 +91,7 @@ Signed-off-by: Sathishkumar Muruganandam case NL80211_IFTYPE_STATION: return true; default: -@@ -1015,7 +1019,8 @@ static void ieee80211_set_vif_encap_ops( +@@ -1014,7 +1018,8 @@ static void ieee80211_set_vif_encap_ops( struct ieee80211_sub_if_data *bss = sdata; bool enabled; @@ -101,7 +101,7 @@ Signed-off-by: Sathishkumar Muruganandam if (!sdata->bss) return; -@@ -1360,10 +1365,17 @@ int ieee80211_do_open(struct wireless_de +@@ -1359,10 +1364,17 @@ int ieee80211_do_open(struct wireless_de switch (sdata->vif.type) { case NL80211_IFTYPE_AP_VLAN: @@ -137,8 +137,8 @@ Signed-off-by: Sathishkumar Muruganandam { --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4730,7 +4730,8 @@ static void ieee80211_8023_xmit(struct i - info->flags |= info_flags; +@@ -4692,7 +4692,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 +181,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 +@@ -5218,7 +5218,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/nss/subsys/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 97% rename from package/kernel/mac80211/patches/nss/subsys/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 d54dae55fc414e..e6bafbbb367458 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -2106,6 +2106,8 @@ enum ieee80211_key_flags { +@@ -2084,6 +2084,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) -@@ -2125,6 +2127,7 @@ struct ieee80211_key_conf { +@@ -2103,6 +2105,7 @@ struct ieee80211_key_conf { u8 hw_key_idx; s8 keyidx; u16 flags; diff --git a/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch b/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch index 923517d3d2d40d..2fe7a853e719b7 100644 --- a/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch +++ b/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch @@ -64,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 +@@ -4740,7 +4742,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; @@ -73,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 +@@ -4758,9 +4760,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 goto out; } @@ -90,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 +@@ -4771,6 +4777,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); @@ -100,7 +100,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c -@@ -5342,7 +5342,7 @@ void ieee80211_rx_list(struct ieee80211_ +@@ -5348,7 +5348,7 @@ void ieee80211_rx_list(struct ieee80211_ if (pubsta) { sta = container_of(pubsta, struct sta_info, sta); diff --git a/package/kernel/mac80211/patches/nss/subsys/300-mac80211-nss-mesh-offload-support.patch b/package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch similarity index 98% rename from package/kernel/mac80211/patches/nss/subsys/300-mac80211-nss-mesh-offload-support.patch rename to package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch index f1dc602953c69e..aaa9b285b46c7c 100644 --- a/package/kernel/mac80211/patches/nss/subsys/300-mac80211-nss-mesh-offload-support.patch +++ b/package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch @@ -112,7 +112,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran }; -@@ -2763,6 +2783,7 @@ enum ieee80211_hw_flags { +@@ -2766,6 +2786,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 -@@ -4263,6 +4284,8 @@ struct ieee80211_prep_tx_info { +@@ -4266,6 +4287,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. -@@ -4646,6 +4669,12 @@ struct ieee80211_ops { +@@ -4649,6 +4672,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); -@@ -7479,4 +7508,100 @@ int ieee80211_set_active_links(struct ie +@@ -7493,4 +7522,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 -@@ -2512,6 +2512,7 @@ static int ieee80211_update_mesh_config( +@@ -2519,6 +2519,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; -@@ -2528,8 +2529,11 @@ static int ieee80211_update_mesh_config( +@@ -2535,8 +2536,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)) { -@@ -2543,8 +2547,12 @@ static int ieee80211_update_mesh_config( +@@ -2550,8 +2554,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)) -@@ -2579,8 +2587,12 @@ static int ieee80211_update_mesh_config( +@@ -2586,8 +2594,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. -@@ -2622,6 +2634,7 @@ static int ieee80211_update_mesh_config( +@@ -2629,6 +2641,7 @@ static int ieee80211_update_mesh_config( conf->dot11MeshConnectedToAuthServer = nconf->dot11MeshConnectedToAuthServer; ieee80211_mbss_info_change_notify(sdata, BSS_CHANGED_BEACON); @@ -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 +@@ -572,3 +572,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); diff --git a/package/kernel/mac80211/patches/nss/subsys/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 94% rename from package/kernel/mac80211/patches/nss/subsys/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 6a37ba0e1aa730..b488e431c6cd3c 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 { +@@ -2728,6 +2728,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 { +@@ -2787,6 +2789,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_MLO_MCAST_MULTI_LINK_TX, IEEE80211_HW_SUPPORTS_NSS_OFFLOAD, IEEE80211_HW_SUPPORTS_MESH_NSS_OFFLOAD, diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index 0fbdc2a7d7cdd1..6ae2863bbe8a90 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -4753,6 +4753,70 @@ out_free: +@@ -4754,6 +4754,70 @@ out_free: kfree_skb(skb); } @@ -85,7 +85,7 @@ Signed-off-by: Aloka Dixit netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, struct net_device *dev) { -@@ -4792,6 +4856,11 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4793,6 +4857,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/nss/subsys/336-mac80211-Mesh-Fast-rx-support.patch b/package/kernel/mac80211/patches/nss/subsys/336-mac80211-Mesh-Fast-rx-support.patch index 70bbee69332044..eb6c51c8ba0cad 100644 --- a/package/kernel/mac80211/patches/nss/subsys/336-mac80211-Mesh-Fast-rx-support.patch +++ b/package/kernel/mac80211/patches/nss/subsys/336-mac80211-Mesh-Fast-rx-support.patch @@ -94,7 +94,7 @@ Signed-off-by: Sriram R if (action) { --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c -@@ -4643,10 +4643,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; -@@ -4687,7 +4692,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; -@@ -4870,6 +4875,10 @@ static bool ieee80211_invoke_fast_rx(str +@@ -4876,6 +4881,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 -@@ -4919,6 +4928,37 @@ static bool ieee80211_invoke_fast_rx(str +@@ -4925,6 +4934,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))) -@@ -4956,9 +4996,33 @@ static bool ieee80211_invoke_fast_rx(str +@@ -4962,9 +5002,33 @@ static bool ieee80211_invoke_fast_rx(str return true; } diff --git a/package/kernel/mac80211/patches/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch b/package/kernel/mac80211/patches/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch index bc7a55273daf58..aa35bc746e6d5a 100644 --- a/package/kernel/mac80211/patches/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch +++ b/package/kernel/mac80211/patches/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch @@ -33,7 +33,7 @@ Signed-off-by: Tamizh Chelvam --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4730,12 +4730,12 @@ static void ieee80211_8023_xmit(struct i +@@ -4731,12 +4731,12 @@ static void ieee80211_8023_xmit(struct i if (unlikely(skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS && diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index d128824140ecb6..ba80b62d0ac732 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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/nss/subsys/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 index b54cea6c97751f..bbd632cae45c6f 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 @@ -113,8 +113,8 @@ Signed-off-by: Aaradhana Sahu + info->flags |= info_flags; info->hw_queue = sdata->vif.hw_queue[queue]; - if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) -@@ -4728,9 +4745,10 @@ static void ieee80211_8023_xmit(struct i + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && +@@ -4729,9 +4746,10 @@ static void ieee80211_8023_xmit(struct i memcpy(IEEE80211_SKB_CB(seg), info, sizeof(*info)); } @@ -128,7 +128,7 @@ Signed-off-by: Aaradhana Sahu info->ack_frame_id = ieee80211_store_ack_skb(local, skb, &info->flags, NULL); -@@ -4755,7 +4773,8 @@ out_free: +@@ -4756,7 +4774,8 @@ out_free: void ieee80211_8023_xmit_ap(struct ieee80211_sub_if_data *sdata, struct net_device *dev, struct sta_info *sta, @@ -138,7 +138,7 @@ Signed-off-by: Aaradhana Sahu { struct ieee80211_tx_info *info; struct ieee80211_local *local = sdata->local; -@@ -4764,6 +4783,9 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4765,6 +4784,9 @@ void ieee80211_8023_xmit_ap(struct ieee8 unsigned long flags; int q; u16 q_map; @@ -148,7 +148,7 @@ Signed-off-by: Aaradhana Sahu /* * If the skb is shared we need to obtain our own copy. -@@ -4775,11 +4797,13 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4776,11 +4798,13 @@ void ieee80211_8023_xmit_ap(struct ieee8 info = IEEE80211_SKB_CB(skb); memset(info, 0, sizeof(*info)); @@ -165,7 +165,7 @@ Signed-off-by: Aaradhana Sahu info->flags |= IEEE80211_TX_CTL_HW_80211_ENCAP; info->control.vif = &sdata->vif; -@@ -4816,14 +4840,23 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4817,14 +4841,23 @@ void ieee80211_8023_xmit_ap(struct ieee8 if (sta) atomic_inc(&sta->tx_drv_pkts); } @@ -190,7 +190,7 @@ Signed-off-by: Aaradhana Sahu #ifdef CPTCFG_MAC80211_NSS_SUPPORT ieee80211_xmit_nss_fixup(skb, dev); -@@ -4839,14 +4872,15 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4840,14 +4873,15 @@ netdev_tx_t ieee80211_subif_start_xmit_8 kfree_skb(skb); goto out; } @@ -208,7 +208,7 @@ Signed-off-by: Aaradhana Sahu goto skip_offload; key = rcu_dereference(sta->ptk[sta->ptk_idx]); -@@ -4857,13 +4891,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4858,13 +4892,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 goto skip_offload; if (sdata->vif.type == NL80211_IFTYPE_AP) { @@ -224,7 +224,7 @@ Signed-off-by: Aaradhana Sahu goto out; skip_offload: -@@ -6369,13 +6403,10 @@ start_xmit: +@@ -6370,13 +6404,10 @@ start_xmit: mutex_lock(&local->mtx); local_bh_disable(); diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index 6614d8d496b354..8a913cf0b4e425 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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_ +@@ -2346,7 +2346,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; diff --git a/package/kernel/mac80211/patches/nss/subsys/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch b/package/kernel/mac80211/patches/nss/subsys/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch index 12ce4198462047..e3c2db4cc8a713 100644 --- a/package/kernel/mac80211/patches/nss/subsys/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch +++ b/package/kernel/mac80211/patches/nss/subsys/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch @@ -27,7 +27,7 @@ Signed-off-by: Ramanathan Choodamani if (likely(!is_multicast_ether_addr(eth->h_dest))) goto normal; -@@ -4843,7 +4844,43 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4844,7 +4845,43 @@ void ieee80211_8023_xmit_ap(struct ieee8 netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, struct net_device *dev) { diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index b59cd3f547936e..a2a9879f25285b 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 @@ -84,7 +84,7 @@ Signed-off-by: Tamizh Chelvam Raja if (!skb) return; -@@ -4844,6 +4845,7 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4845,6 +4846,7 @@ void ieee80211_8023_xmit_ap(struct ieee8 netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, struct net_device *dev) { @@ -92,7 +92,7 @@ Signed-off-by: Tamizh Chelvam Raja 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 = {}; -@@ -4878,9 +4880,10 @@ out: +@@ -4879,9 +4881,10 @@ out: } return NETDEV_TX_OK; @@ -107,7 +107,7 @@ Signed-off-by: Tamizh Chelvam Raja netdev_tx_t __ieee80211_subif_start_xmit_8023(struct sk_buff *skb, --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c -@@ -2255,6 +2255,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/829-mac80211-fix-mesh-ping-issue.patch b/package/kernel/mac80211/patches/nss/subsys/829-mac80211-fix-mesh-ping-issue.patch index eed0aececb6779..c19d97a818ba17 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -4643,16 +4643,14 @@ void ieee80211_check_fast_rx(struct sta_ +@@ -4649,16 +4649,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; } -@@ -4875,10 +4873,7 @@ static bool ieee80211_invoke_fast_rx(str +@@ -4881,10 +4879,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 -@@ -4928,37 +4923,6 @@ static bool ieee80211_invoke_fast_rx(str +@@ -4934,37 +4929,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))) -@@ -4996,30 +4960,6 @@ static bool ieee80211_invoke_fast_rx(str +@@ -5002,30 +4966,6 @@ static bool ieee80211_invoke_fast_rx(str return true; } From 4336f8e4231029da8718eaab1d0ef18ddb9423cc Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 29 Jan 2024 17:05:41 -0500 Subject: [PATCH 103/225] ath11k_nss: align wifi offload with qca-nss-drv The option in qca-nss-drv is actually 'NSS_DRV_WIFIOFFLOAD_ENABLE' use the same syntax. --- package/kernel/mac80211/ath.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk index dd35624db313db..3dff5e754cedcd 100644 --- a/package/kernel/mac80211/ath.mk +++ b/package/kernel/mac80211/ath.mk @@ -312,7 +312,7 @@ define KernelPackage/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):NSS_DRV_WIFI_ENABLE \ + +@(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 From 7588d89b563fc8fc83293eeeec199a334dd349d5 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 29 Jan 2024 22:27:57 -0500 Subject: [PATCH 104/225] ath10k-ct: fix compile with NSS wifi --- .../999-003-ath10k-add-nss-support.patch | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 package/kernel/ath10k-ct/patches/999-003-ath10k-add-nss-support.patch diff --git a/package/kernel/ath10k-ct/patches/999-003-ath10k-add-nss-support.patch b/package/kernel/ath10k-ct/patches/999-003-ath10k-add-nss-support.patch new file mode 100644 index 00000000000000..2ef718625f011e --- /dev/null +++ b/package/kernel/ath10k-ct/patches/999-003-ath10k-add-nss-support.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 From 5c42fcdae13efa2ad5adb11f5e609eb3400fca2e Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 29 Jan 2024 22:31:18 -0500 Subject: [PATCH 105/225] hostapd: Delete already applied patch --- ...CS-Fix-typo-in-bw_40-frequency-array.patch | 25 ------------------- 1 file changed, 25 deletions(-) delete mode 100644 package/network/services/hostapd/patches/993-2023-10-28-ACS-Fix-typo-in-bw_40-frequency-array.patch diff --git a/package/network/services/hostapd/patches/993-2023-10-28-ACS-Fix-typo-in-bw_40-frequency-array.patch b/package/network/services/hostapd/patches/993-2023-10-28-ACS-Fix-typo-in-bw_40-frequency-array.patch deleted file mode 100644 index 948c51b196beb3..00000000000000 --- a/package/network/services/hostapd/patches/993-2023-10-28-ACS-Fix-typo-in-bw_40-frequency-array.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 7a733993211ad46cf3032038c1e7e6bdc2322336 Mon Sep 17 00:00:00 2001 -From: Michael-CY Lee -Date: Tue, 5 Sep 2023 09:43:25 +0800 -Subject: [PATCH] ACS: Fix typo in bw_40 frequency array - -The range for the 5 GHz channel 118 was encoded with an incorrect -channel number. - -Fixes: ed8e13decc71 (ACS: Extract bw40/80/160 freqs out of acs_usable_bwXXX_chan()) -Signed-off-by: Michael Lee ---- - src/ap/acs.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/src/ap/acs.c -+++ b/src/ap/acs.c -@@ -256,7 +256,7 @@ struct bw_item { - static const struct bw_item bw_40[] = { - { 5180, 5200, 38 }, { 5220, 5240, 46 }, { 5260, 5280, 54 }, - { 5300, 5320, 62 }, { 5500, 5520, 102 }, { 5540, 5560, 110 }, -- { 5580, 5600, 110 }, { 5620, 5640, 126}, { 5660, 5680, 134 }, -+ { 5580, 5600, 118 }, { 5620, 5640, 126 }, { 5660, 5680, 134 }, - { 5700, 5720, 142 }, { 5745, 5765, 151 }, { 5785, 5805, 159 }, - { 5825, 5845, 167 }, { 5865, 5885, 175 }, - { 5955, 5975, 3 }, { 5995, 6015, 11 }, { 6035, 6055, 19 }, From 9c71f24f1bd7eff7010f96d2b0abbc0a56678694 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 11 Feb 2024 09:46:22 -0500 Subject: [PATCH 106/225] ath11k_nss: Merge every NSS related feature + more * Added macro to disable NSS mesh offload * Added menuconfig option "ATH11K_NSS_MESH_SUPPORT" to selectivley build mesh support, as well it's depenacndy on nss-drv-wifimeshmgr. * Added option to disable HTT Stats, and STA stats (stations). * Reducing footprint by ~210KB. Debugfs minimal is still enabled. * Reworked a TON of patches, some my own, hopefully there should be a far less amount of WOA2/WPA3 connection issues. * Updated the /etc/init.d/pbuf script to be more robust. (handles tweaking ath11k and NSS settings better) NOTES: Although mesh package builds (nss-drv-wifimeshmgr), ath11k doesn't seem to support it yet. Not sure if NSS requires 3 radios to work, I'm at a dead end currently with that route. ATTENTION: the ptch `37-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch` works well on nss with frame_mode=2. And on `ath11k frame_mode=1 nss_offload=0` And on `ath11k frame_mode=2 nss_offload=1` if you set nss_offload=off and frame_mode=2, it will CRASH if you set nss_offload=on and frame_mode=2, it will RUN if you set nss_offload=off and frame_mode=1, it will RUN --- package/kernel/mac80211/Makefile | 4 +- package/kernel/mac80211/ath.mk | 38 +- .../kernel/mac80211/files/qca-nss-pbuf.init | 100 +- .../068-ath11k-add-rx-histogram-stats.patch | 671 ++++ ...69-ath11k-add-HE-stats-in-peer-stats.patch | 32 +- ...080-ath11k-ethernet-rx-decap-offload.patch | 15 + ...dma-counter-always-zero-in-peer-stat.patch | 82 + .../ath11k/107-ath11k-tid-counter-fix.patch | 21 - ...ul-ofdma-ru-allocation-in-peer-stats.patch | 452 +++ ...-ath11k_nss-add-nss-driver-interface.patch | 27 +- .../199-003-ath11k-add-nss-support.patch | 151 +- ...207-ath11k-Enable-256_512MB-profiles.patch | 144 +- ...-support-on-NSS-offload-for-STA-mode.patch | 30 +- ...14-ath11k-qos-null-frame-tx-over-wmi.patch | 168 +- ...rt-to-enable-disable-color-collision.patch | 46 + ...11k-Disable-rx_header-tlv-for-2K-SKB.patch | 902 ----- ...01-ath11k-account-tx-rx-packets-flow.patch | 494 --- ...th11k-Add-support-for-beacon-tx-mode.patch | 52 + ...vdev-in-NSS-for-AP_VLAN-vif-handling.patch | 36 +- ...pport-for-WDS-offload-in-NSS-offload.patch | 52 +- ...ow-fast-rx-by-bypassing-stats-update.patch | 102 + ...ow-fast-rx-by-bypassing-stats-update.patch | 181 +- .../nss/ath11k/244-ath11k-dp-tx-perf.patch | 33 +- .../300-ath11k-nss-mesh-offload-support.patch | 3365 +++++++++++++++++ .../301-ath11k-nss-mcbc-exception.patch | 64 +- ...-nss-thread-priority-during-pdev_ini.patch | 109 - ...lookup-failure-in-mgmt-tx-completion.patch | 125 + ...30-ath11k-sync-wds_ast_entry-updates.patch | 54 +- ...-0001-ath11k-optimize-tx-completions.patch | 52 +- ...se-DECLARE_BITMAP-for-idr-operations.patch | 6 +- ...ing-rx-stats-with-monitor-vif-enable.patch | 88 + ...-frags-from-uninitialized-peer-in-dp.patch | 74 + ...356-ath11k-invalid-desc-sanity-check.patch | 85 + ...Fix-ppdu_id-from-firmware-PPDU-stats.patch | 52 + ...Add-retry-mechanism-for-update_rx_qu.patch | 384 ++ ...treaming-not-working-for-wan-to-wlan.patch | 49 + .../702-ath11k-fix-memory-leak-in-dp-rx.patch | 48 - ...ing-memset-of-ppdu-info-for-next-skb.patch | 87 + ...support-to-send-the-QoS-Null-Data-fr.patch | 7 +- ...11k-remove-invalid-peer-create-logic.patch | 58 + ...k-make-debugfs-sta-htt-stats-modular.patch | 198 + .../199-001-mac80211-add-nss-support.patch | 2 +- ...03-mac80211-ath11k-fw-dynamic-muedca.patch | 203 + ...-mac80211-account-tx-rx-packets-flow.patch | 369 -- ...N-iftype-support-on-NSS-offload-case.patch | 16 + ...80211-Add-support-for-beacon-tx-mode.patch | 174 + ...-dynamic-VLAN-support-on-NSS-offload.patch | 28 + .../nss/subsys/245-compilation_fix.patch | 32 +- .../300-ath11k-nss-mesh-offload-support.patch | 47 +- ...-0005-mac80211-simple-tx-for-AP-mode.patch | 7 +- ...mac80211-fix-unconditional-sta-usage.patch | 15 +- .../345-mac80211-fix-mixed-declaration.patch | 57 + ...change-to-40Mhz-during-channel-switc.patch | 39 + ...unused-RX_FLAGS-from-mac80211_rx_fla.patch | 85 + ...ncapsulation-of-EAPOL-frames-if-OFFL.patch | 81 +- ...fix-RCU-stall-in-mesh-fast-xmit-path.patch | 12 +- 56 files changed, 7196 insertions(+), 2709 deletions(-) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/068-ath11k-add-rx-histogram-stats.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/080-ath11k-ethernet-rx-decap-offload.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/084-ath11k-fix-ul-ofdma-counter-always-zero-in-peer-stat.patch delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/107-ath11k-tid-counter-fix.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/218-ath11k-add-support-to-enable-disable-color-collision.patch delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/234-001-ath11k-account-tx-rx-packets-flow.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/235-001-ath11k-Add-support-for-beacon-tx-mode.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/237-001-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/300-ath11k-nss-mesh-offload-support.patch delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/314-ath11k-Fix-peer-lookup-failure-in-mgmt-tx-completion.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/336-ath11k-Fix-updating-rx-stats-with-monitor-vif-enable.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/371-ath11k-Fix-ppdu_id-from-firmware-PPDU-stats.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/702-ath11k-fix-memory-leak-in-dp-rx.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/907-01-wifi-ath11k-remove-invalid-peer-create-logic.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/908-ath11k-make-debugfs-sta-htt-stats-modular.patch create mode 100644 package/kernel/mac80211/patches/nss/subsys/203-mac80211-ath11k-fw-dynamic-muedca.patch delete mode 100644 package/kernel/mac80211/patches/nss/subsys/234-002-mac80211-account-tx-rx-packets-flow.patch create mode 100644 package/kernel/mac80211/patches/nss/subsys/235-002-mac80211-Add-support-for-beacon-tx-mode.patch create mode 100644 package/kernel/mac80211/patches/nss/subsys/345-mac80211-fix-mixed-declaration.patch create mode 100644 package/kernel/mac80211/patches/nss/subsys/346-mac80211-fix-bw-change-to-40Mhz-during-channel-switc.patch create mode 100644 package/kernel/mac80211/patches/nss/subsys/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 5060fe5ae0aaa9..26d3c0533e1604 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 PKG_VERSION:=6.5 -PKG_RELEASE:=11 +PKG_RELEASE:=12 # PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.15.58/ PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/ PKG_HASH:=908c22dceba185eab83caa5a1e58ce6b3ebdc58f099c3fd3e11c7352ebfab2d7 @@ -38,7 +38,7 @@ 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 diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk index 3dff5e754cedcd..f5fbf965ffc505 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 += \ @@ -64,6 +67,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) += ATH10K ATH10K_PCI @@ -312,6 +318,7 @@ define KernelPackage/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_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 \ @@ -327,6 +334,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 @@ -334,6 +345,20 @@ 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_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_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 || \ @@ -342,10 +367,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 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/qca-nss-pbuf.init b/package/kernel/mac80211/files/qca-nss-pbuf.init index 02afd5f6c3d380..eaba09ca85e8af 100755 --- a/package/kernel/mac80211/files/qca-nss-pbuf.init +++ b/package/kernel/mac80211/files/qca-nss-pbuf.init @@ -28,43 +28,64 @@ apply_sysctl() { 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 - - 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 - - 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 > /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 + # + # 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 } 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 + + 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.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 + 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 case "$memory_profile" in - 1g*|512m*|256m*) - board=$memory_profile - logger -t ath11k_nss "Using custom memory profile - $board" - ;; - off*|false*|disable*|0) - logger -s -t ath11k_nss -p user.warn "NSS pbuf option 'memory_profile=off'. Not running. Enable if you have issues connecting more than 65 clients" - exit 0 - ;; - auto) - board=$(board_name) - logger -t ath11k_nss "Setting n2hcfg values for board: $board" - ;; - *) - logger -s -t ath11k_nss -p user.error "Unknown profile $memory_profile. Choose auto, 1gb, 512mb, or 256mb" - exit 1 - ;; + 1g* | 512m* | 256m*) + board=$memory_profile + logger -t ath11k_nss "Using custom memory profile - $board" + ;; + off* | false* | disable* | 0) + logger -s -t ath11k_nss -p user.warn "NSS pbuf option 'memory_profile=off'. Not running. Enable if you have issues connecting more than 65 clients" + exit 0 + ;; + auto) + board=$(board_name) + logger -t ath11k_nss "Setting n2hcfg values for board: $board" + ;; + *) + logger -s -t ath11k_nss -p user.error "Unknown profile $memory_profile. Choose auto, 1gb, 512mb, or 256mb" + exit 1 + ;; esac else - exi 0 + exit 0 fi case "$board" in @@ -104,18 +125,25 @@ apply_nss_config() { 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 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 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 + } diff --git a/package/kernel/mac80211/patches/nss/ath11k/068-ath11k-add-rx-histogram-stats.patch b/package/kernel/mac80211/patches/nss/ath11k/068-ath11k-add-rx-histogram-stats.patch new file mode 100644 index 00000000000000..c4b6d2339deea1 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/068-ath11k-add-rx-histogram-stats.patch @@ -0,0 +1,671 @@ +From 4635ca1f29bc5838d556b09e3c186b76a5198ddb Mon Sep 17 00:00:00 2001 +From: Manikanta Pubbisetty +Date: Fri, 18 Aug 2023 11:43:33 +0530 +Subject: [PATCH] ath11k: add rx histogram stats + +Adding rx rate table and byte level peer rx statistics. Also, +adding a debugfs knob to reset rx stats specific to the peer. + +Signed-off-by: Manikanta Pubbisetty +--- + drivers/net/wireless/ath/ath11k/core.h | 19 ++- + drivers/net/wireless/ath/ath11k/debugfs_sta.c | 152 ++++++++++++++++-- + drivers/net/wireless/ath/ath11k/dp_rx.c | 95 +++++++++-- + drivers/net/wireless/ath/ath11k/dp_rx.h | 19 +++ + drivers/net/wireless/ath/ath11k/hal_rx.c | 85 +++++++--- + drivers/net/wireless/ath/ath11k/hal_rx.h | 21 +++ + drivers/net/wireless/ath/ath11k/hw.c | 18 +++ + drivers/net/wireless/ath/ath11k/hw.h | 1 + + 8 files changed, 351 insertions(+), 59 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -41,6 +41,8 @@ + + #define ATH11K_INVALID_HW_MAC_ID 0xFF + #define ATH11K_CONNECTION_LOSS_HZ (3 * HZ) ++#define ATH11K_RX_RATE_TABLE_NUM 320 ++#define ATH11K_RX_RATE_TABLE_11AX_NUM 576 + + /* SMBIOS type containing Board Data File Name Extension */ + #define ATH11K_SMBIOS_BDF_EXT_TYPE 0xF8 +@@ -376,6 +378,17 @@ struct ath11k_vif_iter { + struct ath11k_vif *arvif; + }; + ++struct ath11k_rx_peer_rate_stats { ++ u64 ht_mcs_count[HAL_RX_MAX_MCS_HT + 1]; ++ u64 vht_mcs_count[HAL_RX_MAX_MCS_VHT + 1]; ++ u64 he_mcs_count[HAL_RX_MAX_MCS_HE + 1]; ++ u64 nss_count[HAL_RX_MAX_NSS]; ++ u64 bw_count[HAL_RX_BW_MAX]; ++ u64 gi_count[HAL_RX_GI_MAX]; ++ u64 legacy_count[HAL_RX_MAX_NUM_LEGACY_RATES]; ++ u64 rx_rate[ATH11K_RX_RATE_TABLE_11AX_NUM]; ++}; ++ + struct ath11k_rx_peer_stats { + u64 num_msdu; + u64 num_mpdu_fcs_ok; +@@ -387,10 +400,6 @@ struct ath11k_rx_peer_stats { + u64 non_ampdu_msdu_count; + u64 stbc_count; + u64 beamformed_count; +- u64 mcs_count[HAL_RX_MAX_MCS + 1]; +- u64 nss_count[HAL_RX_MAX_NSS]; +- u64 bw_count[HAL_RX_BW_MAX]; +- u64 gi_count[HAL_RX_GI_MAX]; + u64 coding_count[HAL_RX_SU_MU_CODING_MAX]; + u64 tid_count[IEEE80211_NUM_TIDS + 1]; + u64 pream_cnt[HAL_RX_PREAMBLE_MAX]; +@@ -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]; ++ struct ath11k_rx_peer_rate_stats pkt_stats; ++ struct ath11k_rx_peer_rate_stats byte_stats; + }; + + #define ATH11K_HE_MCS_NUM 12 +--- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c ++++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c +@@ -10,6 +10,7 @@ + #include "peer.h" + #include "debug.h" + #include "dp_tx.h" ++#include "dp_rx.h" + #include "debugfs_htt_stats.h" + + 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; +- const int size = 4096; ++ const int size = 4 * 4096; + char *buf; ++ int he_rates_avail = (rx_stats->pream_cnt[HAL_RX_PREAMBLE_11AX] > 1) ? 1 : 0; ++ int rate_table_len = he_rates_avail ? ATH11K_RX_RATE_TABLE_11AX_NUM : ++ ATH11K_RX_RATE_TABLE_NUM; ++ char *legacy_rate_str[] = {"1Mbps", "2Mbps", "5.5Mbps", "6Mbps", ++ "9Mbps", "11Mbps", "12Mbps", "18Mbps", ++ "24Mbps", "36 Mbps", "48Mbps", "54Mbps"}; + + if (!rx_stats) + return -ENOENT; +@@ -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); +- len += scnprintf(buf + len, size - len, +- "GI: 0.8us %llu 0.4us %llu 1.6us %llu 3.2us %llu\n", +- rx_stats->gi_count[0], rx_stats->gi_count[1], +- rx_stats->gi_count[2], rx_stats->gi_count[3]); +- len += scnprintf(buf + len, size - len, +- "BW: 20Mhz %llu 40Mhz %llu 80Mhz %llu 160Mhz %llu\n", +- rx_stats->bw_count[0], rx_stats->bw_count[1], +- rx_stats->bw_count[2], rx_stats->bw_count[3]); + 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, +@@ -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]); +- len += scnprintf(buf + len, size - len, "\nMCS(0-11) Legacy MCS(12):"); +- for (i = 0; i < HAL_RX_MAX_MCS + 1; i++) +- len += scnprintf(buf + len, size - len, "%llu ", rx_stats->mcs_count[i]); +- len += scnprintf(buf + len, size - len, "\nNSS(1-8):"); +- for (i = 0; i < HAL_RX_MAX_NSS; i++) +- len += scnprintf(buf + len, size - len, "%llu ", rx_stats->nss_count[i]); +- len += scnprintf(buf + len, size - len, "\nRX Duration:%llu ", ++ len += scnprintf(buf + len, size - len, "\nRX Duration:%llu\n", + rx_stats->rx_duration); ++ ++ len += scnprintf(buf + len, size - len, "\nRX success packet stats:\n"); ++ len += scnprintf(buf + len, size - len, "\nHE packet stats:\n"); ++ for (i = 0; i <= HAL_RX_MAX_MCS_HE; i++) ++ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, ++ rx_stats->pkt_stats.he_mcs_count[i], ++ (i + 1) % 6 ? "\t" : "\n"); ++ len += scnprintf(buf + len, size - len, "\nVHT packet stats:\n"); ++ for (i = 0; i <= HAL_RX_MAX_MCS_VHT; i++) ++ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, ++ rx_stats->pkt_stats.vht_mcs_count[i], ++ (i + 1) % 5 ? "\t" : "\n"); ++ len += scnprintf(buf + len, size - len, "\nHT packet stats:\n"); ++ for (i = 0; i <= HAL_RX_MAX_MCS_HT; i++) ++ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, ++ rx_stats->pkt_stats.ht_mcs_count[i], ++ (i + 1) % 8 ? "\t" : "\n"); ++ len += scnprintf(buf + len, size - len, "\nLegacy rate packet stats:\n"); ++ for (i = 0; i < HAL_RX_MAX_NUM_LEGACY_RATES; i++) ++ len += scnprintf(buf + len, size - len, "%s: %llu%s", legacy_rate_str[i], ++ rx_stats->pkt_stats.legacy_count[i], ++ (i + 1) % 4 ? "\t" : "\n"); ++ len += scnprintf(buf + len, size - len, "\nNSS packet stats:\n"); ++ for (i = 0; i < HAL_RX_MAX_NSS; i++) ++ len += scnprintf(buf + len, size - len, "%dx%d: %llu ", i + 1, i + 1, ++ rx_stats->pkt_stats.nss_count[i]); ++ len += scnprintf(buf + len, size - len, ++ "\n\nGI: 0.8us %llu 0.4us %llu 1.6us %llu 3.2us %llu\n", ++ rx_stats->pkt_stats.gi_count[0], ++ rx_stats->pkt_stats.gi_count[1], ++ rx_stats->pkt_stats.gi_count[2], ++ rx_stats->pkt_stats.gi_count[3]); ++ len += scnprintf(buf + len, size - len, ++ "BW: 20Mhz %llu 40Mhz %llu 80Mhz %llu 160Mhz %llu\n", ++ rx_stats->pkt_stats.bw_count[0], ++ rx_stats->pkt_stats.bw_count[1], ++ rx_stats->pkt_stats.bw_count[2], ++ rx_stats->pkt_stats.bw_count[3]); ++ len += scnprintf(buf + len, size - len, "\nRate Table (packets):\n"); ++ for (i = 0; i < rate_table_len; i++) ++ len += scnprintf(buf + len, size - len, "%10llu%s", ++ rx_stats->pkt_stats.rx_rate[i], ++ (i + 1) % (he_rates_avail ? 12 : 8) ? "\t" : "\n"); ++ ++ len += scnprintf(buf + len, size - len, "\nRX success byte stats:\n"); ++ len += scnprintf(buf + len, size - len, "\nHE byte stats:\n"); ++ for (i = 0; i <= HAL_RX_MAX_MCS_HE; i++) ++ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, ++ rx_stats->byte_stats.he_mcs_count[i], ++ (i + 1) % 6 ? "\t" : "\n"); ++ ++ len += scnprintf(buf + len, size - len, "\nVHT byte stats:\n"); ++ for (i = 0; i <= HAL_RX_MAX_MCS_VHT; i++) ++ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, ++ rx_stats->byte_stats.vht_mcs_count[i], ++ (i + 1) % 5 ? "\t" : "\n"); ++ len += scnprintf(buf + len, size - len, "\nHT byte stats:\n"); ++ for (i = 0; i <= HAL_RX_MAX_MCS_HT; i++) ++ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, ++ rx_stats->byte_stats.ht_mcs_count[i], ++ (i + 1) % 8 ? "\t" : "\n"); ++ len += scnprintf(buf + len, size - len, "\nLegacy rate byte stats:\n"); ++ for (i = 0; i < HAL_RX_MAX_NUM_LEGACY_RATES; i++) ++ len += scnprintf(buf + len, size - len, "%s: %llu%s", legacy_rate_str[i], ++ rx_stats->byte_stats.legacy_count[i], ++ (i + 1) % 4 ? "\t" : "\n"); ++ len += scnprintf(buf + len, size - len, "\nNSS byte stats:\n"); ++ for (i = 0; i < HAL_RX_MAX_NSS; i++) ++ len += scnprintf(buf + len, size - len, "%dx%d: %llu ", i + 1, i + 1, ++ rx_stats->byte_stats.nss_count[i]); ++ len += scnprintf(buf + len, size - len, ++ "\n\nGI: 0.8us %llu 0.4us %llu 1.6us %llu 3.2us %llu\n", ++ rx_stats->byte_stats.gi_count[0], ++ rx_stats->byte_stats.gi_count[1], ++ rx_stats->byte_stats.gi_count[2], ++ rx_stats->byte_stats.gi_count[3]); ++ len += scnprintf(buf + len, size - len, ++ "BW: 20Mhz %llu 40Mhz %llu 80Mhz %llu 160Mhz %llu\n", ++ rx_stats->byte_stats.bw_count[0], ++ rx_stats->byte_stats.bw_count[1], ++ rx_stats->byte_stats.bw_count[2], ++ rx_stats->byte_stats.bw_count[3]); ++ len += scnprintf(buf + len, size - len, "\nRate Table (bytes):\n"); ++ for (i = 0; i < rate_table_len; i++) ++ len += scnprintf(buf + len, size - len, "%10llu%s", ++ 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], +@@ -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 +@@ -2756,10 +2756,43 @@ exit: + return total_msdu_reaped; + } + ++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, ++ u32 num_msdu) ++{ ++ u32 rate_idx = 0; ++ u32 mcs_idx = ppdu_info->mcs; ++ u32 nss_idx = ppdu_info->nss - 1; ++ u32 bw_idx = ppdu_info->bw; ++ u32 gi_idx = ppdu_info->gi; ++ ++ if ((mcs_idx > HAL_RX_MAX_MCS_HE) || (nss_idx >= HAL_RX_MAX_NSS) || ++ (bw_idx >= HAL_RX_BW_MAX) || (gi_idx >= HAL_RX_GI_MAX)) { ++ return; ++ } ++ ++ if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11N || ++ ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC) { ++ rate_idx = mcs_idx * 8 + 8 * 10 * nss_idx; ++ rate_idx += bw_idx * 2 + gi_idx; ++ } else if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AX) { ++ gi_idx = ath11k_he_gi_to_nl80211_he_gi(ppdu_info->gi); ++ rate_idx = mcs_idx * 12 + 12 * 12 * nss_idx; ++ rate_idx += bw_idx * 3 + gi_idx; ++ } else { ++ return; ++ } ++ ++ rx_stats->pkt_stats.rx_rate[rate_idx] += num_msdu; ++ rx_stats->byte_stats.rx_rate[rate_idx] += ppdu_info->mpdu_len; ++} ++ + static void ath11k_dp_rx_update_peer_stats(struct ath11k_sta *arsta, + struct hal_rx_mon_ppdu_info *ppdu_info) + { + struct ath11k_rx_peer_stats *rx_stats = arsta->rx_stats; ++ struct ath11k *ar = arsta->arvif->ar; + u32 num_msdu; + int i; + +@@ -2769,6 +2802,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); + ++ if (!ath11k_debugfs_is_extd_rx_stats_enabled(ar)) ++ return; + num_msdu = ppdu_info->tcp_msdu_count + ppdu_info->tcp_ack_msdu_count + + ppdu_info->udp_msdu_count + ppdu_info->other_msdu_count; + +@@ -2785,18 +2820,6 @@ static void ath11k_dp_rx_update_peer_sta + ppdu_info->tid = IEEE80211_NUM_TIDS; + } + +- if (ppdu_info->nss > 0 && ppdu_info->nss <= HAL_RX_MAX_NSS) +- rx_stats->nss_count[ppdu_info->nss - 1] += num_msdu; +- +- if (ppdu_info->mcs <= HAL_RX_MAX_MCS) +- rx_stats->mcs_count[ppdu_info->mcs] += num_msdu; +- +- if (ppdu_info->gi < HAL_RX_GI_MAX) +- rx_stats->gi_count[ppdu_info->gi] += num_msdu; +- +- if (ppdu_info->bw < HAL_RX_BW_MAX) +- rx_stats->bw_count[ppdu_info->bw] += num_msdu; +- + if (ppdu_info->ldpc < HAL_RX_SU_MU_CODING_MAX) + rx_stats->coding_count[ppdu_info->ldpc] += num_msdu; + +@@ -2825,8 +2848,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; + +- arsta->rssi_comb = ppdu_info->rssi_comb; +- + BUILD_BUG_ON(ARRAY_SIZE(arsta->chain_signal) > + ARRAY_SIZE(ppdu_info->rssi_chain_pri20)); + +@@ -2835,6 +2856,52 @@ static void ath11k_dp_rx_update_peer_sta + + rx_stats->rx_duration += ppdu_info->rx_duration; + arsta->rx_duration = rx_stats->rx_duration; ++ ++ if (ppdu_info->nss > 0 && ppdu_info->nss <= HAL_RX_MAX_NSS) { ++ rx_stats->pkt_stats.nss_count[ppdu_info->nss - 1] += num_msdu; ++ rx_stats->byte_stats.nss_count[ppdu_info->nss - 1] += ppdu_info->mpdu_len; ++ } ++ ++ if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11N && ++ ppdu_info->mcs <= HAL_RX_MAX_MCS_HT) { ++ rx_stats->pkt_stats.ht_mcs_count[ppdu_info->mcs] += num_msdu; ++ rx_stats->byte_stats.ht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len; ++ /* To fit into rate table for HT packets */ ++ ppdu_info->mcs = ppdu_info->mcs % 8; ++ } ++ ++ if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC && ++ ppdu_info->mcs <= HAL_RX_MAX_MCS_VHT) { ++ rx_stats->pkt_stats.vht_mcs_count[ppdu_info->mcs] += num_msdu; ++ rx_stats->byte_stats.vht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len; ++ } ++ ++ if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AX && ++ ppdu_info->mcs <= HAL_RX_MAX_MCS_HE) { ++ rx_stats->pkt_stats.he_mcs_count[ppdu_info->mcs] += num_msdu; ++ rx_stats->byte_stats.he_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len; ++ } ++ ++ ++ if ((ppdu_info->preamble_type == HAL_RX_PREAMBLE_11A || ++ ppdu_info->preamble_type == HAL_RX_PREAMBLE_11B) && ++ ppdu_info->rate < HAL_RX_LEGACY_RATE_INVALID) { ++ rx_stats->pkt_stats.legacy_count[ppdu_info->rate] += num_msdu; ++ rx_stats->byte_stats.legacy_count[ppdu_info->rate] += ppdu_info->mpdu_len; ++ } ++ ++ if (ppdu_info->gi < HAL_RX_GI_MAX) { ++ rx_stats->pkt_stats.gi_count[ppdu_info->gi] += num_msdu; ++ rx_stats->byte_stats.gi_count[ppdu_info->gi] += ppdu_info->mpdu_len; ++ } ++ ++ if (ppdu_info->bw < HAL_RX_BW_MAX) { ++ rx_stats->pkt_stats.bw_count[ppdu_info->bw] += num_msdu; ++ rx_stats->byte_stats.bw_count[ppdu_info->bw] += ppdu_info->mpdu_len; ++ } ++ ++ ath11k_dp_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, num_msdu); ++ + } + + 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 +@@ -41,6 +41,25 @@ struct ath11k_dp_rfc1042_hdr { + __be16 snap_type; + } __packed; + ++static inline u32 ath11k_he_gi_to_nl80211_he_gi(u8 sgi) ++{ ++ u32 ret = 0; ++ ++ switch (sgi) { ++ case RX_MSDU_START_SGI_0_8_US: ++ ret = NL80211_RATE_INFO_HE_GI_0_8; ++ break; ++ case RX_MSDU_START_SGI_1_6_US: ++ ret = NL80211_RATE_INFO_HE_GI_1_6; ++ break; ++ case RX_MSDU_START_SGI_3_2_US: ++ ret = NL80211_RATE_INFO_HE_GI_3_2; ++ break; ++ } ++ ++ return ret; ++} ++ + int ath11k_dp_rx_ampdu_start(struct ath11k *ar, + struct ieee80211_ampdu_params *params); + 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 +@@ -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); +- ppdu_info->gi = info1 & HAL_RX_HT_SIG_INFO_INFO1_GI; +- +- switch (ppdu_info->mcs) { +- case 0 ... 7: +- ppdu_info->nss = 1; +- break; +- case 8 ... 15: +- ppdu_info->nss = 2; +- break; +- case 16 ... 23: +- ppdu_info->nss = 3; +- break; +- case 24 ... 31: +- ppdu_info->nss = 4; +- break; +- } +- +- if (ppdu_info->nss > 1) +- ppdu_info->mcs = ppdu_info->mcs % 8; +- ++ ppdu_info->gi = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO1_GI, info1); ++ ppdu_info->nss = (ppdu_info->mcs >> 3) + 1; + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; + break; + } + case HAL_PHYRX_L_SIG_B: { + struct hal_rx_lsig_b_info *lsigb = + (struct hal_rx_lsig_b_info *)tlv_data; ++ u8 rate; ++ ++ rate = FIELD_GET(HAL_RX_LSIG_B_INFO_INFO0_RATE, ++ __le32_to_cpu(lsigb->info0)); + +- ppdu_info->rate = FIELD_GET(HAL_RX_LSIG_B_INFO_INFO0_RATE, +- __le32_to_cpu(lsigb->info0)); ++ switch (rate) { ++ case 1: ++ rate = HAL_RX_LEGACY_RATE_1_MBPS; ++ break; ++ case 2: ++ case 5: ++ rate = HAL_RX_LEGACY_RATE_2_MBPS; ++ break; ++ case 3: ++ case 6: ++ rate = HAL_RX_LEGACY_RATE_5_5_MBPS; ++ break; ++ case 4: ++ case 7: ++ rate = HAL_RX_LEGACY_RATE_11_MBPS; ++ break; ++ default: ++ rate = HAL_RX_LEGACY_RATE_INVALID; ++ } ++ ppdu_info->rate = rate; + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; + break; + } + case HAL_PHYRX_L_SIG_A: { + struct hal_rx_lsig_a_info *lsiga = + (struct hal_rx_lsig_a_info *)tlv_data; ++ u8 rate; + +- ppdu_info->rate = FIELD_GET(HAL_RX_LSIG_A_INFO_INFO0_RATE, +- __le32_to_cpu(lsiga->info0)); ++ rate = FIELD_GET(HAL_RX_LSIG_A_INFO_INFO0_RATE, ++ __le32_to_cpu(lsiga->info0)); ++ switch (rate) { ++ case 8: ++ rate = HAL_RX_LEGACY_RATE_48_MBPS; ++ break; ++ case 9: ++ rate = HAL_RX_LEGACY_RATE_24_MBPS; ++ break; ++ case 10: ++ rate = HAL_RX_LEGACY_RATE_12_MBPS; ++ break; ++ case 11: ++ rate = HAL_RX_LEGACY_RATE_6_MBPS; ++ break; ++ case 12: ++ rate = HAL_RX_LEGACY_RATE_54_MBPS; ++ break; ++ case 13: ++ rate = HAL_RX_LEGACY_RATE_36_MBPS; ++ break; ++ case 14: ++ rate = HAL_RX_LEGACY_RATE_18_MBPS; ++ break; ++ case 15: ++ rate = HAL_RX_LEGACY_RATE_9_MBPS; ++ break; ++ default: ++ rate = HAL_RX_LEGACY_RATE_INVALID; ++ } ++ ppdu_info->rate = rate; + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; + break; + } +@@ -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; ++ ++ ppdu_info->mpdu_len += ab->hw_params.hw_ops->rx_desc_get_hal_mpdu_len(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 +@@ -19,7 +19,11 @@ struct hal_rx_wbm_rel_info { + #define VHT_SIG_SU_NSS_MASK 0x7 + + #define HAL_RX_MAX_MCS 12 ++#define HAL_RX_MAX_MCS_HT 31 ++#define HAL_RX_MAX_MCS_VHT 9 ++#define HAL_RX_MAX_MCS_HE 11 + #define HAL_RX_MAX_NSS 8 ++#define HAL_RX_MAX_NUM_LEGACY_RATES 12 + + struct hal_rx_mon_status_tlv_hdr { + u32 hdr; +@@ -103,6 +107,22 @@ struct hal_rx_user_status { + u32 mpdu_err_byte_count; + }; + ++enum hal_rx_legacy_rate { ++ HAL_RX_LEGACY_RATE_1_MBPS, ++ HAL_RX_LEGACY_RATE_2_MBPS, ++ HAL_RX_LEGACY_RATE_5_5_MBPS, ++ HAL_RX_LEGACY_RATE_6_MBPS, ++ HAL_RX_LEGACY_RATE_9_MBPS, ++ HAL_RX_LEGACY_RATE_11_MBPS, ++ HAL_RX_LEGACY_RATE_12_MBPS, ++ HAL_RX_LEGACY_RATE_18_MBPS, ++ HAL_RX_LEGACY_RATE_24_MBPS, ++ HAL_RX_LEGACY_RATE_36_MBPS, ++ HAL_RX_LEGACY_RATE_48_MBPS, ++ HAL_RX_LEGACY_RATE_54_MBPS, ++ HAL_RX_LEGACY_RATE_INVALID, ++}; ++ + #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 +@@ -127,6 +147,7 @@ struct hal_rx_mon_ppdu_info { + u32 num_mpdu_fcs_ok; + u32 num_mpdu_fcs_err; + u32 preamble_type; ++ u32 mpdu_len; + u16 chan_num; + u16 tcp_msdu_count; + u16 tcp_ack_msdu_count; +--- a/drivers/net/wireless/ath/ath11k/hw.c ++++ b/drivers/net/wireless/ath/ath11k/hw.c +@@ -900,6 +900,17 @@ static u32 ath11k_hw_wcn6750_get_tcl_rin + return skb_get_hash(skb); + } + ++static u32 ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len(struct hal_rx_mpdu_info *mpdu_info) ++{ ++ return FIELD_GET(HAL_RX_MPDU_INFO_INFO1_MPDU_LEN, ++ __le32_to_cpu(mpdu_info->u.ipq8074.info1)); ++} ++ ++static u32 ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_len(struct hal_rx_mpdu_info *mpdu_info) ++{ ++ return FIELD_GET(HAL_RX_MPDU_INFO_INFO1_MPDU_LEN, ++ __le32_to_cpu(mpdu_info->u.qcn9074.info1)); ++} + 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, +@@ -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, + }; + + 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, ++ .rx_desc_get_hal_mpdu_len = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len, + }; + + 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, ++ .rx_desc_get_hal_mpdu_len = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len, + }; + + const struct ath11k_hw_ops qcn9074_ops = { +@@ -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 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, ++ .rx_desc_get_hal_mpdu_len = ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_len, + }; + + #define ATH11K_TX_RING_MASK_0 BIT(0) +--- a/drivers/net/wireless/ath/ath11k/hw.h ++++ b/drivers/net/wireless/ath/ath11k/hw.h +@@ -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); + }; + + extern const struct ath11k_hw_ops ipq8074_ops; diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index c0ecee94867c73..5c29297c3363f8 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -23,7 +23,7 @@ Signed-off-by: Miles Hu #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) -@@ -458,6 +459,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 { -@@ -465,6 +468,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 { -@@ -581,11 +587,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; @@ -181,7 +181,7 @@ Signed-off-by: Miles Hu if (!arsta->tx_stats) return -ENOENT; -@@ -162,45 +237,46 @@ static ssize_t ath11k_dbg_sta_dump_tx_st +@@ -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, -@@ -209,10 +285,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); -@@ -220,6 +354,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); @@ -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); -@@ -1560,13 +1579,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; -@@ -1601,6 +1694,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; } 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 00000000000000..d5e6ec621fcbb3 --- /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 +@@ -26,10 +26,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))"); + + struct ath11k_base *ath11k_soc[MAX_SOCS]; + 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 00000000000000..6a96689002eedb --- /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 +@@ -1480,6 +1480,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 +@@ -1489,6 +1490,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 +@@ -408,6 +408,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/nss/ath11k/107-ath11k-tid-counter-fix.patch b/package/kernel/mac80211/patches/nss/ath11k/107-ath11k-tid-counter-fix.patch deleted file mode 100644 index 1826e64bbcba05..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/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/nss/ath11k/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 new file mode 100644 index 00000000000000..c9dc6912d0d185 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch @@ -0,0 +1,452 @@ +--- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c ++++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c +@@ -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"); ++ len += scnprintf(buf + len, size - len, ++ "\nDCM: %llu\nRU26: %llu \nRU52: %llu \nRU106: %llu \nRU242: %llu \nRU484: %llu \nRU996: %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"); + +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -2893,11 +2893,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, ++ struct hal_rx_user_status* user_stats, + u32 num_msdu) + { + u32 rate_idx = 0; +- u32 mcs_idx = ppdu_info->mcs; +- u32 nss_idx = ppdu_info->nss - 1; ++ u32 mcs_idx = (user_stats) ? user_stats->mcs : ppdu_info->mcs; ++ u32 nss_idx = (user_stats) ? user_stats->nss - 1 : ppdu_info->nss - 1; + u32 bw_idx = ppdu_info->bw; + u32 gi_idx = ppdu_info->gi; + +@@ -2919,10 +2920,13 @@ ath11k_dp_rx_update_peer_rate_table_stat + } + + rx_stats->pkt_stats.rx_rate[rate_idx] += num_msdu; +- rx_stats->byte_stats.rx_rate[rate_idx] += ppdu_info->mpdu_len; ++ if (user_stats) ++ rx_stats->byte_stats.rx_rate[rate_idx] += user_stats->mpdu_ok_byte_count; ++ else ++ rx_stats->byte_stats.rx_rate[rate_idx] += ppdu_info->mpdu_len; + } + +-static void ath11k_dp_rx_update_peer_stats(struct ath11k_sta *arsta, ++static void ath11k_dp_rx_update_peer_su_stats(struct ath11k_sta *arsta, + struct hal_rx_mon_ppdu_info *ppdu_info) + { + struct ath11k_rx_peer_stats *rx_stats = arsta->rx_stats; +@@ -2980,7 +2984,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; +- rx_stats->ru_alloc_cnt[ppdu_info->ru_alloc] += num_msdu; + + BUILD_BUG_ON(ARRAY_SIZE(arsta->chain_signal) > + ARRAY_SIZE(ppdu_info->rssi_chain_pri20)); +@@ -2998,10 +3001,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) { +- rx_stats->pkt_stats.ht_mcs_count[ppdu_info->mcs] += num_msdu; +- rx_stats->byte_stats.ht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len; +- /* To fit into rate table for HT packets */ +- ppdu_info->mcs = ppdu_info->mcs % 8; ++ rx_stats->pkt_stats.ht_mcs_count[ppdu_info->mcs] += num_msdu; ++ rx_stats->byte_stats.ht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len; ++ /* To fit into rate table for HT packets */ ++ ppdu_info->mcs = ppdu_info->mcs % 8; + } + + if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC && +@@ -3034,7 +3037,120 @@ static void ath11k_dp_rx_update_peer_sta + rx_stats->byte_stats.bw_count[ppdu_info->bw] += ppdu_info->mpdu_len; + } + +- ath11k_dp_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, num_msdu); ++ ath11k_dp_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, NULL, num_msdu); ++ ++} ++ ++static void ath11k_dp_rx_update_user_stats(struct ath11k *ar, ++ struct hal_rx_mon_ppdu_info *ppdu_info, ++ u32 uid) ++{ ++ struct ath11k_sta *arsta = NULL; ++ struct ath11k_rx_peer_stats *rx_stats = NULL; ++ struct hal_rx_user_status* user_stats = &ppdu_info->userstats[uid]; ++ struct ath11k_peer *peer; ++ u32 num_msdu; ++ ++ if (user_stats->ast_index == 0 || user_stats->ast_index == 0xFFFF) ++ return; ++ ++ peer = ath11k_peer_find_by_ast(ar->ab, user_stats->ast_index); ++ ++ if (peer == NULL) { ++ ath11k_warn(ar->ab, "peer ast idx %d can't be found\n", ++ user_stats->ast_index); ++ return; ++ } ++ ++ arsta = (struct ath11k_sta *)peer->sta->drv_priv; ++ rx_stats = arsta->rx_stats; ++ ++ if (!rx_stats) ++ return; ++ ++ arsta->rssi_comb = ppdu_info->rssi_comb; ++ ++ num_msdu = user_stats->tcp_msdu_count + user_stats->tcp_ack_msdu_count + ++ user_stats->udp_msdu_count + user_stats->other_msdu_count; ++ ++ rx_stats->num_msdu += num_msdu; ++ rx_stats->tcp_msdu_count += user_stats->tcp_msdu_count + ++ user_stats->tcp_ack_msdu_count; ++ rx_stats->udp_msdu_count += user_stats->udp_msdu_count; ++ rx_stats->other_msdu_count += user_stats->other_msdu_count; ++ ++ if (ppdu_info->ldpc < HAL_RX_SU_MU_CODING_MAX) ++ rx_stats->coding_count[ppdu_info->ldpc] += num_msdu; ++ ++ if (user_stats->tid <= IEEE80211_NUM_TIDS) ++ rx_stats->tid_count[user_stats->tid] += num_msdu; ++ ++ if (user_stats->preamble_type < HAL_RX_PREAMBLE_MAX) ++ rx_stats->pream_cnt[user_stats->preamble_type] += num_msdu; ++ ++ if (ppdu_info->reception_type < HAL_RX_RECEPTION_TYPE_MAX) ++ rx_stats->reception_type[ppdu_info->reception_type] += num_msdu; ++ ++ if (ppdu_info->is_stbc) ++ rx_stats->stbc_count += num_msdu; ++ ++ if (ppdu_info->beamformed) ++ rx_stats->beamformed_count += num_msdu; ++ ++ if (user_stats->mpdu_cnt_fcs_ok > 1) ++ rx_stats->ampdu_msdu_count += num_msdu; ++ else ++ rx_stats->non_ampdu_msdu_count += num_msdu; ++ ++ rx_stats->num_mpdu_fcs_ok += user_stats->mpdu_cnt_fcs_ok; ++ rx_stats->num_mpdu_fcs_err += user_stats->mpdu_cnt_fcs_err; ++ rx_stats->dcm_count += ppdu_info->dcm; ++ if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA || ++ ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO) ++ rx_stats->ru_alloc_cnt[user_stats->ul_ofdma_ru_size] += num_msdu; ++ ++ rx_stats->rx_duration += ppdu_info->rx_duration; ++ arsta->rx_duration = rx_stats->rx_duration; ++ ++ if (user_stats->nss > 0 && user_stats->nss <= HAL_RX_MAX_NSS) { ++ rx_stats->pkt_stats.nss_count[user_stats->nss - 1] += num_msdu; ++ rx_stats->byte_stats.nss_count[user_stats->nss - 1] += user_stats->mpdu_ok_byte_count; ++ } ++ ++ if (user_stats->preamble_type == HAL_RX_PREAMBLE_11AX && ++ user_stats->mcs <= HAL_RX_MAX_MCS_HE) { ++ rx_stats->pkt_stats.he_mcs_count[user_stats->mcs] += num_msdu; ++ rx_stats->byte_stats.he_mcs_count[user_stats->mcs] += user_stats->mpdu_ok_byte_count; ++ } ++ ++ if (ppdu_info->gi < HAL_RX_GI_MAX) { ++ rx_stats->pkt_stats.gi_count[ppdu_info->gi] += num_msdu; ++ rx_stats->byte_stats.gi_count[ppdu_info->gi] += user_stats->mpdu_ok_byte_count; ++ } ++ ++ if (ppdu_info->bw < HAL_RX_BW_MAX) { ++ rx_stats->pkt_stats.bw_count[ppdu_info->bw] += num_msdu; ++ rx_stats->byte_stats.bw_count[ppdu_info->bw] += user_stats->mpdu_ok_byte_count; ++ } ++ ++ ath11k_dp_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, user_stats, num_msdu); ++} ++ ++static void ath11k_dp_rx_update_peer_mu_stats(struct ath11k *ar, ++ struct hal_rx_mon_ppdu_info *ppdu_info) ++{ ++ u32 num_users, i; ++ ++ if (!ath11k_debugfs_is_extd_rx_stats_enabled(ar)) ++ return; ++ ++ num_users = ppdu_info->num_users; ++ if (num_users > HAL_MAX_UL_MU_USERS) ++ num_users = HAL_MAX_UL_MU_USERS; ++ ++ for (i = 0; i < num_users; i++) { ++ ath11k_dp_rx_update_user_stats(ar, ppdu_info, i); ++ } + + } + +@@ -5372,6 +5488,55 @@ static void ath11k_dp_rx_mon_dest_proces + } + } + ++void ath11k_dp_rx_mon_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info) ++{ ++ struct hal_rx_user_status *rx_user_status; ++ u32 num_users; ++ uint32_t i; ++ uint32_t mu_ul_user_v0_word0; ++ uint32_t mu_ul_user_v0_word1; ++ uint32_t ru_size; ++ ++ if (!(ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA || ++ ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO)) ++ return; ++ ++ num_users = ppdu_info->num_users; ++ if (num_users > HAL_MAX_UL_MU_USERS) ++ num_users = HAL_MAX_UL_MU_USERS; ++ ++ for (i = 0; i < num_users; i++) { ++ rx_user_status = &ppdu_info->userstats[i]; ++ mu_ul_user_v0_word0 = ++ rx_user_status->ul_ofdma_user_v0_word0; ++ mu_ul_user_v0_word1 = ++ rx_user_status->ul_ofdma_user_v0_word1; ++ ++ if (FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID, ++ mu_ul_user_v0_word0) && ++ !FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VER, ++ mu_ul_user_v0_word0)) { ++ rx_user_status->mcs = ++ FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_MCS, ++ mu_ul_user_v0_word1); ++ rx_user_status->nss = ++ FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_NSS, ++ mu_ul_user_v0_word1) + 1; ++ ++ rx_user_status->ofdma_info_valid = 1; ++ rx_user_status->ul_ofdma_ru_start_index = ++ FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_START, ++ mu_ul_user_v0_word1); ++ ++ ru_size = FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE, ++ mu_ul_user_v0_word1); ++ rx_user_status->ul_ofdma_ru_width = ru_size; ++ rx_user_status->ul_ofdma_ru_size = ru_size; ++ } ++ } ++ ++} ++ + int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id, + struct napi_struct *napi, int budget) + { +@@ -5445,8 +5610,13 @@ int ath11k_dp_rx_process_mon_status(stru + + 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); ++ 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)) +--- a/drivers/net/wireless/ath/ath11k/hal_rx.c ++++ b/drivers/net/wireless/ath/ath11k/hal_rx.c +@@ -804,7 +804,6 @@ void ath11k_hal_reo_init_cmd_ring(struct + } + } + +-#define HAL_MAX_UL_MU_USERS 37 + static inline void + ath11k_hal_rx_handle_ofdma_info(void *rx_tlv, + struct hal_rx_user_status *rx_user_status) +@@ -836,6 +835,8 @@ ath11k_hal_rx_populate_mu_user_info(void + { + rx_user_status->ast_index = ppdu_info->ast_index; + rx_user_status->tid = ppdu_info->tid; ++ rx_user_status->tcp_ack_msdu_count = ++ ppdu_info->tcp_ack_msdu_count; + rx_user_status->tcp_msdu_count = + ppdu_info->tcp_msdu_count; + rx_user_status->udp_msdu_count = +@@ -859,6 +860,9 @@ ath11k_hal_rx_populate_mu_user_info(void + ppdu_info->num_mpdu_fcs_ok; + rx_user_status->mpdu_cnt_fcs_err = + ppdu_info->num_mpdu_fcs_err; ++ memcpy(&rx_user_status->mpdu_fcs_ok_bitmap[0], &ppdu_info->mpdu_fcs_ok_bitmap[0], ++ HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * ++ sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0])); + + ath11k_hal_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status); + } +@@ -888,6 +892,14 @@ ath11k_hal_rx_parse_mon_status_tlv(struc + __le32_to_cpu(ppdu_start->info0)); + ppdu_info->chan_num = __le32_to_cpu(ppdu_start->chan_num); + ppdu_info->ppdu_ts = __le32_to_cpu(ppdu_start->ppdu_start_ts); ++ ++ if (ppdu_info->ppdu_id != ppdu_info->last_ppdu_id) { ++ ppdu_info->last_ppdu_id = ppdu_info->ppdu_id; ++ ppdu_info->num_users = 0; ++ memset(&ppdu_info->mpdu_fcs_ok_bitmap, 0, ++ HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * ++ sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0])); ++ } + break; + } + case HAL_RX_PPDU_END_USER_STATS: { +@@ -942,15 +954,16 @@ ath11k_hal_rx_parse_mon_status_tlv(struc + + if (userid < HAL_MAX_UL_MU_USERS) { + struct hal_rx_user_status *rxuser_stats = +- &ppdu_info->userstats; ++ &ppdu_info->userstats[userid]; ++ ppdu_info->num_users += 1; + + ath11k_hal_rx_handle_ofdma_info(tlv_data, rxuser_stats); + ath11k_hal_rx_populate_mu_user_info(tlv_data, ppdu_info, + rxuser_stats); + } +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[0] = ++ ppdu_info->mpdu_fcs_ok_bitmap[0] = + __le32_to_cpu(eu_stats->rsvd1[0]); +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[1] = ++ ppdu_info->mpdu_fcs_ok_bitmap[1] = + __le32_to_cpu(eu_stats->rsvd1[1]); + + break; +@@ -958,12 +971,12 @@ ath11k_hal_rx_parse_mon_status_tlv(struc + case HAL_RX_PPDU_END_USER_STATS_EXT: { + struct hal_rx_ppdu_end_user_stats_ext *eu_stats = + (struct hal_rx_ppdu_end_user_stats_ext *)tlv_data; +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[2] = eu_stats->info1; +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[3] = eu_stats->info2; +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[4] = eu_stats->info3; +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[5] = eu_stats->info4; +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[6] = eu_stats->info5; +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[7] = eu_stats->info6; ++ ppdu_info->mpdu_fcs_ok_bitmap[2] = eu_stats->info1; ++ ppdu_info->mpdu_fcs_ok_bitmap[3] = eu_stats->info2; ++ ppdu_info->mpdu_fcs_ok_bitmap[4] = eu_stats->info3; ++ ppdu_info->mpdu_fcs_ok_bitmap[5] = eu_stats->info4; ++ ppdu_info->mpdu_fcs_ok_bitmap[6] = eu_stats->info5; ++ ppdu_info->mpdu_fcs_ok_bitmap[7] = eu_stats->info6; + break; + } + case HAL_PHYRX_HT_SIG: { +--- a/drivers/net/wireless/ath/ath11k/hal_rx.h ++++ b/drivers/net/wireless/ath/ath11k/hal_rx.h +@@ -72,6 +72,10 @@ enum hal_rx_reception_type { + #define HAL_RX_FCS_LEN 4 + #define HAL_AST_IDX_INVALID 0xFFFF + ++#define HAL_MAX_UL_MU_USERS 37 ++#define HAL_RX_MAX_MPDU 256 ++#define HAL_RX_NUM_WORDS_PER_PPDU_BITMAP (HAL_RX_MAX_MPDU >> 5) ++ + enum hal_rx_mon_status { + HAL_RX_MON_STATUS_PPDU_NOT_DONE, + HAL_RX_MON_STATUS_PPDU_DONE, +@@ -82,14 +86,15 @@ struct hal_rx_user_status { + u32 mcs:4, + nss:3, + ofdma_info_valid:1, +- dl_ofdma_ru_start_index:7, +- dl_ofdma_ru_width:7, +- dl_ofdma_ru_size:8; ++ ul_ofdma_ru_start_index:7, ++ ul_ofdma_ru_width:7, ++ ul_ofdma_ru_size:8; + u32 ul_ofdma_user_v0_word0; + u32 ul_ofdma_user_v0_word1; + u32 ast_index; + u32 tid; + u16 tcp_msdu_count; ++ u16 tcp_ack_msdu_count; + u16 udp_msdu_count; + u16 other_msdu_count; + u16 frame_control; +@@ -103,7 +108,7 @@ struct hal_rx_user_status { + u8 rs_flags; + u32 mpdu_cnt_fcs_ok; + u32 mpdu_cnt_fcs_err; +- u32 mpdu_fcs_ok_bitmap[8]; ++ u32 mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP]; + u32 mpdu_ok_byte_count; + u32 mpdu_err_byte_count; + }; +@@ -144,6 +149,7 @@ struct hal_sw_mon_ring_entries { + + struct hal_rx_mon_ppdu_info { + u32 ppdu_id; ++ u32 last_ppdu_id; + u32 ppdu_ts; + u32 num_mpdu_fcs_ok; + u32 num_mpdu_fcs_err; +@@ -212,9 +218,20 @@ struct hal_rx_mon_ppdu_info { + u8 ltf_size; + u8 rxpcu_filter_pass; + char rssi_chain[8][8]; +- struct hal_rx_user_status userstats; ++ 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]; + }; + ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID BIT(30) ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VER BIT(31) ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_NSS GENMASK(2, 0) ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_MCS GENMASK(6, 3) ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_LDPC BIT(7) ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_DCM BIT(8) ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_START GENMASK(15, 9) ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE GENMASK(18, 16) ++ + #define HAL_RX_PPDU_START_INFO0_PPDU_ID GENMASK(15, 0) + + struct hal_rx_ppdu_start { +--- a/drivers/net/wireless/ath/ath11k/peer.c ++++ b/drivers/net/wireless/ath/ath11k/peer.c +@@ -93,6 +93,20 @@ struct ath11k_peer *ath11k_peer_find_by_ + return NULL; + } + ++struct ath11k_peer *ath11k_peer_find_by_ast(struct ath11k_base *ab, ++ int ast_hash) ++{ ++ struct ath11k_peer *peer; ++ ++ lockdep_assert_held(&ab->base_lock); ++ ++ list_for_each_entry(peer, &ab->peers, list) ++ if (ast_hash == peer->ast_hash) ++ return peer; ++ ++ return NULL; ++} ++ + 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 +@@ -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); ++struct ath11k_peer *ath11k_peer_find_by_ast(struct ath11k_base *ab, int ast_hash); + void ath11k_peer_cleanup(struct ath11k *ar, u32 vdev_id); + int ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, u8 *addr); + int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 32f261cfb8de76..c39580e79e1a43 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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(); @@ -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 -@@ -924,6 +924,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/nss/ath11k/199-003-ath11k-add-nss-support.patch b/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch index 7d10aaf6e9cedb..2f043fd65c86b9 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch @@ -164,7 +164,7 @@ Signed-off-by: Sriram R #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) -@@ -382,6 +383,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 { -@@ -526,6 +530,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 */ -@@ -621,6 +628,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; -@@ -838,6 +848,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 { -@@ -879,9 +890,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; -@@ -2027,7 +2030,7 @@ static void ath11k_dp_rx_h_csum_offload( +@@ -2029,7 +2032,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) { -@@ -2054,7 +2057,7 @@ static int ath11k_dp_rx_crypto_mic_len(s +@@ -2056,7 +2059,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) { -@@ -2082,7 +2085,7 @@ static int ath11k_dp_rx_crypto_param_len +@@ -2084,7 +2087,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) { -@@ -5373,7 +5376,7 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -2820,6 +2823,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) + { +@@ -3127,6 +3146,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; + +@@ -3203,8 +3229,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) +@@ -5607,7 +5635,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; +@@ -5675,6 +5703,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 @@ @@ -496,7 +562,7 @@ Signed-off-by: Sriram R +static void ath11k_mac_op_nss_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, -+ u64 changed) ++ u32 changed) +{ + struct ath11k *ar = hw->priv; + struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); @@ -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,14 +826,6 @@ 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 @@ -28,6 +28,7 @@ struct ath11k_peer { @@ -811,17 +869,18 @@ Signed-off-by: Sriram R } ar->debug.rx_filter = tlv_filter.rx_filter; -@@ -2001,6 +2001,75 @@ 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) { @@ -829,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); @@ -884,9 +943,21 @@ Signed-off-by: Sriram R + .llseek = default_llseek, +}; + - void ath11k_debugfs_add_interface(struct ath11k_vif *arvif) + int ath11k_debugfs_register(struct ath11k *ar) { - struct ath11k_base *ab = arvif->ar->ab; + 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); ++ + return 0; + } + --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c @@ -12,7 +12,7 @@ @@ -920,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, @@ -929,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; } @@ -945,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; @@ -968,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; @@ -976,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; @@ -986,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/207-ath11k-Enable-256_512MB-profiles.patch b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch index d43143c76e8017..d18b213cf27607 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -875,6 +875,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; -@@ -1028,6 +1033,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 @@ -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,7 +228,7 @@ Signed-off-by: Ramya Gnanasekar static struct ath11k_hw_params ath11k_hw_params[] = { { .hw_rev = ATH11K_HW_IPQ8074, -@@ -95,7 +99,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -95,7 +97,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = true, @@ -267,25 +237,15 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = false, -@@ -103,7 +107,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 = false, - .alloc_cacheable_memory = true, -@@ -127,6 +130,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 +@@ -177,7 +180,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = true, .coldboot_cal_ftm = true, .cbcal_restart_fw = true, @@ -294,7 +254,7 @@ Signed-off-by: Ramya Gnanasekar .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, @@ -303,7 +263,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, @@ -312,7 +272,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, @@ -321,7 +289,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, @@ -330,7 +306,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, @@ -339,11 +315,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), @@ -356,11 +335,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); + }, + }; diff --git a/package/kernel/mac80211/patches/nss/ath11k/211-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 index 6bf3cb5c797e60..016ace4edd7501 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/211-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 -@@ -631,6 +631,7 @@ struct ath11k { +@@ -642,6 +642,7 @@ struct ath11k { struct ath11k_pdev_wmi *wmi; #ifdef CPTCFG_ATH11K_NSS_SUPPORT struct ath11k_nss nss; @@ -34,12 +34,13 @@ Signed-off-by: Sathishkumar Muruganandam #endif struct ath11k_pdev_dp dp; u8 mac_addr[ETH_ALEN]; -@@ -1036,6 +1037,8 @@ struct ath11k_base { - atomic_t num_max_allowed; - struct ath11k_num_vdevs_peers *num_vdevs_peers; +@@ -1042,6 +1043,9 @@ struct ath11k_base { + } testmode; + #endif + u32 max_ast_index; + u32 num_ast_entries; ++ /* must be last */ u8 drv_priv[] __aligned(sizeof(void *)); }; @@ -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,7 +613,7 @@ Signed-off-by: Sathishkumar Muruganandam struct ath11k_sta *arsta; int ret, fbret; -@@ -452,6 +867,12 @@ int ath11k_peer_create(struct ath11k *ar +@@ -466,6 +881,13 @@ int ath11k_peer_create(struct ath11k *ar peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; peer->vif = arvif->vif; @@ -622,9 +623,10 @@ Signed-off-by: Sathishkumar Muruganandam + 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 @@ -18,6 +18,47 @@ struct ppdu_user_delayba { @@ -700,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, -@@ -72,4 +122,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); diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index f8ebc65fbaa3cc..59816b1883be1d 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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,131 +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,71 +92,71 @@ 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" }, - [WMI_TAG_WDS_ADDR_EVENT] = { -- .min_len = sizeof(struct wmi_wds_addr_event) }, -+ .min_len = sizeof(struct wmi_wds_addr_event), .policy = "wmi_wds_addr_event" }, - }; - - #define PRIMAP(_hw_mode_) \ -@@ -205,8 +206,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; - } -@@ -701,6 +702,55 @@ int ath11k_wmi_mgmt_send(struct ath11k * +@@ -699,6 +699,55 @@ int ath11k_wmi_mgmt_send(struct ath11k * return ret; } @@ -262,7 +147,7 @@ Signed-off-by: Sowmiya Sree Elavalagan int ath11k_wmi_vdev_create(struct ath11k *ar, u8 *macaddr, struct vdev_create_params *param) { -@@ -5904,8 +5954,8 @@ static int ath11k_pull_mgmt_rx_params_tl +@@ -5857,8 +5906,8 @@ static int ath11k_pull_mgmt_rx_params_tl return 0; } @@ -273,7 +158,7 @@ Signed-off-by: Sowmiya Sree Elavalagan { struct sk_buff *msdu; struct ieee80211_tx_info *info; -@@ -5943,6 +5993,11 @@ static int wmi_process_mgmt_tx_comp(stru +@@ -5896,6 +5945,11 @@ static int wmi_process_mgmt_tx_comp(stru info->status.ack_signal = tx_compl_param->ack_rssi; } @@ -285,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); -@@ -5961,10 +6016,13 @@ static int wmi_process_mgmt_tx_comp(stru +@@ -5914,10 +5968,13 @@ static int wmi_process_mgmt_tx_comp(stru arvif = ath11k_vif_to_arvif(vif); mgmt_stats = &arvif->mgmt_stats; @@ -303,7 +188,7 @@ Signed-off-by: Sowmiya Sree Elavalagan spin_unlock_bh(&ar->data_lock); skip_mgmt_stats: -@@ -5986,12 +6044,13 @@ skip_mgmt_stats: +@@ -5939,12 +5996,13 @@ skip_mgmt_stats: return 0; } @@ -321,7 +206,7 @@ Signed-off-by: Sowmiya Sree Elavalagan int ret; tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); -@@ -6001,7 +6060,7 @@ static int ath11k_pull_mgmt_tx_compl_par +@@ -5954,7 +6012,7 @@ static int ath11k_pull_mgmt_tx_compl_par return ret; } @@ -330,7 +215,7 @@ Signed-off-by: Sowmiya Sree Elavalagan if (!ev) { ath11k_warn(ab, "failed to fetch mgmt tx compl ev"); kfree(tb); -@@ -7809,10 +7868,11 @@ exit: +@@ -7731,10 +7789,11 @@ exit: static void ath11k_mgmt_tx_compl_event(struct ath11k_base *ab, struct sk_buff *skb) { @@ -344,7 +229,7 @@ Signed-off-by: Sowmiya Sree Elavalagan ath11k_warn(ab, "failed to extract mgmt tx compl event"); return; } -@@ -7825,7 +7885,7 @@ static void ath11k_mgmt_tx_compl_event(s +@@ -7747,7 +7806,7 @@ static void ath11k_mgmt_tx_compl_event(s goto exit; } @@ -353,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", -@@ -7836,6 +7896,36 @@ exit: +@@ -7758,6 +7817,36 @@ exit: rcu_read_unlock(); } @@ -390,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) -@@ -8941,6 +9031,9 @@ static void ath11k_wmi_tlv_op_rx(struct - case WMI_WDS_PEER_EVENTID: - ath11k_wmi_wds_peer_event(ab, skb); +@@ -8844,6 +8933,10 @@ 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_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; @@ -419,16 +305,16 @@ Signed-off-by: Sowmiya Sree Elavalagan WMI_TX_DELBA_COMPLETE_EVENTID = WMI_TLV_CMD(WMI_GRP_BA_NEG), WMI_TX_ADDBA_COMPLETE_EVENTID, WMI_BA_RSP_SSN_EVENTID, -@@ -1880,6 +1883,9 @@ enum wmi_tlv_tag { +@@ -1878,6 +1881,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 { WMI_TLV_SERVICE_PEER_POWER_SAVE_DURATION_SUPPORT = 246, WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT = 249, @@ -447,7 +333,7 @@ Signed-off-by: Sowmiya Sree Elavalagan /* The second 128 bits */ WMI_MAX_EXT_SERVICE = 256, -@@ -3829,6 +3845,7 @@ struct wmi_scan_prob_req_oui_cmd { +@@ -3814,6 +3830,7 @@ struct wmi_scan_prob_req_oui_cmd { } __packed; #define WMI_MGMT_SEND_DOWNLD_LEN 64 @@ -455,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) -@@ -3839,9 +3856,10 @@ struct wmi_scan_prob_req_oui_cmd { +@@ -3824,9 +3841,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) @@ -468,7 +354,7 @@ Signed-off-by: Sowmiya Sree Elavalagan u32 tlv_header; u32 tx_params_dword0; u32 tx_params_dword1; -@@ -4947,7 +4965,7 @@ struct wmi_rssi_ctl_ext { +@@ -4917,7 +4935,7 @@ struct wmi_rssi_ctl_ext { u32 rssi_ctl_ext[MAX_ANTENNA_EIGHT - ATH_MAX_ANTENNA]; }; @@ -477,7 +363,7 @@ Signed-off-by: Sowmiya Sree Elavalagan u32 desc_id; u32 status; u32 pdev_id; -@@ -5778,6 +5796,17 @@ struct wmi_debug_log_config_cmd_fixed_pa +@@ -5748,6 +5766,17 @@ struct wmi_debug_log_config_cmd_fixed_pa u32 value; } __packed; @@ -495,7 +381,7 @@ Signed-off-by: Sowmiya Sree Elavalagan #define WMI_MAX_MEM_REQS 32 #define MAX_RADIOS 3 -@@ -6388,6 +6417,8 @@ int ath11k_wmi_cmd_send(struct ath11k_pd +@@ -6358,6 +6387,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/nss/ath11k/218-ath11k-add-support-to-enable-disable-color-collision.patch b/package/kernel/mac80211/patches/nss/ath11k/218-ath11k-add-support-to-enable-disable-color-collision.patch new file mode 100644 index 00000000000000..24520cbeafbc7a --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/218-ath11k-add-support-to-enable-disable-color-collision.patch @@ -0,0 +1,46 @@ +From ee8c401bdfa08c6b98fb5b016841db5603ba4059 Mon Sep 17 00:00:00 2001 +From: Lavanya Suresh +Date: Wed, 23 Sep 2020 21:54:34 +0530 +Subject: [PATCH] ath11k: add support to enable/disable bss color collision + detection + +Added module param to enable or disable bss color collision detection. +By default, it is disabled. This config should be changed before VAP +bringup only. + + +Signed-off-by: Lavanya Suresh +--- + drivers/net/wireless/ath/ath11k/mac.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -53,6 +54,10 @@ + .max_power = 30, \ + } + ++unsigned int color_collision_enable = 0; ++module_param_named(color_collision_detect, color_collision_enable, uint, 0644); ++MODULE_PARM_DESC(color_collision_detect, "BSS color collision detecion: 0-disable 1-enable"); ++ + static const struct ieee80211_channel ath11k_2ghz_channels[] = { + CHAN2G(1, 2412, 0), + CHAN2G(2, 2417, 0), +@@ -3723,7 +3728,7 @@ static void ath11k_mac_op_bss_info_chang + ret = ath11k_wmi_send_obss_color_collision_cfg_cmd( + ar, arvif->vdev_id, info->he_bss_color.color, + ATH11K_BSS_COLOR_COLLISION_DETECTION_AP_PERIOD_MS, +- info->he_bss_color.enabled); ++ (info->he_bss_color.enabled & color_collision_enable)); + if (ret) + ath11k_warn(ar->ab, "failed to set bss color collision on vdev %i: %d\n", + arvif->vdev_id, ret); diff --git a/package/kernel/mac80211/patches/nss/ath11k/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch b/package/kernel/mac80211/patches/nss/ath11k/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch deleted file mode 100644 index 4ff42b80105d61..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch +++ /dev/null @@ -1,902 +0,0 @@ -From 30f54666ae15128f26fbad787a35253885a10513 Mon Sep 17 00:00:00 2001 -From: Ramya Gnanasekar -Date: Fri, 25 Dec 2020 16:11:06 +0530 -Subject: [PATCH] ath11k: Disable rx_header tlv for 2K SKB - -On low memory platform hdr_status in hal_rx_desc is not subscribed to -get a savings of 128bytes in skb. This is required to reduce the skb -size from 4K to 2K. Use HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG message -to unsubscribe rx_pkt_header tlv for rxdma ring. - -Signed-off-by: Ramya Gnanasekar - ---- a/drivers/net/wireless/ath/ath11k/debugfs.c -+++ b/drivers/net/wireless/ath/ath11k/debugfs.c -@@ -668,6 +668,7 @@ static ssize_t ath11k_write_extd_rx_stat - } - - ar->debug.rx_filter = tlv_filter.rx_filter; -+ tlv_filter.offset_valid = false; - - 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; -@@ -1129,6 +1130,7 @@ static ssize_t ath11k_write_pktlog_filte - } - - /* Clear rx filter set for monitor mode and rx status */ -+ tlv_filter.offset_valid = false; - 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, 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 { - #define DP_REO_CMD_RING_SIZE 256 - #define DP_REO_STATUS_RING_SIZE 2048 - #define DP_RXDMA_BUF_RING_SIZE 4096 --#define DP_RXDMA_REFILL_RING_SIZE 2048 -+#define DP_RXDMA_REFILL_RING_SIZE ATH11K_DP_RXDMA_REFILL_RING_SIZE -+#define DP_RXDMA_NSS_REFILL_RING_SIZE ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE - #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 -@@ -648,7 +649,7 @@ enum htt_stats_internal_ppdu_frametype { - * - * |31 26|25|24|23 16|15 8|7 0| - * |-----------------+----------------+----------------+---------------| -- * | rsvd1 |PS|SS| ring_id | pdev_id | msg_type | -+ * | rsvd1|OV|PS|SS| ring_id | pdev_id | msg_type | - * |-------------------------------------------------------------------| - * | rsvd2 | ring_buffer_size | - * |-------------------------------------------------------------------| -@@ -662,6 +663,14 @@ enum htt_stats_internal_ppdu_frametype { - * |-------------------------------------------------------------------| - * | tlv_filter_in_flags | - * |-------------------------------------------------------------------| -+ * | rx_header_offset | rx_packet_offset | -+ * |-------------------------------------------------------------------| -+ * | rx_mpdu_start_offset | rx_mpdu_end_offset | -+ * |-------------------------------------------------------------------| -+ * | rx_msdu_start_offset | rx_msdu_end_offset | -+ * |-------------------------------------------------------------------| -+ * | rsvd3 | rx_attention_offset | -+ * |-------------------------------------------------------------------| - * Where: - * PS = pkt_swap - * SS = status_swap -@@ -675,6 +684,9 @@ 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 - rx_offset_valid (OV): flag to indicate rx offsets -+ * configuration fields are valid -+ * - * b'26:31 - rsvd1: reserved for future use - * dword1 - b'0:16 - ring_buffer_size: size of buffers referenced by rx ring, - * in byte units. -@@ -704,6 +716,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 -+ * dword7 - b'0:15 - rx_packet_offset: rx_packet_offset in byte units -+ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING -+ * A value of 0 will be considered as ignore this config. -+ * Refer to BUF_RING_CFG_1 defs within HW .h files, -+ * e.g. wmac_top_reg_seq_hwioreg.h -+ * - b'16:31 - rx_header_offset: rx_header_offset in byte units -+ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING -+ * A value of 0 will be considered as ignore this config. -+ * Refer to BUF_RING_CFG_1 defs within HW .h files, -+ * e.g. wmac_top_reg_seq_hwioreg.h -+ * dword8 - b'0:15 - rx_mpdu_end_offset: rx_mpdu_end_offset in byte units -+ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING -+ * A value of 0 will be considered as ignore this config. -+ * Refer to BUF_RING_CFG_2 defs within HW .h files, -+ * e.g. wmac_top_reg_seq_hwioreg.h -+ * - b'16:31 - rx_mpdu_start_offset: rx_mpdu_start_offset in byte units -+ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING -+ * A value of 0 will be considered as ignore this config. -+ * Refer to BUF_RING_CFG_2 defs within HW .h files, -+ * e.g. wmac_top_reg_seq_hwioreg.h -+ * dword9 - b'0:15 - rx_msdu_end_offset: rx_msdu_end_offset in byte units -+ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING -+ * A value of 0 will be considered as ignore this config. -+ * Refer to BUF_RING_CFG_3 defs within HW .h files, -+ * e.g. wmac_top_reg_seq_hwioreg.h -+ * - b'16:31 - rx_msdu_start_offset: rx_msdu_start_offset in byte units -+ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING -+ * A value of 0 will be considered as ignore this config. -+ * Refer to BUF_RING_CFG_3 defs within HW .h files, -+ * e.g. wmac_top_reg_seq_hwioreg.h -+ * dword10- b'0:15 - rx_attention_offset: rx_attention_offset in byte units -+ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING -+ * A value of 0 will be considered as ignore this config. -+ * Refer to BUF_RING_CFG_4 defs within HW .h files, -+ * e.g. wmac_top_reg_seq_hwioreg.h -+ * - b'16:31 - rsvd3 for future use - */ - - #define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) -@@ -711,8 +759,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) -+#define HTT_RX_RING_SELECTION_CFG_CMD_OFFSET_VALID BIT(26) - - #define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE GENMASK(15, 0) -+#define HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET GENMASK(15, 0) -+#define HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET GENMASK(31, 16) -+#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET GENMASK(15, 0) -+#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET GENMASK(31, 16) -+#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET GENMASK(15, 0) -+#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET GENMASK(31, 16) -+#define HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET GENMASK(15, 0) - - enum htt_rx_filter_tlv_flags { - HTT_RX_FILTER_TLV_FLAGS_MPDU_START = BIT(0), -@@ -1016,6 +1072,14 @@ enum htt_rx_data_pkt_filter_tlv_flasg3 { - HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER | \ - HTT_RX_FILTER_TLV_FLAGS_ATTENTION) - -+#define HTT_RX_RXDMA_FILTER_TLV_FLAGS_BUF_RING \ -+ (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ -+ HTT_RX_FILTER_TLV_FLAGS_MSDU_START | \ -+ HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \ -+ HTT_RX_FILTER_TLV_FLAGS_MSDU_END | \ -+ HTT_RX_FILTER_TLV_FLAGS_MPDU_END | \ -+ HTT_RX_FILTER_TLV_FLAGS_ATTENTION) -+ - struct htt_rx_ring_selection_cfg_cmd { - u32 info0; - u32 info1; -@@ -1024,6 +1088,10 @@ struct htt_rx_ring_selection_cfg_cmd { - u32 pkt_type_en_flags2; - u32 pkt_type_en_flags3; - u32 rx_filter_tlv; -+ u32 rx_packet_offset; -+ u32 rx_mpdu_offset; -+ u32 rx_msdu_offset; -+ u32 rx_attn_offset; - } __packed; - - struct htt_rx_ring_tlv_filter { -@@ -1032,6 +1100,14 @@ struct htt_rx_ring_tlv_filter { - u32 pkt_filter_flags1; /* MGMT */ - u32 pkt_filter_flags2; /* CTRL */ - u32 pkt_filter_flags3; /* DATA */ -+ bool offset_valid; -+ u16 rx_packet_offset; -+ u16 rx_header_offset; -+ u16 rx_mpdu_end_offset; -+ u16 rx_mpdu_start_offset; -+ u16 rx_msdu_end_offset; -+ u16 rx_msdu_start_offset; -+ u16 rx_attn_offset; - }; - - #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 - return ab->hw_params.hw_ops->rx_desc_get_mpdu_fc_valid(desc); - } - -+static u16 ath11k_dp_rxdesc_get_mpdu_frame_ctrl(struct ath11k_base *ab, -+ struct hal_rx_desc *desc) -+{ -+ return ab->hw_params.hw_ops->rx_desc_get_mpdu_frame_ctl(desc); -+} -+ - 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 - return ab->hw_params.hw_ops->rx_desc_mpdu_start_addr2(desc); - } - -+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M -+static void ath11k_dp_get_rx_header_offset(struct ath11k_base *ab, -+ struct htt_rx_ring_tlv_filter *tlv_filter) -+{ -+ ab->hw_params.hw_ops->rx_desc_get_offset(tlv_filter); -+} -+#endif -+ -+static bool ath11k_dp_rx_desc_dot11_hdr_fields_valid(struct ath11k_base *ab, -+ struct hal_rx_desc *desc) -+{ -+ return ab->hw_params.hw_ops->rx_desc_dot11_hdr_fields_valid(desc); -+} -+ -+static void ath11k_dp_rx_desc_get_dot11_hdr(struct ath11k_base *ab, -+ struct hal_rx_desc *desc, -+ struct ieee80211_hdr *hdr) -+{ -+ ab->hw_params.hw_ops->rx_desc_get_dot11_hdr(desc, hdr); -+} -+ -+static void ath11k_dp_rx_desc_get_crypto_header(struct ath11k_base *ab, -+ struct hal_rx_desc *desc, -+ u8 *crypto_hdr, -+ enum hal_encrypt_type enctype) -+{ -+ ab->hw_params.hw_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); -+} -+ - static void ath11k_dp_service_mon_ring(struct timer_list *t) - { - struct ath11k_base *ab = from_timer(ab, t, mon_reap_timer); -@@ -2126,6 +2161,49 @@ int ath11k_dp_rx_crypto_icv_len(struct a - return 0; - } - -+static void ath11k_get_dot11_hdr_from_rx_desc(struct ath11k *ar, -+ struct sk_buff *msdu, -+ struct ath11k_skb_rxcb *rxcb, -+ struct ieee80211_rx_status *status, -+ enum hal_encrypt_type enctype) -+{ -+ struct hal_rx_desc *rx_desc = rxcb->rx_desc; -+ struct ath11k_base *ab = ar->ab; -+ size_t hdr_len, crypto_len; -+ struct ieee80211_hdr *hdr; -+ u16 fc, qos_ctl = 0; -+ u8 *crypto_hdr; -+ -+ if (!(status->flag & RX_FLAG_IV_STRIPPED)) { -+ crypto_len = ath11k_dp_rx_crypto_param_len(ar, enctype); -+ crypto_hdr = skb_push(msdu, crypto_len); -+ ath11k_dp_rx_desc_get_crypto_header(ab, rx_desc, crypto_hdr, enctype); -+ } -+ -+ fc = ath11k_dp_rxdesc_get_mpdu_frame_ctrl(ab, rx_desc); -+ hdr_len = ieee80211_hdrlen(fc); -+ skb_push(msdu, hdr_len); -+ hdr = (struct ieee80211_hdr *)msdu->data; -+ hdr->frame_control = fc; -+ -+ /* Get wifi header from rx_desc */ -+ ath11k_dp_rx_desc_get_dot11_hdr(ab, rx_desc, hdr); -+ -+ if (rxcb->is_mcbc) -+ status->flag &= ~RX_FLAG_PN_VALIDATED; -+ -+ /* Add QOS header */ -+ if (ieee80211_is_data_qos(hdr->frame_control)) { -+ qos_ctl = rxcb->tid; -+ if (ath11k_dp_rx_h_msdu_start_mesh_ctl_present(ab, rx_desc)) -+ qos_ctl |= IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT; -+ -+ /* TODO Add other QoS ctl fields when required */ -+ memcpy(msdu->data + (hdr_len - IEEE80211_QOS_CTL_LEN), -+ &qos_ctl, IEEE80211_QOS_CTL_LEN); -+ } -+} -+ - static void ath11k_dp_rx_h_undecap_nwifi(struct ath11k *ar, - struct sk_buff *msdu, - u8 *first_hdr, -@@ -2139,7 +2217,8 @@ static void ath11k_dp_rx_h_undecap_nwifi - u8 da[ETH_ALEN]; - u8 sa[ETH_ALEN]; - u16 qos_ctl = 0; -- u8 *qos; -+ u8 *qos, *crypto_hdr; -+ bool add_qos_ctrl = false; - - /* copy SA & DA and pull decapped header */ - hdr = (struct ieee80211_hdr *)msdu->data; -@@ -2148,7 +2227,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)); - -- if (rxcb->is_first_msdu) { -+ if (rxcb->is_first_msdu && first_hdr) { - /* original 802.11 header is valid for the first msdu - * hence we can reuse the same header - */ -@@ -2178,16 +2257,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); -+ add_qos_ctrl = true; - } - - 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)); -+ if (first_hdr) { -+ memcpy(skb_push(msdu, -+ ath11k_dp_rx_crypto_param_len(ar, enctype)), -+ (void *)hdr + hdr_len, -+ ath11k_dp_rx_crypto_param_len(ar, enctype)); -+ } else { -+ crypto_hdr = skb_push(msdu, ath11k_dp_rx_crypto_param_len(ar, enctype)); -+ ath11k_dp_rx_desc_get_crypto_header(ar->ab, -+ rxcb->rx_desc, crypto_hdr, enctype); -+ } - } - -- if (!rxcb->is_first_msdu) { -+ if (!rxcb->is_first_msdu || add_qos_ctrl) { - memcpy(skb_push(msdu, - IEEE80211_QOS_CTL_LEN), &qos_ctl, - IEEE80211_QOS_CTL_LEN); -@@ -2303,6 +2389,20 @@ static void ath11k_dp_rx_h_undecap_eth(s - u8 da[ETH_ALEN]; - u8 sa[ETH_ALEN]; - void *rfc1042; -+ struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); -+ struct ath11k_dp_rfc1042_hdr rfc = {0xaa, 0xaa, 0x03, {0x00, 0x00, 0x00}}; -+ -+ if (!first_hdr) { -+ eth = (struct ethhdr *)msdu->data; -+ ether_addr_copy(da, eth->h_dest); -+ ether_addr_copy(sa, eth->h_source); -+ rfc.snap_type = eth->h_proto; -+ skb_pull(msdu, sizeof(struct ethhdr)); -+ 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); -+ goto exit; -+ } - - rfc1042 = ath11k_dp_rx_h_find_rfc1042(ar, msdu, enctype); - if (WARN_ON_ONCE(!rfc1042)) -@@ -2331,6 +2431,7 @@ static void ath11k_dp_rx_h_undecap_eth(s - - memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); - -+exit: - /* original 802.11 header has a different DA and in - * case of 4addr it may also have different SA - */ -@@ -2349,6 +2450,7 @@ static void ath11k_dp_rx_h_undecap_snap( - size_t hdr_len; - u8 l3_pad_bytes; - struct hal_rx_desc *rx_desc; -+ struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); - - /* Delivered decapped frame: - * [amsdu header] <-- replaced with 802.11 hdr -@@ -2362,6 +2464,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); - -+ if (!first_hdr) { -+ ath11k_get_dot11_hdr_from_rx_desc(ar, msdu, rxcb, status, enctype); -+ return; -+ } -+ - hdr = (struct ieee80211_hdr *)first_hdr; - hdr_len = ieee80211_hdrlen(hdr->frame_control); - -@@ -2758,6 +2865,20 @@ static int ath11k_dp_rx_process_msdu(str - goto free_out; - } - -+ hdr_status = ath11k_dp_rx_h_80211_hdr(ab, rx_desc); -+ /* wifi hdr fields validation for 512M:: -+ * Mcast packets in ethernet frame mode -+ * will need wifi hdr in msdu to validate PN. -+ * Header will be added in undecap routine. -+ * Validation on wifi hdr fields from rx_desc. -+ */ -+ if (!hdr_status && ath11k_dp_rx_h_attn_is_mcbc(ab, rx_desc) && -+ !ath11k_dp_rx_desc_dot11_hdr_fields_valid(ab, rx_desc)) { -+ ath11k_warn(ab, "One or more invalid dot11 header fields\n"); -+ ret = -EIO; -+ goto free_out; -+ } -+ - rxcb = ATH11K_SKB_RXCB(msdu); - rxcb->rx_desc = rx_desc; - msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(ab, rx_desc); -@@ -2770,8 +2891,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); -- ath11k_dbg_dump(ab, ATH11K_DBG_DATA, NULL, "", hdr_status, -- sizeof(struct ieee80211_hdr)); -+ if (hdr_status) -+ ath11k_dbg_dump(ab, ATH11K_DBG_DATA, NULL, "", hdr_status, -+ sizeof(struct ieee80211_hdr)); - ath11k_dbg_dump(ab, ATH11K_DBG_DATA, NULL, "", rx_desc, - sizeof(struct hal_rx_desc)); - goto free_out; -@@ -3433,6 +3555,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); -+ - head_len = hdr_len + hal_rx_desc_sz + IEEE80211_TKIP_IV_LEN; - tail_len = IEEE80211_CCMP_MIC_LEN + IEEE80211_TKIP_ICV_LEN + FCS_LEN; - -@@ -3713,8 +3836,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) - { -- struct ieee80211_hdr *hdr; - u64 pn = 0; -+ struct ieee80211_hdr *hdr; - u8 *ehdr; - u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; - -@@ -3944,8 +4067,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); -- ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", hdr_status, -- sizeof(struct ieee80211_hdr)); -+ if (hdr_status) -+ ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", hdr_status, -+ sizeof(struct ieee80211_hdr)); - ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", rx_desc, - sizeof(struct hal_rx_desc)); - dev_kfree_skb_any(msdu); -@@ -4568,6 +4692,47 @@ void ath11k_dp_rx_pdev_free(struct ath11 - ath11k_dp_rxdma_pdev_buf_free(ar); - } - -+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M -+static int ath11k_dp_rxdma_ring_sel_config(struct ath11k *ar) -+{ -+ struct ath11k_pdev_dp *dp = &ar->dp; -+ struct htt_rx_ring_tlv_filter tlv_filter = {0}; -+ u32 ring_id; -+ int ret; -+ u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; -+ -+ ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id; -+ -+ tlv_filter.rx_filter = HTT_RX_RXDMA_FILTER_TLV_FLAGS_BUF_RING; -+ tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR; -+ tlv_filter.pkt_filter_flags3 = HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST | -+ HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST; -+ tlv_filter.offset_valid = true; -+ tlv_filter.rx_packet_offset = hal_rx_desc_sz; -+ tlv_filter.rx_header_offset = 0; -+ -+ ath11k_dp_get_rx_header_offset(ar->ab, &tlv_filter); -+ -+ if (!ar->ab->nss.enabled) -+ ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, dp->mac_id, -+ HAL_RXDMA_BUF, -+ DP_RXDMA_REFILL_RING_SIZE, -+ &tlv_filter); -+ else -+ ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, dp->mac_id, -+ HAL_RXDMA_BUF, -+ DP_RXDMA_NSS_REFILL_RING_SIZE, -+ &tlv_filter); -+ -+ return ret; -+} -+#else -+static int ath11k_dp_rxdma_ring_sel_config(struct ath11k *ar) -+{ -+ return 0; -+} -+#endif -+ - int ath11k_dp_rx_pdev_alloc(struct ath11k_base *ab, int mac_id) - { - struct ath11k *ar = ab->pdevs[mac_id].ar; -@@ -4661,6 +4826,12 @@ config_refill_ring: - } - } - -+ ret = ath11k_dp_rxdma_ring_sel_config(ar); -+ if (ret) { -+ ath11k_warn(ab, "failed to setup rxdma ring selection config\n"); -+ return ret; -+ } -+ - return 0; - } - ---- a/drivers/net/wireless/ath/ath11k/dp_tx.c -+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -@@ -1183,6 +1183,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)); -+ cmd->info0 |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_OFFSET_VALID, -+ tlv_filter->offset_valid); - - cmd->info1 = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE, - rx_buf_size); -@@ -1192,6 +1194,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; - -+ if (tlv_filter->offset_valid) { -+ cmd->rx_packet_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET, -+ tlv_filter->rx_packet_offset); -+ cmd->rx_packet_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET, -+ tlv_filter->rx_header_offset); -+ -+ cmd->rx_mpdu_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET, -+ tlv_filter->rx_mpdu_end_offset); -+ cmd->rx_mpdu_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET, -+ tlv_filter->rx_mpdu_start_offset); -+ -+ cmd->rx_msdu_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET, -+ tlv_filter->rx_msdu_end_offset); -+ cmd->rx_msdu_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET, -+ tlv_filter->rx_msdu_start_offset); -+ -+ cmd->rx_attn_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET, -+ tlv_filter->rx_attn_offset); -+ } -+ - ret = ath11k_htc_send(&ab->htc, ab->dp.eid, skb); - if (ret) - goto err_free; -@@ -1270,6 +1292,7 @@ int ath11k_dp_tx_htt_monitor_mode_ring_c - } - - ring_id = dp->rxdma_mon_buf_ring.refill_buf_ring.ring_id; -+ tlv_filter.offset_valid = false; - - if (!reset) { - tlv_filter.rx_filter = HTT_RX_MON_FILTER_TLV_FLAGS_MON_BUF_RING; ---- a/drivers/net/wireless/ath/ath11k/hw.c -+++ b/drivers/net/wireless/ath/ath11k/hw.c -@@ -260,7 +260,11 @@ static u8 ath11k_hw_ipq8074_rx_desc_get_ - - static u8 *ath11k_hw_ipq8074_rx_desc_get_hdr_status(struct hal_rx_desc *desc) - { -+#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M - return desc->u.ipq8074.hdr_status; -+#else -+ return NULL; -+#endif - } - - 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 - desc->u.ipq8074.msdu_start.info1 = __cpu_to_le32(info); - } - -+static -+struct rx_attention *ath11k_hw_ipq8074_rx_desc_get_attention(struct hal_rx_desc *desc) -+{ -+ return &desc->u.ipq8074.attention; -+} -+ -+static u8 *ath11k_hw_ipq8074_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) -+{ -+ return &desc->u.ipq8074.msdu_payload[0]; -+} -+ -+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M -+static void ath11k_hw_ipq8074_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_ipq8074, mpdu_end_tag)); -+ tlv_filter->rx_mpdu_start_offset = __le16_to_cpu(offsetof -+ (struct hal_rx_desc_ipq8074, mpdu_start_tag)); -+ tlv_filter->rx_msdu_end_offset = __le16_to_cpu(offsetof -+ (struct hal_rx_desc_ipq8074, msdu_end_tag)); -+ tlv_filter->rx_msdu_start_offset = __le16_to_cpu(offsetof -+ (struct hal_rx_desc_ipq8074, msdu_start_tag)); -+ tlv_filter->rx_attn_offset = __le16_to_cpu(offsetof -+ (struct hal_rx_desc_ipq8074, rx_attn_tag)); -+} -+#endif -+ -+static u16 ath11k_hw_ipq8074_rx_desc_get_mpdu_frame_ctl(struct hal_rx_desc *desc) -+{ -+ return __le16_to_cpu(desc->u.ipq8074.mpdu_start.frame_ctrl); -+} -+ - static bool ath11k_hw_ipq8074_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) - { - return __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & - RX_MPDU_START_INFO1_MAC_ADDR2_VALID; - } - --static u8 *ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) -+static u8* ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) - { - return desc->u.ipq8074.mpdu_start.addr2; - } - --static --struct rx_attention *ath11k_hw_ipq8074_rx_desc_get_attention(struct hal_rx_desc *desc) -+static bool ath11k_hw_ipq8074_rx_desc_dot11_hdr_fields_valid(struct hal_rx_desc *desc) - { -- return &desc->u.ipq8074.attention; -+ if ((ath11k_hw_ipq8074_rx_desc_get_mpdu_seq_ctl_vld(desc) && -+ ath11k_hw_ipq8074_rx_desc_get_mpdu_fc_valid(desc) && -+ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & -+ RX_MPDU_START_INFO1_MAC_ADDR1_VALID && -+ ath11k_hw_ipq8074_rx_desc_mac_addr2_valid(desc) && -+ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & -+ RX_MPDU_START_INFO1_MAC_ADDR3_VALID && -+ FIELD_GET((RX_MPDU_START_INFO1_MPDU_DUR_VALID), -+ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1)))) { -+ return true; -+ } -+ return false; -+} -+ -+static void ath11k_hw_ipq8074_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, -+ struct ieee80211_hdr *hdr) -+{ -+ hdr->frame_control = __le16_to_cpu(desc->u.ipq8074.mpdu_start.frame_ctrl); -+ hdr->duration_id = __le16_to_cpu(desc->u.ipq8074.mpdu_start.duration); -+ ether_addr_copy(hdr->addr1, desc->u.ipq8074.mpdu_start.addr1); -+ ether_addr_copy(hdr->addr2, desc->u.ipq8074.mpdu_start.addr2); -+ ether_addr_copy(hdr->addr3, desc->u.ipq8074.mpdu_start.addr3); -+ if (__le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & -+ RX_MPDU_START_INFO1_MAC_ADDR4_VALID) { -+ ether_addr_copy(hdr->addr4, desc->u.ipq8074.mpdu_start.addr4); -+ } -+ hdr->seq_ctrl = __le16_to_cpu(desc->u.ipq8074.mpdu_start.seq_ctrl); -+} -+ -+static void ath11k_hw_ipq8074_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.ipq8074.mpdu_start.pn[0]); -+ crypto_hdr[1] = 0; -+ crypto_hdr[2] = -+ HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.ipq8074.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.ipq8074.mpdu_start.pn[0]); -+ crypto_hdr[1] = -+ HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.ipq8074.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_INFO5_KEY_ID, -+ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info5)); -+ crypto_hdr[3] = 0x20 | (key_id << 6); -+ crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.ipq8074.mpdu_start.pn[0]); -+ crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.ipq8074.mpdu_start.pn[0]); -+ crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.ipq8074.mpdu_start.pn[1]); -+ crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.ipq8074.mpdu_start.pn[1]); - } - --static u8 *ath11k_hw_ipq8074_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) -+static bool ath11k_hw_qcn9074_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) - { -- return &desc->u.ipq8074.msdu_payload[0]; -+ return __le32_to_cpu(desc->u.qcn9074.mpdu_start.info11) & -+ RX_MPDU_START_INFO11_MAC_ADDR2_VALID; -+} -+ -+static u8* ath11k_hw_qcn9074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) -+{ -+ return desc->u.qcn9074.mpdu_start.addr2; - } - - 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_ - - static u8 *ath11k_hw_qcn9074_rx_desc_get_hdr_status(struct hal_rx_desc *desc) - { -+#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M - return desc->u.qcn9074.hdr_status; -+#else -+ return NULL; -+#endif - } - - 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_ - - static u8 *ath11k_hw_wcn6855_rx_desc_get_hdr_status(struct hal_rx_desc *desc) - { -+#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M - return desc->u.wcn6855.hdr_status; -+#else -+ return NULL; -+#endif - } - - 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, - .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2, - .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, -+#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 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 = - .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, - .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, - }; - ---- a/drivers/net/wireless/ath/ath11k/hw.h -+++ b/drivers/net/wireless/ath/ath11k/hw.h -@@ -22,7 +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 -+ */ -+#define ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE 1816 - #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 @@ - #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 -+#define ATH11K_DP_RXDMA_REFILL_RING_SIZE 2048 -+#define ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE 2048 - #endif - - /* Num of peers for Single Radio mode */ -@@ -142,6 +152,8 @@ 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_desc_mpdu_start_addr2)(struct hal_rx_desc *desc); - u32 (*get_ring_selector)(struct sk_buff *skb); -+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M -+ void (*rx_desc_get_offset)(struct htt_rx_ring_tlv_filter *tlv_filter); -+#endif -+ u16 (*rx_desc_get_mpdu_frame_ctl)(struct hal_rx_desc *desc); -+ bool (*rx_desc_dot11_hdr_fields_valid)(struct hal_rx_desc *desc); -+ void (*rx_desc_get_dot11_hdr)(struct hal_rx_desc *desc, -+ struct ieee80211_hdr *hdr); -+ void (*rx_desc_get_crypto_header)(struct hal_rx_desc *desc, -+ u8 *crypto_hdr, -+ enum hal_encrypt_type enctype); - }; - - extern const struct ath11k_hw_ops ipq8074_ops; ---- a/drivers/net/wireless/ath/ath11k/mac.c -+++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6341,6 +6341,7 @@ static int ath11k_mac_config_mon_status_ - tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar); - } - -+ tlv_filter.offset_valid = false; - 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, ---- 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 { - __le32 mpdu_end_tag; - struct rx_mpdu_end mpdu_end; - u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES]; -+#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M - __le32 hdr_status_tag; - __le32 phy_ppdu_id; - u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN]; -+#endif - u8 msdu_payload[]; - } __packed; - -@@ -1461,9 +1463,11 @@ struct hal_rx_desc_qcn9074 { - __le32 mpdu_end_tag; - struct rx_mpdu_end mpdu_end; - u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES]; -+#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M - __le32 hdr_status_tag; - __le32 phy_ppdu_id; - u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN]; -+#endif - u8 msdu_payload[]; - } __packed; - -@@ -1480,9 +1484,11 @@ struct hal_rx_desc_wcn6855 { - __le32 mpdu_end_tag; - struct rx_mpdu_end mpdu_end; - u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES]; -+#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M - __le32 hdr_status_tag; - __le32 phy_ppdu_id; - u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN]; -+#endif - u8 msdu_payload[]; - } __packed; - -@@ -1507,4 +1513,17 @@ struct hal_rx_desc { - #define RU_484 18 - #define RU_996 37 - -+#define HAL_RX_MPDU_INFO_PN_GET_BYTE1(__val) \ -+ FIELD_GET(GENMASK(7, 0), __le32_to_cpu(__val)) -+ -+#define HAL_RX_MPDU_INFO_PN_GET_BYTE2(__val) \ -+ FIELD_GET(GENMASK(15, 8), __le32_to_cpu(__val)) -+ -+#define HAL_RX_MPDU_INFO_PN_GET_BYTE3(__val) \ -+ FIELD_GET(GENMASK(23, 16), __le32_to_cpu(__val)) -+ -+#define HAL_RX_MPDU_INFO_PN_GET_BYTE4(__val) \ -+ FIELD_GET(GENMASK(31, 24), __le32_to_cpu(__val)) -+ -+ - #endif /* ATH11K_RX_DESC_H */ ---- a/drivers/net/wireless/ath/ath11k/nss.c -+++ b/drivers/net/wireless/ath/ath11k/nss.c -@@ -2226,7 +2226,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; -- wim->wrip.rx_buf_len = DP_RX_BUFFER_SIZE; -+ wim->wrip.rx_buf_len = DP_RXDMA_NSS_REFILL_RING_SIZE; - - /* fill hal srng message */ - wim->hssm.dev_base_addr = (u32)ab->mem_pa; diff --git a/package/kernel/mac80211/patches/nss/ath11k/234-001-ath11k-account-tx-rx-packets-flow.patch b/package/kernel/mac80211/patches/nss/ath11k/234-001-ath11k-account-tx-rx-packets-flow.patch deleted file mode 100644 index f5c9b1943fb85c..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -501,6 +501,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; - -@@ -534,6 +545,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 -@@ -221,9 +221,6 @@ static ssize_t ath11k_dbg_sta_dump_tx_st - char *buf, mu_group_id[MAX_MU_GROUP_LENGTH] = {0}; - u32 index; - -- if (!arsta->tx_stats) -- return -ENOENT; -- - buf = kzalloc(size, GFP_KERNEL); - if (!buf) - return -ENOMEM; -@@ -231,6 +228,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]; -@@ -364,6 +367,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 = { -@@ -982,17 +990,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 -@@ -2566,6 +2566,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); -@@ -2759,6 +2760,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; -@@ -2824,6 +2826,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, -@@ -2970,6 +2984,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; -@@ -3043,6 +3059,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); - -@@ -4234,7 +4263,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); - -@@ -4286,6 +4318,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 -@@ -6255,6 +6255,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; -@@ -6315,6 +6316,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/nss/ath11k/235-001-ath11k-Add-support-for-beacon-tx-mode.patch b/package/kernel/mac80211/patches/nss/ath11k/235-001-ath11k-Add-support-for-beacon-tx-mode.patch new file mode 100644 index 00000000000000..9782bb186801af --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/235-001-ath11k-Add-support-for-beacon-tx-mode.patch @@ -0,0 +1,52 @@ +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 + +Add support to configure the beacon tx mode in +the driver. + +Beacons can be sent out in burst(continuously in a single shot +one after another) or staggered (equally spread out over beacon +interval) mode. + +Use the below configuration in the hostapd/wpa_supplicant +for AP/MESH mode to configure the beacon tx mode. + +"beacon_tx_mode=N", where N = 1 for STAGGERED beacon mode +and N = 2 for BURST beacon mode. + +Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-00480-QCAHKSWPL_SILICONZ-1 + +Signed-off-by: Maharaja Kennadyrajan +--- + + drivers/net/wireless/ath/ath11k/mac.c | 10 +++++++--- + 1 file changed, 7 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 == WMI_BEACON_BURST_MODE) ? "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/nss/ath11k/235-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 index fae9eb86e87c5f..7a935968261d33 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/235-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 -@@ -322,6 +322,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; -@@ -555,8 +559,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; -@@ -578,19 +583,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); -@@ -634,7 +642,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; -@@ -655,8 +664,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)); -@@ -723,6 +732,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; -@@ -778,10 +788,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 -@@ -844,6 +855,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; -@@ -866,10 +939,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), -@@ -1210,6 +1289,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; -@@ -1241,6 +1321,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; -@@ -1250,6 +1336,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; -@@ -1277,11 +1364,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, -@@ -1375,22 +1813,22 @@ free: +@@ -1376,22 +1814,22 @@ free: return status; } @@ -623,7 +623,7 @@ Signed-off-by: Sathishkumar Muruganandam sta->addr); goto exit; } -@@ -1462,13 +1900,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) -@@ -1772,8 +2210,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); -@@ -1818,8 +2256,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, diff --git a/package/kernel/mac80211/patches/nss/ath11k/235-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 index 602899eea5228c..429b781199f132 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/235-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,7 +33,7 @@ Signed-off-by: Sathishkumar Muruganandam --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -387,6 +387,7 @@ struct ath11k_vif { +@@ -389,6 +389,7 @@ struct ath11k_vif { #ifdef CPTCFG_ATH11K_NSS_SUPPORT struct arvif_nss nss; #endif @@ -43,7 +43,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 -@@ -4739,6 +4739,11 @@ static void ath11k_sta_rc_update_wk(stru +@@ -4748,6 +4748,11 @@ static void ath11k_sta_rc_update_wk(stru arvif = arsta->arvif; ar = arvif->ar; @@ -55,7 +55,7 @@ Signed-off-by: Sathishkumar Muruganandam if (WARN_ON(ath11k_mac_vif_chan(arvif->vif, &def))) return; -@@ -4910,17 +4915,28 @@ err_rc_bw_changed: +@@ -4919,17 +4924,28 @@ err_rc_bw_changed: static void ath11k_sta_set_4addr_wk(struct work_struct *wk) { struct ath11k *ar; @@ -86,7 +86,7 @@ Signed-off-by: Sathishkumar Muruganandam "setting USE_4ADDR for peer %pM\n", sta->addr); ret = ath11k_wmi_set_peer_param(ar, sta->addr, -@@ -4928,8 +4944,93 @@ static void ath11k_sta_set_4addr_wk(stru +@@ -4937,8 +4953,93 @@ static void ath11k_sta_set_4addr_wk(stru WMI_PEER_USE_4ADDR, 1); if (ret) @@ -181,7 +181,7 @@ Signed-off-by: Sathishkumar Muruganandam } static int ath11k_mac_inc_num_stations(struct ath11k_vif *arvif, -@@ -5259,9 +5360,32 @@ static void ath11k_mac_op_sta_set_4addr( +@@ -5268,9 +5369,32 @@ static void ath11k_mac_op_sta_set_4addr( struct ieee80211_sta *sta, bool enabled) { struct ath11k *ar = hw->priv; @@ -214,7 +214,7 @@ Signed-off-by: Sathishkumar Muruganandam ieee80211_queue_work(ar->hw, &arsta->set_4addr_wk); arsta->use_4addr_set = true; } -@@ -6655,6 +6779,9 @@ static int ath11k_mac_op_update_vif_offl +@@ -6654,6 +6778,9 @@ static int ath11k_mac_op_update_vif_offl u32 param_id, param_value; int ret; @@ -224,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 && -@@ -6875,7 +7002,8 @@ static int ath11k_mac_op_add_interface(s +@@ -6874,7 +7001,8 @@ static int ath11k_mac_op_add_interface(s goto err; } @@ -234,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; -@@ -6895,6 +7023,28 @@ static int ath11k_mac_op_add_interface(s +@@ -6894,6 +7022,28 @@ static int ath11k_mac_op_add_interface(s arvif->vif = vif; INIT_LIST_HEAD(&arvif->list); @@ -263,7 +263,7 @@ Signed-off-by: Sathishkumar Muruganandam INIT_DELAYED_WORK(&arvif->connection_loss_work, ath11k_mac_vif_sta_connection_loss_work); -@@ -6924,6 +7074,7 @@ static int ath11k_mac_op_add_interface(s +@@ -6923,6 +7073,7 @@ static int ath11k_mac_op_add_interface(s fallthrough; case NL80211_IFTYPE_AP: arvif->vdev_type = WMI_VDEV_TYPE_AP; @@ -271,7 +271,7 @@ Signed-off-by: Sathishkumar Muruganandam break; case NL80211_IFTYPE_MONITOR: arvif->vdev_type = WMI_VDEV_TYPE_MONITOR; -@@ -7146,13 +7297,30 @@ static void ath11k_mac_op_remove_interfa +@@ -7145,13 +7296,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; @@ -304,7 +304,7 @@ Signed-off-by: Sathishkumar Muruganandam ath11k_dbg(ab, ATH11K_DBG_MAC, "remove interface (vdev %d)\n", arvif->vdev_id); -@@ -7169,6 +7337,14 @@ static void ath11k_mac_op_remove_interfa +@@ -7168,6 +7336,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); @@ -319,7 +319,7 @@ Signed-off-by: Sathishkumar Muruganandam } ret = ath11k_mac_vdev_delete(ar, arvif); -@@ -7212,8 +7388,7 @@ err_vdev_del: +@@ -7211,8 +7387,7 @@ err_vdev_del: ath11k_debugfs_remove_interface(arvif); @@ -329,7 +329,7 @@ Signed-off-by: Sathishkumar Muruganandam mutex_unlock(&ar->conf_mutex); } -@@ -7273,16 +7448,17 @@ static int ath11k_mac_op_ampdu_action(st +@@ -7272,16 +7447,17 @@ static int ath11k_mac_op_ampdu_action(st struct ieee80211_ampdu_params *params) { struct ath11k *ar = hw->priv; @@ -349,7 +349,7 @@ Signed-off-by: Sathishkumar Muruganandam break; case IEEE80211_AMPDU_TX_START: case IEEE80211_AMPDU_TX_STOP_CONT: -@@ -8805,6 +8981,7 @@ static void ath11k_mac_op_sta_statistics +@@ -8804,6 +8980,7 @@ static void ath11k_mac_op_sta_statistics { struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); struct ath11k *ar = arsta->arvif->ar; @@ -357,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); -@@ -8861,7 +9038,8 @@ static void ath11k_mac_op_sta_statistics +@@ -8860,7 +9037,8 @@ static void ath11k_mac_op_sta_statistics ATH11K_DEFAULT_NOISE_FLOOR; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); @@ -415,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, @@ -429,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; } @@ -454,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) { @@ -465,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); @@ -473,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; @@ -494,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); @@ -503,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; } @@ -536,13 +536,13 @@ Signed-off-by: Sathishkumar Muruganandam - 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(); -@@ -996,6 +1002,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; 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 00000000000000..ee1e977310c046 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/237-001-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch @@ -0,0 +1,102 @@ +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -1048,6 +1049,7 @@ struct ath11k_base { + } testmode; + #endif + ++ 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/nss/ath11k/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 index 735ffa00cdedc2..8034b6186ee671 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -141,6 +141,7 @@ struct ath11k_skb_rxcb { +@@ -143,6 +143,7 @@ struct ath11k_skb_rxcb { u8 tid; u16 peer_id; u16 seq_no; @@ -31,99 +31,9 @@ Signed-off-by: P Praneesh }; enum ath11k_hw_rev { -@@ -1074,6 +1075,7 @@ struct ath11k_base { - - atomic_t num_max_allowed; - struct ath11k_num_vdevs_peers *num_vdevs_peers; -+ bool stats_disable; - - u32 max_ast_index; - u32 num_ast_entries; ---- a/drivers/net/wireless/ath/ath11k/debugfs.c -+++ b/drivers/net/wireless/ath/ath11k/debugfs.c -@@ -974,6 +974,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)) --- 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; } @@ -136,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, -@@ -2553,10 +2559,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; + } +@@ -2448,10 +2454,60 @@ ath11k_dp_rx_h_find_peer(struct ath11k_b return peer; } @@ -198,17 +117,22 @@ Signed-off-by: P Praneesh { bool fill_crypto_hdr; enum hal_encrypt_type enctype; -@@ -2568,6 +2624,9 @@ static void ath11k_dp_rx_h_mpdu(struct a +@@ -2462,9 +2518,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); -@@ -2581,6 +2640,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) { +@@ -2475,6 +2535,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) { @@ -228,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 -@@ -2844,7 +2927,8 @@ static void ath11k_dp_rx_deliver_msdu(st +@@ -2484,6 +2564,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) +@@ -2725,7 +2807,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, @@ -249,7 +178,7 @@ Signed-off-by: P Praneesh { struct ath11k_base *ab = ar->ab; struct hal_rx_desc *rx_desc, *lrx_desc; -@@ -2926,8 +3010,13 @@ static int ath11k_dp_rx_process_msdu(str +@@ -2792,8 +2875,13 @@ static int ath11k_dp_rx_process_msdu(str } } @@ -264,7 +193,7 @@ Signed-off-by: P Praneesh rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; -@@ -2942,10 +3031,12 @@ static void ath11k_dp_rx_process_receive +@@ -2808,10 +2896,12 @@ static void ath11k_dp_rx_process_receive struct sk_buff_head *msdu_list, int mac_id) { @@ -277,7 +206,7 @@ Signed-off-by: P Praneesh if (skb_queue_empty(msdu_list)) return; -@@ -2962,7 +3053,12 @@ static void ath11k_dp_rx_process_receive +@@ -2828,7 +2918,12 @@ static void ath11k_dp_rx_process_receive } while ((msdu = __skb_dequeue(msdu_list))) { @@ -291,7 +220,7 @@ Signed-off-by: P Praneesh if (unlikely(ret)) { ath11k_dbg(ab, ATH11K_DBG_DATA, "Unable to process msdu %d", ret); -@@ -2970,7 +3066,10 @@ static void ath11k_dp_rx_process_receive +@@ -2836,7 +2931,10 @@ static void ath11k_dp_rx_process_receive continue; } @@ -303,15 +232,29 @@ Signed-off-by: P Praneesh } } -@@ -4268,6 +4367,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; -+ bool fast_rx; +@@ -2845,11 +2943,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; - msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(ar->ab, desc); + 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; -@@ -4311,7 +4411,8 @@ static int ath11k_dp_rx_h_null_q_desc(st +@@ -4316,6 +4415,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; + u16 msdu_len; + struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; + struct rx_attention *rx_attention; +@@ -4365,7 +4465,8 @@ static int ath11k_dp_rx_h_null_q_desc(st } ath11k_dp_rx_h_ppdu(ar, desc, status); @@ -323,7 +266,7 @@ Signed-off-by: P Praneesh --- a/drivers/net/wireless/ath/ath11k/hw.c +++ b/drivers/net/wireless/ath/ath11k/hw.c -@@ -297,6 +297,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)); } @@ -340,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, -@@ -584,6 +594,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)); } @@ -357,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, -@@ -1137,6 +1157,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, @@ -365,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, -@@ -1298,6 +1319,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, @@ -375,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); @@ -385,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 -@@ -5527,6 +5527,14 @@ static int ath11k_mac_op_sta_state(struc +@@ -5536,6 +5536,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/nss/ath11k/244-ath11k-dp-tx-perf.patch b/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch index 7430ded742fb14..3c4d324161644c 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -113,6 +113,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,19 +34,20 @@ Signed-off-by: P Praneesh }; struct ath11k_skb_cb { -@@ -888,7 +889,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 @@ -358,7 +358,7 @@ void ath11k_dp_stop_shadow_timers(struct @@ -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) == @@ -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) && @@ -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 -@@ -6668,12 +6668,22 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6643,12 +6643,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; } -@@ -7631,7 +7641,7 @@ err_vdev_del: +@@ -7596,7 +7606,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 -@@ -191,7 +191,6 @@ static struct ath11k_hw_params ath11k_hw +@@ -186,7 +186,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, -@@ -216,6 +215,8 @@ static struct ath11k_hw_params ath11k_hw +@@ -212,6 +211,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,7 @@ Signed-off-by: P Praneesh }, { .name = "qca6390 hw2.0", -@@ -383,6 +384,8 @@ static struct ath11k_hw_params ath11k_hw +@@ -381,6 +382,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,7 +516,7 @@ Signed-off-by: P Praneesh }, { .name = "wcn6855 hw2.0", -@@ -2144,6 +2147,9 @@ int ath11k_core_pre_init(struct ath11k_b +@@ -2146,6 +2149,9 @@ int ath11k_core_pre_init(struct ath11k_b if (nss_offload) ab->nss.stats_enabled = 1; 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 00000000000000..f11c9d28710d53 --- /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 +@@ -1403,6 +1403,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) +@@ -1426,6 +1491,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); +@@ -1559,6 +1627,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(); + } +@@ -1679,6 +1749,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) + { +@@ -1697,6 +1830,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) { +@@ -1764,6 +1906,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 +@@ -3474,6 +3474,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); + } + +@@ -9700,6 +9712,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, +@@ -9757,6 +9791,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, +@@ -10215,6 +10252,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/nss/ath11k/301-ath11k-nss-mcbc-exception.patch b/package/kernel/mac80211/patches/nss/ath11k/301-ath11k-nss-mcbc-exception.patch index 5202b7bf90fd02..6f4793b5a0afd5 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -567,7 +567,7 @@ static int ath11k_nss_undecap_nwifi(stru +@@ -568,7 +568,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; -@@ -603,8 +603,6 @@ static void ath11k_nss_wds_type_rx(struc +@@ -604,8 +604,6 @@ static void ath11k_nss_wds_type_rx(struc } } @@ -34,7 +34,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 } spin_unlock_bh(&ab->base_lock); -@@ -648,8 +646,7 @@ static void ath11k_nss_mec_handler(struc +@@ -649,8 +647,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; -@@ -671,7 +668,7 @@ static void ath11k_nss_vdev_spl_receive_ +@@ -672,7 +669,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,7 +53,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 break; case NSS_WIFI_VDEV_WDS_TYPE_MEC: ath11k_nss_mec_handler(ar, (u8 *)(skb->data)); -@@ -738,10 +735,12 @@ ath11k_nss_vdev_special_data_receive(str +@@ -739,10 +736,12 @@ ath11k_nss_vdev_special_data_receive(str struct ieee80211_vif *vif; struct ath11k_vif *arvif; struct ath11k_base *ab; @@ -67,7 +67,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 if (!dev) { dev_kfree_skb_any(skb); -@@ -790,15 +789,50 @@ ath11k_nss_vdev_special_data_receive(str +@@ -791,15 +790,50 @@ ath11k_nss_vdev_special_data_receive(str return; } @@ -126,7 +126,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 } static void -@@ -1005,6 +1039,9 @@ int ath11k_nss_vdev_set_cmd(struct ath11 +@@ -1006,6 +1040,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; @@ -136,7 +136,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 default: return -EINVAL; } -@@ -1246,12 +1283,31 @@ int ath11k_nss_vdev_create(struct ath11k +@@ -1247,12 +1284,31 @@ int ath11k_nss_vdev_create(struct ath11k goto free_vdev; switch (arvif->vif->type) { @@ -169,16 +169,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 break; default: ret = -ENOTSUPP; -@@ -1401,7 +1457,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, -@@ -1525,7 +1581,6 @@ static int ath11k_nss_ext_vdev_register( +@@ -1526,7 +1582,6 @@ static int ath11k_nss_ext_vdev_register( { struct ath11k *ar = arvif->ar; struct ath11k_base *ab = ar->ab; @@ -186,7 +177,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 u32 features = 0; if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN || arvif->nss.ctx) -@@ -1539,7 +1594,7 @@ static int ath11k_nss_ext_vdev_register( +@@ -1540,7 +1595,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", @@ -210,38 +201,3 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 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 -@@ -3073,6 +3073,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 -@@ -138,4 +138,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/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch b/package/kernel/mac80211/patches/nss/ath11k/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch deleted file mode 100644 index ea8e6016dfa22c..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 246e530a47d9adab9106fb6f2b92197cace17e53 Mon Sep 17 00:00:00 2001 -From: Seevalamuthu Mariappan -Date: Fri, 21 May 2021 14:16:22 +0530 -Subject: [PATCH] ath11k: configure nss radio priority during pdev_init - -pdev's priority value is read from dts. Get scheme_id -using pdev priority. Configure scheme_id during pdev_init. - -Signed-off-by: Seevalamuthu Mariappan ---- - drivers/net/wireless/ath/ath11k/nss.c | 20 +++++++++++++++++++- - drivers/net/wireless/ath/ath11k/nss.h | 3 +++ - 2 files changed, 22 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/ath/ath11k/nss.c -+++ b/drivers/net/wireless/ath/ath11k/nss.c -@@ -2,6 +2,7 @@ - /* - * Copyright (c) 2020 The Linux Foundation. All rights reserved. - */ -+#include - - #include "debug.h" - #include "mac.h" -@@ -2793,6 +2794,7 @@ static int ath11k_nss_init(struct ath11k - nss_tx_status_t status; - struct ath11k_dp *dp; - int i, ret; -+ struct device *dev = ab->dev; - - dp = &ab->dp; - -@@ -2812,6 +2814,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; -+ if (of_property_read_bool(dev->of_node, "nss-radio-priority")) -+ wim->flags |= WIFILI_MULTISOC_THREAD_MAP_ENABLE; - - /* fill hal srng message */ - wim->hssm.dev_base_addr = (u32)ab->mem_pa; -@@ -2989,11 +2993,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; -+ struct device *dev = ab->dev; - int radio_if_num = -1; - int refill_ring_id; - int features = 0; - int dyn_if_type; -- int ret, i; -+ int ret, i, scheme_id = 0; -+ u32 nss_radio_priority; - - dyn_if_type = ath11k_nss_get_dynamic_interface_type(ab); - -@@ -3022,6 +3028,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); - -+ if (!of_property_read_u32(dev->of_node, "nss-radio-priority", &nss_radio_priority)) { -+ scheme_id = nss_wifili_thread_scheme_alloc(ab->nss.ctx, ar->nss.if_num, nss_radio_priority); -+ if (scheme_id == WIFILI_SCHEME_ID_INVALID) { -+ ath11k_warn(ab, "received invalid scheme_id, configuring default value\n"); -+ scheme_id = 0; -+ } -+ } -+ ath11k_dbg(ab, ATH11K_DBG_NSS, "ifnum: %d scheme_id: %d nss_radio_priority: %d\n", ar->nss.if_num, scheme_id, nss_radio_priority); -+ - wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); - if (!wlmsg) { - ret = -ENOMEM; -@@ -3034,6 +3049,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; -+ pdevmsg->scheme_id = scheme_id; - - /* Store rxdma ring info to the message */ - refill_ring_id = ar->dp.rx_refill_buf_ring.refill_buf_ring.ring_id; -@@ -3327,6 +3343,9 @@ int ath11k_nss_pdev_deinit(struct ath11k - /* pdev deinit msg success, dealloc, deregister and return */ - ret = 0; - -+ /* reset thread scheme*/ -+ nss_wifili_thread_scheme_dealloc(ab->nss.ctx, ar->nss.if_num); -+ - nss_dynamic_interface_dealloc_node(ar->nss.if_num, dyn_if_type); - nss_unregister_wifili_radio_if(ar->nss.if_num); - free: ---- a/drivers/net/wireless/ath/ath11k/nss.h -+++ b/drivers/net/wireless/ath/ath11k/nss.h -@@ -63,6 +63,7 @@ struct hal_rx_user_status; - /* Init Flags */ - #define WIFILI_NSS_CCE_DISABLED 0x1 - #define WIFILI_ADDTL_MEM_SEG_SET 0x000000002 -+#define WIFILI_MULTISOC_THREAD_MAP_ENABLE 0x10 - - /* ATH11K NSS PEER Info */ - /* Host memory allocated for peer info storage in nss */ -@@ -115,6 +116,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 -+ - enum ath11k_nss_opmode { - ATH11K_NSS_OPMODE_UNKNOWN, - ATH11K_NSS_OPMODE_AP, 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 00000000000000..ed3cde7c8e00ec --- /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 +@@ -7640,8 +7640,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 +@@ -6125,13 +6125,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); + +@@ -6139,6 +6139,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; + } + +@@ -6147,6 +6148,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)) && !tx_compl_param->status) +@@ -6161,34 +6184,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/nss/ath11k/330-ath11k-sync-wds_ast_entry-updates.patch b/package/kernel/mac80211/patches/nss/ath11k/330-ath11k-sync-wds_ast_entry-updates.patch index 9635b4b6297a6b..98fb7325850498 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -2213,6 +2213,7 @@ struct ath11k_base *ath11k_core_alloc(st +@@ -2235,6 +2235,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); -@@ -2226,6 +2227,8 @@ struct ath11k_base *ath11k_core_alloc(st +@@ -2248,6 +2249,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); @@ -83,21 +83,19 @@ Signed-off-by: Rameshkumar Sundaram #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) -@@ -1085,6 +1086,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 -@@ -609,8 +609,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]; -@@ -637,7 +638,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); -@@ -672,7 +673,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); -@@ -2335,11 +2336,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; -@@ -2462,7 +2459,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; -@@ -2480,8 +2477,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 -@@ -242,8 +242,8 @@ int ath11k_nss_update_wds_peer(struct at +@@ -288,8 +288,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, -@@ -342,8 +342,8 @@ static inline int ath11k_nss_map_wds_pee +@@ -409,8 +409,8 @@ static inline int ath11k_nss_map_wds_pee return 0; } @@ -195,7 +193,7 @@ Signed-off-by: Rameshkumar Sundaram --- a/drivers/net/wireless/ath/ath11k/peer.c +++ b/drivers/net/wireless/ath/ath11k/peer.c -@@ -146,49 +146,68 @@ struct ath11k_ast_entry *ath11k_peer_ast +@@ -160,49 +160,68 @@ struct ath11k_ast_entry *ath11k_peer_ast void ath11k_peer_ast_wds_wmi_wk(struct work_struct *wk) { @@ -299,7 +297,7 @@ Signed-off-by: Rameshkumar Sundaram } int ath11k_peer_add_ast(struct ath11k *ar, struct ath11k_peer *peer, -@@ -197,6 +216,8 @@ int ath11k_peer_add_ast(struct ath11k *a +@@ -211,6 +230,8 @@ int ath11k_peer_add_ast(struct ath11k *a struct ath11k_ast_entry *ast_entry = NULL; struct ath11k_base *ab = ar->ab; @@ -308,7 +306,7 @@ Signed-off-by: Rameshkumar Sundaram if (ab->num_ast_entries == ab->max_ast_index) { ath11k_warn(ab, "failed to add ast for %pM due to insufficient ast entry resource %d in target\n", mac_addr, ab->max_ast_index); -@@ -212,6 +233,9 @@ int ath11k_peer_add_ast(struct ath11k *a +@@ -226,6 +247,9 @@ int ath11k_peer_add_ast(struct ath11k *a } } @@ -318,7 +316,7 @@ Signed-off-by: Rameshkumar Sundaram ast_entry = kzalloc(sizeof(*ast_entry), GFP_ATOMIC); if (!ast_entry) { ath11k_warn(ab, "failed to alloc ast_entry for %pM\n", -@@ -243,7 +267,7 @@ int ath11k_peer_add_ast(struct ath11k *a +@@ -257,7 +281,7 @@ int ath11k_peer_add_ast(struct ath11k *a } INIT_LIST_HEAD(&ast_entry->ase_list); @@ -327,7 +325,7 @@ Signed-off-by: Rameshkumar Sundaram ast_entry->vdev_id = peer->vdev_id; ast_entry->pdev_idx = peer->pdev_idx; ast_entry->is_mapped = false; -@@ -257,16 +281,12 @@ int ath11k_peer_add_ast(struct ath11k *a +@@ -271,16 +295,12 @@ int ath11k_peer_add_ast(struct ath11k *a ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_add_ast peer %pM ast_entry %pM, ast_type %d\n", peer->addr, mac_addr, ast_entry->type); @@ -346,7 +344,7 @@ Signed-off-by: Rameshkumar Sundaram } ab->num_ast_entries++; -@@ -279,6 +299,8 @@ int ath11k_peer_update_ast(struct ath11k +@@ -293,6 +313,8 @@ int ath11k_peer_update_ast(struct ath11k struct ath11k_peer *old_peer = ast_entry->peer; struct ath11k_base *ab = ar->ab; @@ -355,7 +353,7 @@ Signed-off-by: Rameshkumar Sundaram if (!ast_entry->is_mapped) { ath11k_warn(ab, "ath11k_peer_update_ast: ast_entry %pM not mapped yet\n", ast_entry->addr); -@@ -291,6 +313,9 @@ int ath11k_peer_update_ast(struct ath11k +@@ -305,6 +327,9 @@ int ath11k_peer_update_ast(struct ath11k (ast_entry->is_active)) return 0; @@ -365,7 +363,7 @@ Signed-off-by: Rameshkumar Sundaram ast_entry->vdev_id = peer->vdev_id; ast_entry->pdev_idx = peer->pdev_idx; ast_entry->type = ATH11K_AST_TYPE_WDS; -@@ -303,7 +328,14 @@ int ath11k_peer_update_ast(struct ath11k +@@ -317,7 +342,14 @@ int ath11k_peer_update_ast(struct ath11k old_peer->addr, peer->addr, ast_entry->addr); ast_entry->action = ATH11K_WDS_WMI_UPDATE; @@ -381,7 +379,7 @@ Signed-off-by: Rameshkumar Sundaram return 0; } -@@ -349,16 +381,23 @@ void ath11k_peer_del_ast(struct ath11k * +@@ -363,16 +395,23 @@ void ath11k_peer_del_ast(struct ath11k * ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_del_ast pdev:%d peer %pM ast_entry %pM\n", ar->pdev->pdev_id, peer->addr, ast_entry->addr); @@ -410,7 +408,7 @@ Signed-off-by: Rameshkumar Sundaram ab->num_ast_entries--; } -@@ -667,6 +706,10 @@ void ath11k_peer_cleanup(struct ath11k * +@@ -681,6 +720,10 @@ void ath11k_peer_cleanup(struct ath11k * lockdep_assert_held(&ar->conf_mutex); @@ -421,7 +419,7 @@ Signed-off-by: Rameshkumar Sundaram mutex_lock(&ab->tbl_mtx_lock); spin_lock_bh(&ab->base_lock); list_for_each_entry_safe(peer, tmp_peer, &ab->peers, list) { -@@ -695,6 +738,9 @@ void ath11k_peer_cleanup(struct ath11k * +@@ -709,6 +752,9 @@ void ath11k_peer_cleanup(struct ath11k * spin_unlock_bh(&ab->base_lock); mutex_unlock(&ab->tbl_mtx_lock); @@ -431,7 +429,7 @@ Signed-off-by: Rameshkumar Sundaram } static int ath11k_wait_for_peer_deleted(struct ath11k *ar, int vdev_id, const u8 *addr) -@@ -729,12 +775,18 @@ static int __ath11k_peer_delete(struct a +@@ -743,12 +789,18 @@ static int __ath11k_peer_delete(struct a int ret; struct ath11k_peer *peer; struct ath11k_base *ab = ar->ab; @@ -450,7 +448,7 @@ Signed-off-by: Rameshkumar Sundaram mutex_lock(&ab->tbl_mtx_lock); spin_lock_bh(&ab->base_lock); -@@ -757,17 +809,35 @@ static int __ath11k_peer_delete(struct a +@@ -771,17 +823,35 @@ static int __ath11k_peer_delete(struct a return -EINVAL; } diff --git a/package/kernel/mac80211/patches/nss/ath11k/335-0001-ath11k-optimize-tx-completions.patch b/package/kernel/mac80211/patches/nss/ath11k/335-0001-ath11k-optimize-tx-completions.patch index e34922f11df238..60f3b246550641 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -453,6 +453,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 */ - -@@ -651,9 +652,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 }; -@@ -663,9 +696,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; } -@@ -674,11 +710,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); -@@ -688,6 +727,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; -@@ -698,54 +739,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; -@@ -767,44 +810,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) == -@@ -821,9 +833,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; -@@ -843,7 +855,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], -@@ -863,14 +875,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, -@@ -894,7 +908,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/nss/ath11k/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 index 5c5e2de6ed756f..f567ec640942c9 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -139,7 +139,7 @@ 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 @@ -251,7 +251,7 @@ Signed-off-by: Venkateswara Naralasetty if (unlikely(!msdu)) { ath11k_warn(ab, "htt tx completion for unknown msdu_id %d\n", -@@ -874,6 +885,7 @@ void ath11k_dp_tx_completion_handler(str +@@ -870,6 +881,7 @@ void ath11k_dp_tx_completion_handler(str } while (count--) { @@ -259,7 +259,7 @@ Signed-off-by: Venkateswara Naralasetty tx_status = &tx_ring->tx_status[i++]; desc_id = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, -@@ -892,17 +904,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/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 00000000000000..8cd0b134bdf77e --- /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 +@@ -6197,12 +6197,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); +@@ -6524,6 +6535,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; + +@@ -6563,7 +6581,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; +@@ -6594,16 +6611,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/nss/ath11k/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 new file mode 100644 index 00000000000000..0e99521c4d5ff0 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch @@ -0,0 +1,74 @@ +From 0ab84604de1db0f589f7303507f38148ba8f3f04 Mon Sep 17 00:00:00 2001 +From: Nagarajan Maran +Date: Tue, 28 Jun 2022 11:31:50 +0530 +Subject: [PATCH] ath11k: Ignore frags from uninitialized peer in dp + +In certain scenario, fragmented packet is received for self peer, +for which rx_tid and rx_frags are not initialized in datapath. +While handling this fragment, crash is observed as the +rx_frag list is uninitialised and when we walk in +ath11k_dp_rx_h_sort_frags, skb null leads to exception. + +To address this, before processing received fragments we +check dp_setup_done flag is set to ensure that peer +has completed its dp peer setup for fragment queue, +else ignore processing the fragments. + +Also, __fls would have an undefined behavior if the argument +is passed as "0". Hence, added changes to handle the same. + +Below is the call trace of the crash: + + CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.4.164 #0 + Hardware name: Qualcomm Technologies, Inc. IPQ6018/AP-CP01-C1 (DT) + pstate: a0400005 (NzCv daif +PAN -UAO) + pc : ath11k_dp_process_rx_err+0x550/0x1084 [ath11k] + lr : ath11k_dp_process_rx_err+0x4e0/0x1084 [ath11k] + + Call trace: + ath11k_dp_process_rx_err+0x550/0x1084 [ath11k] + ath11k_dp_service_srng+0x70/0x370 [ath11k] + 0xffffffc009693a04 + __napi_poll+0x30/0xa4 + net_rx_action+0x118/0x270 + __do_softirq+0x10c/0x244 + irq_exit+0x64/0xb4 + __handle_domain_irq+0x88/0xac + gic_handle_irq+0x74/0xbc + el1_irq+0xf0/0x1c0 + arch_cpu_idle+0x10/0x18 + do_idle+0x104/0x248 + cpu_startup_entry+0x20/0x64 + rest_init+0xd0/0xdc + arch_call_rest_init+0xc/0x14 + start_kernel+0x480/0x4b8 + Code: f9400281 f94066a2 91405021 b94a0023 (f9406401) + +Signed-off-by: Harshitha Prem +Signed-off-by: Nagarajan Maran +--- + drivers/net/wireless/ath/ath11k/dp.c | 3 ++- + drivers/net/wireless/ath/ath11k/dp_rx.c | 11 ++++++++++- + drivers/net/wireless/ath/ath11k/peer.h | 2 ++ + 3 files changed, 14 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/dp.c ++++ b/drivers/net/wireless/ath/ath11k/dp.c +@@ -38,6 +38,7 @@ void ath11k_dp_peer_cleanup(struct ath11 + ath11k_peer_rx_tid_cleanup(ar, peer); + peer->dp_setup_done = false; + crypto_free_shash(peer->tfm_mmic); ++ peer->dp_setup_done = false; + spin_unlock_bh(&ab->base_lock); + } + +--- a/drivers/net/wireless/ath/ath11k/peer.h ++++ b/drivers/net/wireless/ath/ath11k/peer.h +@@ -92,6 +92,7 @@ struct ath11k_peer { + u16 sec_type; + u16 sec_type_grp; + bool is_authorized; ++ /* Peer's datapath set flag */ + bool dp_setup_done; + struct ppdu_user_delayba ppdu_stats_delayba; + bool delayba_flag; diff --git a/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch b/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch new file mode 100644 index 00000000000000..e1d407e57d2e6f --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch @@ -0,0 +1,85 @@ +From c7e37aebbe19056eb7b61299e75c863263acf2b9 Mon Sep 17 00:00:00 2001 +From: Nagarajan Maran +Date: Tue, 9 Aug 2022 13:22:43 +0530 +Subject: [PATCH] Fix SKB corruption in REO destination ring + +In the traffic cases, randomly, invalid RX descriptor +from REO destination ring is received. This +invalid descriptor causes wrong SKB to be fetched +which in turn causes SKB memory corruption issue. + +Introduced Sanity check to validate the descriptor, +before processing the SKB. + +During the failure scenario, invalid RX descriptor +filled with values "0" is received which in-turn +corrupts the SKB stored in the ldr lookup +with buffer id "0". Changed the start id for +idr allocation to "1" and the buffer id "0" is +reserved for error validation. + + +Crash Signature : + +Unable to handle kernel paging request at virtual address 3f004900 +During the crash, +PC points to "b15_dma_inv_range+0x30/0x50" +LR points to "dma_cache_maint_page+0x8c/0x128". +The Backtrace obtained is as follows: +[<8031716c>] (b15_dma_inv_range) from [<80313a4c>] (dma_cache_maint_page+0x8c/0x128) +[<80313a4c>] (dma_cache_maint_page) from [<80313b90>] (__dma_page_dev_to_cpu+0x28/0xcc) +[<80313b90>] (__dma_page_dev_to_cpu) from [<7fb5dd68>] (ath11k_dp_process_rx+0x1e8/0x4a4 [ath11k]) +[<7fb5dd68>] (ath11k_dp_process_rx [ath11k]) from [<7fb53c20>] (ath11k_dp_service_srng+0xb0/0x2ac [ath11k]) +[<7fb53c20>] (ath11k_dp_service_srng [ath11k]) from [<7f67bba4>] (ath11k_pci_ext_grp_napi_poll+0x1c/0x78 [ath11k_pci]) +[<7f67bba4>] (ath11k_pci_ext_grp_napi_poll [ath11k_pci]) from [<807d5cf4>] (__napi_poll+0x28/0xb8) +[<807d5cf4>] (__napi_poll) from [<807d5f28>] (net_rx_action+0xf0/0x280) +[<807d5f28>] (net_rx_action) from [<80302148>] (__do_softirq+0xd0/0x280) +[<80302148>] (__do_softirq) from [<80320408>] (irq_exit+0x74/0xd4) +[<80320408>] (irq_exit) from [<803638a4>] (__handle_domain_irq+0x90/0xb4) +[<803638a4>] (__handle_domain_irq) from [<805bedec>] (gic_handle_irq+0x58/0x90) +[<805bedec>] (gic_handle_irq) from [<80301a78>] (__irq_svc+0x58/0x8c) + +Signed-off-by: Nagarajan Maran +--- + drivers/net/wireless/ath/ath11k/dp_rx.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -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; +@@ -3134,6 +3134,16 @@ try_again: + while (likely(desc = + (struct hal_reo_dest_ring *)ath11k_hal_srng_dst_get_next_entry(ab, + srng))) { ++ ++ push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON, ++ desc->info0); ++ if (unlikely(push_reason == ++ HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED)) { ++ ath11k_warn(ab,"Received invalid desc\n"); ++ ab->soc_stats.hal_reo_error[dp->reo_dst_ring[ring_id].ring_id]++; ++ continue; ++ } ++ + cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, + desc->buf_addr_info.info1); + buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID, +@@ -3164,8 +3174,6 @@ try_again: + + num_buffs_reaped[mac_id]++; + +- push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON, +- desc->info0); + if (unlikely(push_reason != + HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION)) { + dev_kfree_skb_any(msdu); 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 00000000000000..fd4f0938cdb83b --- /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 +@@ -1501,6 +1501,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 +@@ -1323,7 +1323,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; + +@@ -1404,6 +1404,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, +@@ -1415,6 +1417,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/nss/ath11k/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 new file mode 100644 index 00000000000000..832a7d92b35a0a --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch @@ -0,0 +1,384 @@ +From 17d1895bad45ec2ef4c8c430ac0fbaff2ff1cf39 Mon Sep 17 00:00:00 2001 +From: Manish Dharanenthiran +Date: Tue, 18 Apr 2023 15:01:42 +0530 +Subject: [PATCH 2/3] CHROMIUM: ath11k: Add retry mechanism for update_rx_queue + reo cmd + +While reo_cmd ring is full, peer delete update rx queue +will be failed as there is no space to send the command +in ring. During the failure scenario, host will do +dma_unmap and free the allocated address but the HW +still have that particular vaddr. So, on next alloc +cycle kernel will allocated the freed addr but HW will +still have the address. This will result in memory +corruption as the host will try to access/write that +memory which is already in-use. + +To avoid this corruption, added new retry mechanism +for HAL_REO_CMD_UPDATE_RX_QUEUE by adding new list to +dp struct and protecting with new lock for access. +This avoids the host free in failure case and will +be freed only when HW freed that particular vaddr. + +Also, updated below changes +1) reo_flush command for sending 1K desc in one +command instead of sending 11 command for single +TID. + +2) Set FWD_MPDU and valid bit flag so that reo +flush will happen soon instead of waiting to +flush the queue. + +Signed-off-by: Manish Dharanenthiran +Signed-off-by: Tamizh Chelvam Raja +--- + drivers/net/wireless/ath/ath11k/core.h | 3 + + drivers/net/wireless/ath/ath11k/debugfs.c | 12 ++ + drivers/net/wireless/ath/ath11k/dp.c | 2 + + drivers/net/wireless/ath/ath11k/dp.h | 15 ++ + drivers/net/wireless/ath/ath11k/dp_rx.c | 167 +++++++++++++++++----- + 5 files changed, 161 insertions(+), 38 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -1176,6 +1176,9 @@ struct ath11k_soc_dp_stats { + u32 reo_error[HAL_REO_DEST_RING_ERROR_CODE_MAX]; + u32 reo_error_drop[HAL_REO_DEST_RING_ERROR_CODE_MAX]; + u32 hal_reo_error[DP_REO_DST_RING_MAX]; ++ u32 hal_reo_cmd_drain; ++ u32 reo_cmd_cache_error; ++ u32 reo_cmd_update_rx_queue_error; + struct ath11k_soc_dp_tx_err_stats tx_err; + struct ath11k_dp_ring_bp_stats bp_stats; + }; +--- a/drivers/net/wireless/ath/ath11k/debugfs.c ++++ b/drivers/net/wireless/ath/ath11k/debugfs.c +@@ -1416,6 +1416,18 @@ static ssize_t ath11k_debugfs_dump_soc_d + "\nNSS Transmit Failures: %d\n", + atomic_read(&soc_stats->tx_err.nss_tx_fail)); + ++ len += scnprintf(buf + len, size - len, ++ "\nHAL_REO_CMD_DRAIN Counter: %u\n", ++ soc_stats->hal_reo_cmd_drain); ++ ++ len += scnprintf(buf + len, size - len, ++ "\nREO_CMD_CACHE_FLUSH Failure: %u\n", ++ soc_stats->reo_cmd_cache_error); ++ ++ len += scnprintf(buf + len, size - len, ++ "\nREO_CMD_UPDATE_RX_QUEUE Failure: %u\n", ++ soc_stats->reo_cmd_update_rx_queue_error); ++ + len += ath11k_debugfs_dump_soc_ring_bp_stats(ab, buf + len, size - len); + + if (len > size) +--- a/drivers/net/wireless/ath/ath11k/dp.c ++++ b/drivers/net/wireless/ath/ath11k/dp.c +@@ -1185,8 +1185,10 @@ int ath11k_dp_alloc(struct ath11k_base * + + INIT_LIST_HEAD(&dp->reo_cmd_list); + INIT_LIST_HEAD(&dp->reo_cmd_cache_flush_list); ++ INIT_LIST_HEAD(&dp->reo_cmd_update_rx_queue_list); + INIT_LIST_HEAD(&dp->dp_full_mon_mpdu_list); + spin_lock_init(&dp->reo_cmd_lock); ++ spin_lock_init(&dp->reo_cmd_update_queue_lock); + + dp->reo_cmd_cache_flush_count = 0; + +--- a/drivers/net/wireless/ath/ath11k/dp.h ++++ b/drivers/net/wireless/ath/ath11k/dp.h +@@ -24,6 +24,7 @@ struct dp_rx_tid { + u32 *vaddr; + dma_addr_t paddr; + u32 size; ++ u32 pending_desc_size; + u32 ba_win_sz; + bool active; + +@@ -53,6 +54,14 @@ struct dp_reo_cache_flush_elem { + unsigned long ts; + }; + ++struct dp_reo_update_rx_queue_elem { ++ struct list_head list; ++ struct dp_rx_tid data; ++ int peer_id; ++ u8 tid; ++ bool reo_cmd_update_rx_queue_resend_flag; ++}; ++ + struct dp_reo_cmd { + struct list_head list; + struct dp_rx_tid data; +@@ -298,6 +307,12 @@ struct ath11k_dp { + * - reo_cmd_cache_flush_count + */ + spinlock_t reo_cmd_lock; ++ struct list_head reo_cmd_update_rx_queue_list; ++ /** ++ * protects access to below field, ++ * - reo_cmd_update_rx_queue_list ++ */ ++ spinlock_t reo_cmd_update_queue_lock; + struct ath11k_hp_update_timer reo_cmd_timer; + struct ath11k_hp_update_timer tx_ring_timer[DP_TCL_NUM_RING_MAX]; + +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -22,6 +22,9 @@ + + #define ATH11K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ) + ++static void ath11k_dp_rx_tid_del_func(struct ath11k_dp *dp, void *ctx, ++ enum hal_reo_cmd_status status); ++ + static inline + u8 *ath11k_dp_rx_h_80211_hdr(struct ath11k_base *ab, struct hal_rx_desc *desc) + { +@@ -729,13 +732,50 @@ static int ath11k_dp_rx_pdev_srng_alloc( + return 0; + } + ++static int ath11k_peer_rx_tid_delete_handler(struct ath11k_base *ab, ++ struct dp_rx_tid *rx_tid, u8 tid) ++{ ++ struct ath11k_hal_reo_cmd cmd = {0}; ++ struct ath11k_dp *dp = &ab->dp; ++ ++ lockdep_assert_held(&dp->reo_cmd_update_queue_lock); ++ ++ rx_tid->active = false; ++ cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; ++ cmd.addr_lo = lower_32_bits(rx_tid->paddr); ++ cmd.addr_hi = upper_32_bits(rx_tid->paddr); ++ cmd.upd0 |= HAL_REO_CMD_UPD0_VLD; ++ ++ return ath11k_dp_tx_send_reo_cmd(ab, rx_tid, ++ HAL_REO_CMD_UPDATE_RX_QUEUE, ++ &cmd, ++ ath11k_dp_rx_tid_del_func); ++} ++ + void ath11k_dp_reo_cmd_list_cleanup(struct ath11k_base *ab) + { + struct ath11k_dp *dp = &ab->dp; + struct dp_reo_cmd *cmd, *tmp; + struct dp_reo_cache_flush_elem *cmd_cache, *tmp_cache; ++ struct dp_reo_update_rx_queue_elem *cmd_queue, *tmp_queue; + struct dp_rx_tid *rx_tid; + ++ spin_lock_bh(&dp->reo_cmd_update_queue_lock); ++ list_for_each_entry_safe(cmd_queue, tmp_queue, ++ &dp->reo_cmd_update_rx_queue_list, ++ list) { ++ list_del(&cmd_queue->list); ++ rx_tid = &cmd_queue->data; ++ if (rx_tid->vaddr) { ++ dma_unmap_single(ab->dev, rx_tid->paddr, ++ rx_tid->size, DMA_BIDIRECTIONAL); ++ kfree(rx_tid->vaddr); ++ rx_tid->vaddr = NULL; ++ } ++ kfree(cmd_queue); ++ } ++ spin_unlock_bh(&dp->reo_cmd_update_queue_lock); ++ + spin_lock_bh(&dp->reo_cmd_lock); + list_for_each_entry_safe(cmd, tmp, &dp->reo_cmd_list, list) { + list_del(&cmd->list); +@@ -781,14 +821,18 @@ static void ath11k_dp_reo_cmd_free(struc + } + } + +-static void ath11k_dp_reo_cache_flush(struct ath11k_base *ab, ++static int ath11k_dp_reo_cache_flush(struct ath11k_base *ab, + struct dp_rx_tid *rx_tid) + { + struct ath11k_hal_reo_cmd cmd = {0}; + unsigned long tot_desc_sz, desc_sz; + int ret; + +- tot_desc_sz = rx_tid->size; ++ if (rx_tid->pending_desc_size) ++ tot_desc_sz = rx_tid->pending_desc_size; ++ else ++ tot_desc_sz = rx_tid->size; ++ + desc_sz = ath11k_hal_reo_qdesc_size(0, HAL_DESC_REO_NON_QOS_TID); + + while (tot_desc_sz > desc_sz) { +@@ -799,11 +843,17 @@ static void ath11k_dp_reo_cache_flush(st + HAL_REO_CMD_FLUSH_CACHE, &cmd, + NULL); + if (ret) +- ath11k_warn(ab, +- "failed to send HAL_REO_CMD_FLUSH_CACHE, tid %d (%d)\n", +- rx_tid->tid, ret); ++ rx_tid->pending_desc_size = tot_desc_sz + desc_sz; ++ ++ /* If this fails with ring full condition, then ++ * no need to retry below as it is expected to ++ * fail within short time ++ */ ++ if (ret == -ENOBUFS) ++ goto exit; + } + ++ rx_tid->pending_desc_size = desc_sz; + memset(&cmd, 0, sizeof(cmd)); + cmd.addr_lo = lower_32_bits(rx_tid->paddr); + cmd.addr_hi = upper_32_bits(rx_tid->paddr); +@@ -811,24 +861,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); +- if (ret) { +- ath11k_err(ab, "failed to send HAL_REO_CMD_FLUSH_CACHE cmd, tid %d (%d)\n", +- rx_tid->tid, ret); +- dma_unmap_single(ab->dev, rx_tid->paddr, rx_tid->size, +- DMA_BIDIRECTIONAL); +- kfree(rx_tid->vaddr); +- rx_tid->vaddr = NULL; +- } ++ ++exit: ++ return ret; + } + + static void ath11k_dp_rx_tid_del_func(struct ath11k_dp *dp, void *ctx, + enum hal_reo_cmd_status status) + { + struct ath11k_base *ab = dp->ab; +- struct dp_rx_tid *rx_tid = ctx; ++ struct dp_rx_tid *rx_tid = ctx, *update_rx_tid; + struct dp_reo_cache_flush_elem *elem, *tmp; ++ struct dp_reo_update_rx_queue_elem *qelem, *qtmp; + + if (status == HAL_REO_CMD_DRAIN) { ++ ab->soc_stats.hal_reo_cmd_drain++; + goto free_desc; + } else if (status != HAL_REO_CMD_SUCCESS) { + /* Shouldn't happen! Cleanup in case of other failure? */ +@@ -837,6 +884,29 @@ static void ath11k_dp_rx_tid_del_func(st + return; + } + ++ /* Check if there is any pending rx_queue, if yes then update it */ ++ spin_lock_bh(&dp->reo_cmd_update_queue_lock); ++ list_for_each_entry_safe(qelem, qtmp, &dp->reo_cmd_update_rx_queue_list, ++ list) { ++ if (qelem->reo_cmd_update_rx_queue_resend_flag && ++ qelem->data.active) { ++ update_rx_tid = &qelem->data; ++ ++ if (ath11k_peer_rx_tid_delete_handler(ab, update_rx_tid, qelem->tid)) { ++ update_rx_tid->active = true; ++ break; ++ } ++ update_rx_tid->vaddr = NULL; ++ update_rx_tid->paddr = 0; ++ update_rx_tid->size = 0; ++ update_rx_tid->pending_desc_size = 0; ++ ++ list_del(&qelem->list); ++ kfree(qelem); ++ } ++ } ++ spin_unlock_bh(&dp->reo_cmd_update_queue_lock); ++ + elem = kzalloc(sizeof(*elem), GFP_ATOMIC); + if (!elem) + goto free_desc; +@@ -854,13 +924,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))) { ++ spin_unlock_bh(&dp->reo_cmd_lock); ++ if (ath11k_dp_reo_cache_flush(ab, &elem->data)) { ++ ab->soc_stats.reo_cmd_cache_error++; ++ /* In failure case, just update the timestamp ++ * for flush cache elem and continue ++ */ ++ spin_lock_bh(&dp->reo_cmd_lock); ++ elem->ts = jiffies; ++ break; ++ } ++ spin_lock_bh(&dp->reo_cmd_lock); + list_del(&elem->list); + dp->reo_cmd_cache_flush_count--; +- spin_unlock_bh(&dp->reo_cmd_lock); +- +- ath11k_dp_reo_cache_flush(ab, &elem->data); + kfree(elem); +- spin_lock_bh(&dp->reo_cmd_lock); + } + } + spin_unlock_bh(&dp->reo_cmd_lock); +@@ -876,34 +953,48 @@ free_desc: + void ath11k_peer_rx_tid_delete(struct ath11k *ar, + struct ath11k_peer *peer, u8 tid) + { +- struct ath11k_hal_reo_cmd cmd = {0}; + struct dp_rx_tid *rx_tid = &peer->rx_tid[tid]; +- int ret; ++ struct dp_reo_update_rx_queue_elem *elem, *tmp; ++ struct ath11k_base *ab = ar->ab; ++ struct ath11k_dp *dp = &ab->dp; + + if (!rx_tid->active) + return; + +- rx_tid->active = false; ++ elem = kzalloc(sizeof(*elem), GFP_ATOMIC); ++ if (!elem) { ++ ath11k_warn(ar->ab, "failed to alloc reo_update_rx_queue_elem, rx tid %d\n", ++ rx_tid->tid); ++ return; ++ } ++ elem->reo_cmd_update_rx_queue_resend_flag = false; ++ elem->peer_id = peer->peer_id; ++ elem->tid = tid; ++ memcpy(&elem->data, rx_tid, sizeof(*rx_tid)); ++ spin_lock_bh(&dp->reo_cmd_update_queue_lock); ++ list_add_tail(&elem->list, &dp->reo_cmd_update_rx_queue_list); + +- cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; +- cmd.addr_lo = lower_32_bits(rx_tid->paddr); +- cmd.addr_hi = upper_32_bits(rx_tid->paddr); +- cmd.upd0 |= HAL_REO_CMD_UPD0_VLD; +- ret = ath11k_dp_tx_send_reo_cmd(ar->ab, rx_tid, +- HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, +- ath11k_dp_rx_tid_del_func); +- if (ret) { +- if (ret != -ESHUTDOWN) +- ath11k_err(ar->ab, "failed to send HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n", +- tid, ret); +- dma_unmap_single(ar->ab->dev, rx_tid->paddr, rx_tid->size, +- DMA_BIDIRECTIONAL); +- kfree(rx_tid->vaddr); ++ list_for_each_entry_safe(elem, tmp, &dp->reo_cmd_update_rx_queue_list, ++ list) { ++ rx_tid = &elem->data; ++ ++ if (ath11k_peer_rx_tid_delete_handler(ab, rx_tid, elem->tid)) { ++ rx_tid->active = true; ++ ab->soc_stats.reo_cmd_update_rx_queue_error++; ++ elem->reo_cmd_update_rx_queue_resend_flag = true; ++ break; ++ } + rx_tid->vaddr = NULL; ++ rx_tid->paddr = 0; ++ rx_tid->size = 0; ++ rx_tid->pending_desc_size = 0; ++ ++ list_del(&elem->list); ++ kfree(elem); + } ++ spin_unlock_bh(&dp->reo_cmd_update_queue_lock); + +- rx_tid->paddr = 0; +- rx_tid->size = 0; ++ return; + } + + static int ath11k_dp_rx_link_desc_return(struct ath11k_base *ab, diff --git a/package/kernel/mac80211/patches/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch b/package/kernel/mac80211/patches/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch new file mode 100644 index 00000000000000..144d5a9ca4d36c --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch @@ -0,0 +1,49 @@ +From c9bcb26f30a1b2e3434d851aea19200a6d757cca Mon Sep 17 00:00:00 2001 +From: Aaradhana Sahu +Date: Sat, 3 Jun 2023 18:33:54 +0530 +Subject: [PATCH] ath11k: fix VLC streaming not working for wan to wlan when + multicast to unicast flag enable + +Currently, additional two bytes after 802.11 header are seen on the air. +When per-packet encap mode is native wifi and vdev level encap mode is +eth mode, native wifi encap functionality is skipped. + +This leaves QoS header unremoved in the 802.11 header of the packet. When +sending the packet HW will also add (one more) QoS header. The additional +two bytes before LLC/SNAP header confuses the receiver and those packets +will get dropped at receiver. + +Fix this issue by removing QoS header (native wifi encap functionality) +for all the packets which will be enqueued to hw in native wifi mode. + +Signed-off-by: Aaradhana Sahu +--- + drivers/net/wireless/ath/ath11k/dp_tx.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.c b/drivers/net/wireless/ath/ath11k/dp_tx.c +index 3d8417d..5c034e6 100644 +--- a/drivers/net/wireless/ath/ath11k/dp_tx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_tx.c +@@ -347,7 +347,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)) + is_diff_encap = true; + else + ath11k_dp_tx_encap_nwifi(skb); +@@ -375,7 +376,7 @@ tcl_ring_sel: + if ((!test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) && + !(info->control.flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && + !info->control.hw_key && ieee80211_has_protected(hdr->frame_control)) || +- (skb->protocol == cpu_to_be16(ETH_P_PAE) && is_diff_encap)) { ++ is_diff_encap) { + /* HW requirement is that metadata should always point to a + * 8-byte aligned address. So we add alignment pad to start of + * buffer. HTT Metadata should be ensured to be multiple of 8-bytes +-- +2.17.1 + diff --git a/package/kernel/mac80211/patches/nss/ath11k/702-ath11k-fix-memory-leak-in-dp-rx.patch b/package/kernel/mac80211/patches/nss/ath11k/702-ath11k-fix-memory-leak-in-dp-rx.patch deleted file mode 100644 index 250112c55a89c4..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -2663,8 +2663,6 @@ static void ath11k_dp_rx_h_mpdu(struct a - } - } - -- *fast_rx = false; -- - if (rxcb->is_mcbc) - enctype = peer->sec_type_grp; - else -@@ -2674,6 +2672,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/nss/ath11k/830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch b/package/kernel/mac80211/patches/nss/ath11k/830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch new file mode 100644 index 00000000000000..de7f697c7ccb7c --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch @@ -0,0 +1,87 @@ +From 5b4a0de1356558f58df9c6a1f46c7c0ce2fadb03 Mon Sep 17 00:00:00 2001 +From: Yuvasree Sivasankaran +Date: Mon, 28 Aug 2023 14:48:41 +0530 +Subject: [PATCH] ath11k: Avoiding memset of ppdu-info for next skb + +While parsing mon status from skb, ppdu_info got memset with zero during +next skb fetch from queue or mon ring in case a single PPDU is more than +RX_BUFFER_SIZE. Because of this nss value got override for respective +ppdu and leads to warn_on in mac80211.Removed memset from next skb fetch +and added flag to track discontinued skb in case of fetch from skb. + +WARN_ON Reason: + +Rate marked as an HE rate but data is invalid: MCS: 0, NSS: 0 + +Below the call trace observed: + + Call trace: + ieee80211_rx_list+0x1d4/0xcc4 [mac80211] + ieee80211_rx_napi+0x58/0xcc [mac80211] + ath11k_dp_rx_deliver_msdu+0x358/0x3e4 [ath11k] + ath11k_dp_rx_mon_deliver.isra.27+0x470/0x4cc [ath11k] + ath11k_dp_rx_mon_dest_process+0x1cc/0x2bc [ath11k] + ath11k_dp_rx_process_mon_status+0x5ec/0xf90 [ath11k] + ath11k_dp_rx_process_mon_rings+0x40c/0x44c [ath11k] + ath11k_dp_service_srng+0x114/0x2c0 [ath11k] + ath11k_ahb_ext_grp_napi_poll+0x30/0xa0 [ath11k_ahb] + __napi_poll+0x30/0xa4 + net_rx_action+0x118/0x270 + __do_softirq+0x10c/0x244 + irq_exit+0x64/0xb4 + __handle_domain_irq+0x88/0xac + gic_handle_irq+0x74/0xbc + el1_irq+0xf0/0x1c0 + arch_cpu_idle+0x10/0x18 + do_idle+0x104/0x248 + cpu_startup_entry+0x20/0x64 + rest_init+0xd0/0xdc + arch_call_rest_init+0xc/0x14 + start_kernel+0x46c/0x4a4 + --[ end trace e754e9088a240857 ]--- + +Signed-off-by: Yuvasree Sivasankaran +--- + drivers/net/wireless/ath/ath11k/dp_rx.c | 6 ++++-- + drivers/net/wireless/ath/ath11k/hal_rx.h | 1 + + 2 files changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -6292,7 +6292,9 @@ int ath11k_dp_rx_process_mon_status(stru + if (!num_buffs_reaped) + goto exit; + +- memset(ppdu_info, 0, sizeof(*ppdu_info)); ++ if (!ppdu_info->ppdu_continuation) ++ memset(ppdu_info, 0, sizeof(*ppdu_info)); ++ + ppdu_info->peer_id = HAL_INVALID_PEERID; + + while ((skb = __skb_dequeue(&skb_list))) { +@@ -6310,7 +6312,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); + +- memset(ppdu_info, 0, sizeof(*ppdu_info)); + ppdu_info->peer_id = HAL_INVALID_PEERID; + hal_status = ath11k_hal_rx_parse_mon_status(ab, ppdu_info, skb); + +@@ -6326,6 +6327,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; + } + +--- a/drivers/net/wireless/ath/ath11k/hal_rx.h ++++ b/drivers/net/wireless/ath/ath11k/hal_rx.h +@@ -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]; + 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/nss/ath11k/906-456-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch b/package/kernel/mac80211/patches/nss/ath11k/906-456-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch index 92fb2195806f2d..04d842e96a107b 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/906-456-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/906-456-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch @@ -18,12 +18,11 @@ Signed-off-by: Karthikeyan Periyasamy --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -@@ -221,7 +221,9 @@ tcl_ring_sel: - +@@ -217,7 +217,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) && + if ((arvif->vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) && +- skb->protocol == cpu_to_be16(ETH_P_PAE)) + (skb->protocol == cpu_to_be16(ETH_P_PAE) || + ieee80211_is_qos_nullfunc(hdr->frame_control))) is_diff_encap = true; 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 00000000000000..f5301ca9e4890f --- /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 +@@ -8232,7 +8232,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); + +@@ -8255,21 +8254,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/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 00000000000000..3bcf93279c5a2f --- /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 +@@ -1919,7 +1919,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 +@@ -1664,8 +1664,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; +@@ -2105,7 +2107,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" +@@ -551,7 +553,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; +@@ -640,8 +644,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 +@@ -9869,7 +9869,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/nss/subsys/199-001-mac80211-add-nss-support.patch b/package/kernel/mac80211/patches/nss/subsys/199-001-mac80211-add-nss-support.patch index dc539711a5bba5..1c508dc8884c96 100644 --- a/package/kernel/mac80211/patches/nss/subsys/199-001-mac80211-add-nss-support.patch +++ b/package/kernel/mac80211/patches/nss/subsys/199-001-mac80211-add-nss-support.patch @@ -123,7 +123,7 @@ Signed-off-by: Sriram R - + 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, 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 00000000000000..db6550ab79c2cc --- /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 +@@ -9229,4 +9229,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 +@@ -7353,6 +7353,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 */ +@@ -2818,6 +2823,8 @@ enum nl80211_commands { + * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce + * transmit power to stay within regulatory limits. u32, dBi. + * ++ * @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 +@@ -3358,6 +3365,8 @@ enum nl80211_attrs { + + NL80211_ATTR_WIPHY_ANTENNA_GAIN, + ++ 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 +@@ -7910,3 +7910,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 +@@ -3085,6 +3085,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 +@@ -20170,6 +20170,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/nss/subsys/234-002-mac80211-account-tx-rx-packets-flow.patch b/package/kernel/mac80211/patches/nss/subsys/234-002-mac80211-account-tx-rx-packets-flow.patch deleted file mode 100644 index 7488f0c2bfce6b..00000000000000 --- a/package/kernel/mac80211/patches/nss/subsys/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/nss/subsys/235-001-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 index 14869c1e2cb340..cf3784afa29b2a 100644 --- a/package/kernel/mac80211/patches/nss/subsys/235-001-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 @@ -137,6 +137,22 @@ Signed-off-by: Sathishkumar Muruganandam { --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c +@@ -4298,8 +4298,13 @@ 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 && + !is_multicast_ether_addr(skb->data)) { + if (sta) @@ -4692,7 +4692,8 @@ static void ieee80211_8023_xmit(struct i info->hw_queue = sdata->vif.hw_queue[queue]; diff --git a/package/kernel/mac80211/patches/nss/subsys/235-002-mac80211-Add-support-for-beacon-tx-mode.patch b/package/kernel/mac80211/patches/nss/subsys/235-002-mac80211-Add-support-for-beacon-tx-mode.patch new file mode 100644 index 00000000000000..b500d000a19004 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/subsys/235-002-mac80211-Add-support-for-beacon-tx-mode.patch @@ -0,0 +1,174 @@ +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 = 1 for STAGGERED beacon mode +and N = 2 for BURST beacon mode, default is STAGGERED mode +"N = 0". + +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 +@@ -1440,6 +1440,7 @@ struct cfg80211_unsol_bcast_probe_resp { + * @fils_discovery: FILS discovery transmission parameters + * @unsol_bcast_probe_resp: Unsolicited broadcast probe response parameters + * @mbssid_config: AP settings for multiple bssid ++ * @beacon_tx_mode: Beacon Tx Mode setting + * @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. +@@ -1477,6 +1478,7 @@ struct cfg80211_ap_settings { + struct cfg80211_fils_discovery fils_discovery; + struct cfg80211_unsol_bcast_probe_resp unsol_bcast_probe_resp; + struct cfg80211_mbssid_config mbssid_config; ++ enum nl80211_beacon_tx_mode beacon_tx_mode; + u16 punct_bitmap; + }; + +@@ -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 +@@ -656,6 +656,7 @@ struct ieee80211_fils_discovery { + * @tx_pwr_env_num: number of @tx_pwr_env. + * @pwr_reduction: power constraint of BSS. + * @eht_support: does this BSS support EHT ++ * @beacon_tx_mode: Beacon Tx Mode setting. + * @eht_puncturing: bitmap to indicate which channels are punctured in this BSS + * @csa_active: marks whether a channel switch is going on. Internally it is + * write-protected by sdata_lock and local->mtx so holding either is fine +@@ -766,6 +767,7 @@ struct ieee80211_bss_conf { + u8 tx_pwr_env_num; + u8 pwr_reduction; + bool eht_support; ++ enum nl80211_beacon_tx_mode beacon_tx_mode; + u16 eht_puncturing; + + bool csa_active; +--- a/include/uapi/linux/nl80211.h ++++ b/include/uapi/linux/nl80211.h +@@ -2758,6 +2758,13 @@ enum nl80211_commands { + * association request when used with NL80211_CMD_NEW_STATION). Can be set + * only if %NL80211_STA_FLAG_WME is set. + * ++ * @NL80211_ATTR_BEACON_TX_MODE: used to configure the beacon tx mode (u32), ++ * as specified in the &enum nl80211_beacon_tx_mode. The user-space ++ * can use this attribute to configure the tx mode of beacons. ++ * Beacons can be sent out in burst(continuously in a single shot ++ * one after another) or staggered (equally spread out over beacon ++ * interval) mode. ++ * + * @NL80211_ATTR_MLO_LINK_ID: A (u8) link ID for use with MLO, to be used with + * various commands that need a link ID to operate. + * @NL80211_ATTR_MLO_LINKS: A nested array of links, each containing some +@@ -3362,6 +3369,8 @@ enum nl80211_attrs { + + NL80211_ATTR_HE_MUEDCA_PARAMS, + ++ NL80211_ATTR_BEACON_TX_MODE, ++ + /* add attributes here, update the policy in nl80211.c */ + + __NL80211_ATTR_AFTER_LAST, +@@ -7849,4 +7858,16 @@ enum nl80211_ap_settings_flags { + NL80211_AP_SETTINGS_SA_QUERY_OFFLOAD_SUPPORT = 1 << 1, + }; + ++/** ++ * enum nl80211_beacon_tx_mode - Beacon Tx Mode enum. ++ * @NL80211_BEACON_STAGGERED_MODE: Used to configure beacon tx mode as ++ * staggered mode. This is the default beacon tx mode. ++ * @NL80211_BEACON_BURST_MODE: Used to configure beacon tx mode as burst mode. ++ */ ++enum nl80211_beacon_tx_mode { ++ NL80211_BEACON_DEFAULT_MODE = 0, ++ 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 = +@@ -2496,6 +2497,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 +@@ -796,8 +796,11 @@ static const struct nla_policy nl80211_p + [NL80211_ATTR_AP_SETTINGS_FLAGS] = { .type = NLA_U32 }, + [NL80211_ATTR_EHT_CAPABILITY] = + NLA_POLICY_BINARY_RANGE(NL80211_EHT_MIN_CAPABILITY_LEN, NL80211_EHT_MAX_CAPABILITY_LEN), +- [NL80211_ATTR_DISABLE_EHT] = { .type = NLA_FLAG }, +- [NL80211_ATTR_MLO_LINKS] = ++ [NL80211_ATTR_DISABLE_EHT] = { .type = NLA_FLAG }, ++ [NL80211_ATTR_BEACON_TX_MODE] = ++ NLA_POLICY_RANGE(NLA_U32, NL80211_BEACON_STAGGERED_MODE, ++ NL80211_BEACON_BURST_MODE), ++ [NL80211_ATTR_MLO_LINKS] = + NLA_POLICY_NESTED_ARRAY(nl80211_policy), + [NL80211_ATTR_MLO_LINK_ID] = + NLA_POLICY_RANGE(NLA_U8, 0, IEEE80211_MLD_MAX_NUM_LINKS), +@@ -5942,6 +5945,10 @@ static int nl80211_start_ap(struct sk_bu + 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); + if (err) +@@ -13037,6 +13044,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/nss/subsys/236-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 index e6bafbbb367458..453f516497a5b5 100644 --- a/package/kernel/mac80211/patches/nss/subsys/236-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 @@ -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 +@@ -4654,16 +4654,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/nss/subsys/245-compilation_fix.patch b/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch index 2fe7a853e719b7..2503fa030c946c 100644 --- a/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch +++ b/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch @@ -30,7 +30,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran struct ieee80211_local *local; --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4668,19 +4668,21 @@ static void ieee80211_8023_xmit(struct i +@@ -4676,19 +4676,21 @@ static void ieee80211_8023_xmit(struct i ieee80211_aggr_check(sdata, sta, skb); @@ -64,7 +64,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran } skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); -@@ -4740,7 +4742,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4745,7 +4747,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; @@ -73,7 +73,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran struct sta_info *sta; #ifdef CPTCFG_MAC80211_NSS_SUPPORT -@@ -4758,9 +4760,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4763,9 +4765,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 goto out; } @@ -90,7 +90,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran goto skip_offload; key = rcu_dereference(sta->ptk[sta->ptk_idx]); -@@ -4771,6 +4777,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4776,6 +4782,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); @@ -98,14 +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 -@@ -5348,7 +5348,7 @@ void ieee80211_rx_list(struct ieee80211_ +@@ -6282,13 +6289,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); - } + 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); +- else +- __ieee80211_subif_start_xmit(skb, skb->dev, flags, ctrl_flags, cookie); +- ++ __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/nss/subsys/300-ath11k-nss-mesh-offload-support.patch b/package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch index aaa9b285b46c7c..5e0a156312fe4e 100644 --- a/package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch +++ b/package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch @@ -67,18 +67,18 @@ Signed-off-by: Gautham Kumar Senthilkumaran /* @@ -792,6 +801,11 @@ struct ieee80211_bss_conf { + bool he_full_ul_mumimo; + bool eht_su_beamformer; bool eht_su_beamformee; - bool eht_mu_beamformer; - bool nss_ap_isolate; + + /* 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; }; - - /** -@@ -1271,6 +1285,8 @@ struct ieee80211_rate_status { +@@ -1273,6 +1287,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; -@@ -1281,6 +1297,8 @@ struct ieee80211_tx_status { +@@ -1283,6 +1299,8 @@ struct ieee80211_tx_status { u8 n_rates; struct list_head *free_list; @@ -96,7 +96,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran }; /** -@@ -1773,6 +1791,7 @@ struct ieee80211_channel_switch { +@@ -1775,6 +1793,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), -@@ -1780,6 +1799,7 @@ enum ieee80211_vif_flags { +@@ -1782,6 +1801,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 }; -@@ -2766,6 +2786,7 @@ enum ieee80211_hw_flags { +@@ -2768,6 +2788,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 -@@ -4266,6 +4287,8 @@ struct ieee80211_prep_tx_info { +@@ -4268,6 +4289,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. -@@ -4649,6 +4672,12 @@ struct ieee80211_ops { +@@ -4651,6 +4674,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); -@@ -7493,4 +7522,100 @@ int ieee80211_set_active_links(struct ie +@@ -7509,4 +7538,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 -@@ -2519,6 +2519,7 @@ static int ieee80211_update_mesh_config( +@@ -2521,6 +2521,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; -@@ -2535,8 +2536,11 @@ static int ieee80211_update_mesh_config( +@@ -2537,8 +2538,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)) { -@@ -2550,8 +2554,12 @@ static int ieee80211_update_mesh_config( +@@ -2552,8 +2556,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)) -@@ -2586,8 +2594,12 @@ static int ieee80211_update_mesh_config( +@@ -2588,8 +2596,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. -@@ -2629,6 +2641,7 @@ static int ieee80211_update_mesh_config( +@@ -2631,6 +2643,7 @@ static int ieee80211_update_mesh_config( conf->dot11MeshConnectedToAuthServer = nconf->dot11MeshConnectedToAuthServer; ieee80211_mbss_info_change_notify(sdata, BSS_CHANGED_BEACON); @@ -1173,6 +1173,15 @@ 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 +@@ -2609,7 +2609,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); + @@ -2621,6 +2621,9 @@ static struct sk_buff *ieee80211_build_h info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; #endif @@ -1220,7 +1229,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran struct ieee80211_sub_if_data *ap_sdata; if (unlikely(!ieee80211_sdata_running(sdata) || skb->len < ETH_HLEN)) { -@@ -4346,9 +4357,15 @@ void __ieee80211_subif_start_xmit(struct +@@ -4348,9 +4359,15 @@ void __ieee80211_subif_start_xmit(struct goto out; } @@ -1229,7 +1238,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran - ieee80211_xmit(sdata, sta, skb); + info = IEEE80211_SKB_CB(skb); + if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { -+ if (sta) ++ if (sta) + key = rcu_dereference(sta->ptk[sta->ptk_idx]); + ieee80211_8023_xmit(sdata, dev, sta, key, skb); + } else { diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index 6ae2863bbe8a90..0a3e71bee9716f 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -4754,6 +4754,70 @@ out_free: +@@ -4759,6 +4759,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) { -@@ -4793,6 +4857,11 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4798,6 +4859,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/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch b/package/kernel/mac80211/patches/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch index aa35bc746e6d5a..0be0c6106bf788 100644 --- a/package/kernel/mac80211/patches/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch +++ b/package/kernel/mac80211/patches/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch @@ -33,13 +33,16 @@ Signed-off-by: Tamizh Chelvam --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4731,12 +4731,12 @@ static void ieee80211_8023_xmit(struct i +@@ -4711,7 +4711,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) { +@@ -4762,7 +4762,7 @@ static void ieee80211_8023_xmit(struct i &info->flags, NULL); dev_sw_netstats_tx_add(dev, skbs, len); 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 00000000000000..5fd21ba6a4d42b --- /dev/null +++ b/package/kernel/mac80211/patches/nss/subsys/345-mac80211-fix-mixed-declaration.patch @@ -0,0 +1,57 @@ +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(-) + +diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c +index 76747bf..7ddfb96 100644 +--- a/net/mac80211/spectmgmt.c ++++ b/net/mac80211/spectmgmt.c +@@ -33,7 +33,10 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, + 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 ieee80211_sub_if_data *sdata, + } + + 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 +-- +2.7.4 + 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 00000000000000..82e44b83600984 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/subsys/346-mac80211-fix-bw-change-to-40Mhz-during-channel-switc.patch @@ -0,0 +1,39 @@ +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(+) + +diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c +index 7ddfb96..15c7ac3 100644 +--- a/net/mac80211/spectmgmt.c ++++ b/net/mac80211/spectmgmt.c +@@ -136,6 +136,10 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, + } + + 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; +-- +2.7.4 + diff --git a/package/kernel/mac80211/patches/nss/subsys/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 new file mode 100644 index 00000000000000..eaec491461b6cc --- /dev/null +++ b/package/kernel/mac80211/patches/nss/subsys/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch @@ -0,0 +1,85 @@ +From 11d0cce62afc157468e1d97ea80a2510091ea2c2 Mon Sep 17 00:00:00 2001 +From: P Praneesh +Date: Fri, 1 Jul 2022 11:57:00 +0530 +Subject: [PATCH] mac80211: Remove unused RX_FLAGS from mac80211_rx_flags + +Remove unused RX_FLAG_AMPDU_DELIM_CRC_KNOWN flag from +mac80211_rx_flags to provide space for new EHT flags. + +Signed-off-by: P Praneesh +--- + include/net/mac80211.h | 33 +++++++++++++++------------------ + net/mac80211/rx.c | 7 +------ + 2 files changed, 16 insertions(+), 24 deletions(-) + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -1427,8 +1427,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 +- * @RX_FLAG_AMPDU_DELIM_CRC_KNOWN: The delimiter CRC field is known (the CRC +- * is stored in the @ampdu_delimiter_crc field) + * @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 +@@ -1500,22 +1498,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), +- RX_FLAG_AMPDU_DELIM_CRC_KNOWN = BIT(15), +- RX_FLAG_MACTIME_END = BIT(16), +- RX_FLAG_ONLY_MONITOR = BIT(17), +- RX_FLAG_SKIP_MONITOR = BIT(18), +- RX_FLAG_AMSDU_MORE = BIT(19), +- RX_FLAG_RADIOTAP_TLV_AT_END = BIT(20), +- RX_FLAG_MIC_STRIPPED = BIT(21), +- RX_FLAG_ALLOW_SAME_PN = BIT(22), +- RX_FLAG_ICV_STRIPPED = BIT(23), +- RX_FLAG_AMPDU_EOF_BIT = BIT(24), +- RX_FLAG_AMPDU_EOF_BIT_KNOWN = BIT(25), +- RX_FLAG_RADIOTAP_HE = BIT(26), +- RX_FLAG_RADIOTAP_HE_MU = BIT(27), +- RX_FLAG_RADIOTAP_LSIG = BIT(28), +- RX_FLAG_NO_PSDU = BIT(29), +- RX_FLAG_8023 = BIT(30), ++ RX_FLAG_MACTIME_END = BIT(15), ++ RX_FLAG_ONLY_MONITOR = BIT(16), ++ RX_FLAG_SKIP_MONITOR = BIT(17), ++ RX_FLAG_AMSDU_MORE = BIT(18), ++ RX_FLAG_RADIOTAP_TLV_AT_END = BIT(19), ++ RX_FLAG_MIC_STRIPPED = BIT(20), ++ RX_FLAG_ALLOW_SAME_PN = BIT(21), ++ RX_FLAG_ICV_STRIPPED = BIT(22), ++ RX_FLAG_AMPDU_EOF_BIT = BIT(23), ++ RX_FLAG_AMPDU_EOF_BIT_KNOWN = BIT(24), ++ RX_FLAG_RADIOTAP_HE = BIT(25), ++ RX_FLAG_RADIOTAP_HE_MU = BIT(26), ++ RX_FLAG_RADIOTAP_LSIG = BIT(27), ++ RX_FLAG_NO_PSDU = BIT(28), ++ RX_FLAG_8023 = BIT(29), + }; + + /** +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -517,18 +517,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; +- if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN) +- flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN; + if (status->flag & RX_FLAG_AMPDU_EOF_BIT_KNOWN) + flags |= IEEE80211_RADIOTAP_AMPDU_EOF_KNOWN; + if (status->flag & RX_FLAG_AMPDU_EOF_BIT) + flags |= IEEE80211_RADIOTAP_AMPDU_EOF; + put_unaligned_le16(flags, pos); + pos += 2; +- if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN) +- *pos++ = status->ampdu_delimiter_crc; +- else +- *pos++ = 0; ++ *pos++ = 0; + *pos++ = 0; + } + diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index bbd632cae45c6f..e0415032bb8ae7 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 @@ -44,20 +44,7 @@ Signed-off-by: Aaradhana Sahu /* misc utils */ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, -@@ -4309,13 +4310,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 && +@@ -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; } -@@ -4361,7 +4367,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) + 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 { dev_sw_netstats_tx_add(dev, 1, skb->len); ieee80211_xmit(sdata, sta, skb); -@@ -4662,19 +4668,29 @@ static bool ieee80211_tx_8023(struct iee +@@ -4667,7 +4668,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,29 +71,8 @@ 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; -@@ -4709,6 +4725,7 @@ static void ieee80211_8023_xmit(struct i + struct ethhdr *ehdr = (struct ethhdr *)skb->data; +@@ -4723,6 +4725,7 @@ static void ieee80211_8023_xmit(struct i info = IEEE80211_SKB_CB(skb); memset(info, 0, sizeof(*info)); @@ -114,21 +80,23 @@ Signed-off-by: Aaradhana Sahu info->hw_queue = sdata->vif.hw_queue[queue]; if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && -@@ -4729,9 +4746,10 @@ static void ieee80211_8023_xmit(struct i +@@ -4743,11 +4746,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); -@@ -4756,7 +4774,8 @@ out_free: + dev_sw_netstats_tx_add(dev, skbs, len); + if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD) && sta) { +@@ -4770,7 +4774,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; -@@ -4765,6 +4784,9 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4779,6 +4784,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. -@@ -4776,11 +4798,13 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4790,11 +4798,13 @@ void ieee80211_8023_xmit_ap(struct ieee8 info = IEEE80211_SKB_CB(skb); memset(info, 0, sizeof(*info)); @@ -165,7 +133,7 @@ Signed-off-by: Aaradhana Sahu info->flags |= IEEE80211_TX_CTL_HW_80211_ENCAP; info->control.vif = &sdata->vif; -@@ -4817,14 +4841,23 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4831,14 +4841,23 @@ void ieee80211_8023_xmit_ap(struct ieee8 if (sta) atomic_inc(&sta->tx_drv_pkts); } @@ -190,7 +158,7 @@ Signed-off-by: Aaradhana Sahu #ifdef CPTCFG_MAC80211_NSS_SUPPORT ieee80211_xmit_nss_fixup(skb, dev); -@@ -4840,14 +4873,15 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4854,14 +4873,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]); -@@ -4858,13 +4892,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4872,13 +4892,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: -@@ -6370,13 +6404,10 @@ start_xmit: +@@ -6384,7 +6404,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/nss/subsys/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 index 8a913cf0b4e425..61421d7d766950 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -2346,7 +2346,7 @@ static void mpath_set_pinfo(struct mesh_ +@@ -2373,7 +2373,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 +@@ -510,7 +510,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 +@@ -571,7 +571,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); From 619c14bb907e04e450f8bafdcd9cf3746bbc0fa2 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 11 Feb 2024 21:00:33 -0500 Subject: [PATCH 107/225] ath11k_nss: fix n2h high_water_core0/wifi_pool_buf These were commented out, but looks like they are needed to prevent lock ups with heavy usage apps (users report in torrenting) --- .../kernel/mac80211/files/qca-nss-pbuf.init | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/package/kernel/mac80211/files/qca-nss-pbuf.init b/package/kernel/mac80211/files/qca-nss-pbuf.init index eaba09ca85e8af..f4f45b9a4a4c60 100755 --- a/package/kernel/mac80211/files/qca-nss-pbuf.init +++ b/package/kernel/mac80211/files/qca-nss-pbuf.init @@ -17,24 +17,24 @@ 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 - # - # 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 - # - # 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" > /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" + + 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" } @@ -67,22 +67,22 @@ apply_nss_config() { local memory_profile if memory_profile=$(uci_get pbuf.opt.memory_profile); then case "$memory_profile" in - 1g* | 512m* | 256m*) - board=$memory_profile - logger -t ath11k_nss "Using custom memory profile - $board" - ;; - off* | false* | disable* | 0) - logger -s -t ath11k_nss -p user.warn "NSS pbuf option 'memory_profile=off'. Not running. Enable if you have issues connecting more than 65 clients" - exit 0 - ;; - auto) - board=$(board_name) - logger -t ath11k_nss "Setting n2hcfg values for board: $board" - ;; - *) - logger -s -t ath11k_nss -p user.error "Unknown profile $memory_profile. Choose auto, 1gb, 512mb, or 256mb" - exit 1 - ;; + 1g*|512m*|256m*) + board=$memory_profile + logger -t ath11k_nss "Using custom memory profile - $board" + ;; + off*|false*|disable*|0) + logger -s -t ath11k_nss -p user.warn "NSS pbuf option 'memory_profile=off'. Not running. Enable if you have issues connecting more than 65 clients" + exit 0 + ;; + auto) + board=$(board_name) + logger -t ath11k_nss "Setting n2hcfg values for board: $board" + ;; + *) + logger -s -t ath11k_nss -p user.error "Unknown profile $memory_profile. Choose auto, 1gb, 512mb, or 256mb" + exit 1 + ;; esac else exit 0 @@ -127,11 +127,11 @@ apply_nss_config() { boost_performance() { - find /sys/kernel/debug/ath11k -name stats_disable | while read stats_disable; do + find /sys/kernel/debug/ath11k -name stats_disable| while read -r stats_disable; do echo 1 > "$stats_disable" done - ubus call iwinfo devices | jsonfilter -e "@.devices[*]" | while read device; do + ubus call iwinfo devices | jsonfilter -e "@.devices[*]"| while read -r device; do tc qdisc replace dev "${device}" root noqueue done From 1128290dbf4a7b06cb984ff6d176220b310ca3c4 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 11 Feb 2024 21:15:23 -0500 Subject: [PATCH 108/225] ipq807x: Revert disallowing identical algo (nss-cfi) Reverts recent commit in 6.1.76 that shows an error when duplicate encryption driver names are used. This is due to NSS crypto offering the offloading encryptions. Revert the change for now. --- ...rt-crypto-api-disallow-identical-driver-names.patch | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/9999-revert-crypto-api-disallow-identical-driver-names.patch diff --git a/target/linux/qualcommax/patches-6.1/9999-revert-crypto-api-disallow-identical-driver-names.patch b/target/linux/qualcommax/patches-6.1/9999-revert-crypto-api-disallow-identical-driver-names.patch new file mode 100644 index 00000000000000..60cc5e6de280a2 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/9999-revert-crypto-api-disallow-identical-driver-names.patch @@ -0,0 +1,10 @@ +--- b/crypto/algapi.c ++++ a/crypto/algapi.c +@@ -217,7 +217,6 @@ + } + + if (!strcmp(q->cra_driver_name, alg->cra_name) || +- !strcmp(q->cra_driver_name, alg->cra_driver_name) || + !strcmp(q->cra_name, alg->cra_driver_name)) + goto err; + } From cddb2bfd9c396543a9305f074815bef641501a13 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Thu, 15 Feb 2024 18:04:34 -0500 Subject: [PATCH 109/225] ath11k_nss: Renumber ath11k patches in the range commit 3c7cc4b725ea406f19b736427034e3bdb436aedc Author: Yuvasree Sivasankaran AuthorDate: Thu Jan 4 11:25:56 2024 +0530 Commit: Yuvasree Sivasankaran CommitDate: Wed Jan 3 22:53:51 2024 -0800 wifi: ath11k: Renumber ath11k patches in the range In ath11k, patches are not maintained in the range and not sequential. Renumber the patches sequential and in the range. Change-Id: I77c51c0f5bf9f94863db4ef364b156e14465a60c Signed-off-by: Yuvasree Sivasankaran --- ... 457-wifi-ath11k-Avoid-memset-of-ppdu-info-for-next-skb.patch} | 0 ...58-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename package/kernel/mac80211/patches/nss/ath11k/{830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch => 457-wifi-ath11k-Avoid-memset-of-ppdu-info-for-next-skb.patch} (100%) rename package/kernel/mac80211/patches/nss/ath11k/{906-456-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch => 458-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch} (100%) diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 100% rename from package/kernel/mac80211/patches/nss/ath11k/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 diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 100% rename from package/kernel/mac80211/patches/nss/ath11k/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 From a5a1fac239032b7088f5267dc13c5db685912207 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Thu, 15 Feb 2024 18:08:12 -0500 Subject: [PATCH 110/225] ath11k_nss: Add mac hw flag to avoid tx queue in mac80211 commit 4e9b5f7f0d1ed40dbf3208f7ed4448e49b4a4ac1 Author: Yuvasree Sivasankaran AuthorDate: Wed Dec 6 12:20:59 2023 +0530 Commit: Yuvasree Sivasankaran CommitDate: Mon Dec 18 12:52:33 2023 +0530 wifi: mac80211: Add mac hw flag to avoid tx queue in mac80211 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. --- ...th11k-Advertise-TX_QUEUE-mac-hw-flag.patch | 28 ++ ...1-Add-mac-hw-flag-to-avoid-queue-skb.patch | 342 ++++++++++++++++++ 2 files changed, 370 insertions(+) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/456-wifi-ath11k-Advertise-TX_QUEUE-mac-hw-flag.patch create mode 100644 package/kernel/mac80211/patches/nss/subsys/785-wifi-mac80211-Add-mac-hw-flag-to-avoid-queue-skb.patch 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 00000000000000..2b7d9c50c0c776 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/456-wifi-ath11k-Advertise-TX_QUEUE-mac-hw-flag.patch @@ -0,0 +1,28 @@ +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(+) + +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index 3e79e07..32ff5c9 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -13034,6 +13034,7 @@ static int __ath11k_mac_register(struct ath11k *ar) + 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); +-- +2.34.1 + 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 00000000000000..e25220a1b01c99 --- /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 +@@ -2727,6 +2727,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 { +@@ -2787,6 +2790,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 +@@ -499,6 +499,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 +@@ -1602,6 +1602,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; +@@ -1649,6 +1652,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; + +@@ -1665,7 +1671,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) +@@ -4326,7 +4333,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) { +@@ -4678,8 +4686,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); + +@@ -6414,9 +6424,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 +@@ -4516,6 +4516,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 +@@ -841,7 +841,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++) { +@@ -427,7 +429,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); +@@ -529,8 +533,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); +@@ -604,18 +606,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)) +@@ -689,7 +695,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 +@@ -1684,11 +1691,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); +@@ -2103,6 +2112,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)) || +@@ -2519,7 +2531,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(); + +@@ -2847,6 +2859,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, From 4f22c7f4a4c479389de7c0935b87fe15369634c5 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Thu, 15 Feb 2024 18:09:30 -0500 Subject: [PATCH 111/225] ath11k_nss: add the HTC+ / iPhone fix commit ccdca73cd65723c3cb63c17edc95c4c43318cb38 Author: John Crispin AuthorDate: Sun Jul 9 17:12:34 2023 +0200 Commit: John Crispin CommitDate: Thu Aug 31 16:08:34 2023 +0200 mac80211: add the HTC+ / iPhone fix Signed-off-by: John Crispin --- .../patches/nss/ath11k/270-iphone-issue.patch | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/270-iphone-issue.patch diff --git a/package/kernel/mac80211/patches/nss/ath11k/270-iphone-issue.patch b/package/kernel/mac80211/patches/nss/ath11k/270-iphone-issue.patch new file mode 100644 index 00000000000000..5890fa6a784a08 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/270-iphone-issue.patch @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -5898,6 +5898,8 @@ static int ath11k_mac_copy_he_cap(struct + memcpy(he_cap_elem->phy_cap_info, band_cap->he_cap_phy_info, + sizeof(he_cap_elem->phy_cap_info)); + ++ he_cap_elem->mac_cap_info[0] &= ~IEEE80211_HE_MAC_CAP0_HTC_HE; ++ + he_cap_elem->mac_cap_info[1] &= + IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_MASK; + From a521b136abd2d68ec65d6a8b40b3e2e4be70da4d Mon Sep 17 00:00:00 2001 From: Qosmio Date: Thu, 15 Feb 2024 18:13:12 -0500 Subject: [PATCH 112/225] ath11k_nss: ath-next fix connection failure due to unexpected peer delete 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. Also do some cleanups in patch "wifi: ath11k: remove invalid peer create logic", and refactor in patches "wifi: ath11k: rename ath11k_start_vdev_delay()" and "wifi: ath11k: avoid forward declaration of ath11k_mac_start_vdev_delay()". Tested this patch set using QCA6390 and WCN6855 on both STA and SAP interfaces. Basic connection and ping work well. Baochen Qiang (4): wifi: ath11k: remove invalid peer create logic wifi: ath11k: rename ath11k_start_vdev_delay() wifi: ath11k: avoid forward declaration of ath11k_mac_start_vdev_delay() wifi: ath11k: fix connection failure due to unexpected peer delete drivers/net/wireless/ath/ath11k/mac.c | 564 +++++++++++++------------- 1 file changed, 288 insertions(+), 276 deletions(-) --- ...th11k-rename-ath11k_start_vdev_delay.patch | 52 ++ ...ation-of-ath11k_mac_start_vdev_delay.patch | 601 ++++++++++++++++++ ...ailure-due-to-unexpected-peer-delete.patch | 257 ++++++++ 3 files changed, 910 insertions(+) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/907-02-wifi-ath11k-rename-ath11k_start_vdev_delay.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/907-03-wifi-ath11k-avoid-forward-declaration-of-ath11k_mac_start_vdev_delay.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/907-04-wifi-ath11k-fix-connection-failure-due-to-unexpected-peer-delete.patch 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 00000000000000..2490a8139d452a --- /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 +@@ -261,8 +261,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) + { +@@ -5323,7 +5323,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; +@@ -8175,8 +8175,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 00000000000000..3b6e24ae508bbe --- /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 +@@ -261,9 +261,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; +@@ -5253,100 +5250,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) + { +@@ -5402,187 +5305,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) +@@ -9735,6 +9457,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 00000000000000..e8e663431217c5 --- /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 +@@ -7937,6 +7937,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, +@@ -7981,15 +8005,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)) { +@@ -8029,8 +8055,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); +@@ -8054,24 +8078,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 && +@@ -9551,6 +9564,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, +@@ -9586,31 +9639,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); +@@ -9621,12 +9658,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 || +@@ -10195,6 +10226,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; From b36b58dbf5fe5995111187c76d63e381c7b2e5c9 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Thu, 15 Feb 2024 18:15:12 -0500 Subject: [PATCH 113/225] ath11k_nss: Revert support for beacon_tx_mode --- ...th11k-Add-support-for-beacon-tx-mode.patch | 52 ------ ...80211-Add-support-for-beacon-tx-mode.patch | 174 ------------------ 2 files changed, 226 deletions(-) delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/235-001-ath11k-Add-support-for-beacon-tx-mode.patch delete mode 100644 package/kernel/mac80211/patches/nss/subsys/235-002-mac80211-Add-support-for-beacon-tx-mode.patch diff --git a/package/kernel/mac80211/patches/nss/ath11k/235-001-ath11k-Add-support-for-beacon-tx-mode.patch b/package/kernel/mac80211/patches/nss/ath11k/235-001-ath11k-Add-support-for-beacon-tx-mode.patch deleted file mode 100644 index 9782bb186801af..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/235-001-ath11k-Add-support-for-beacon-tx-mode.patch +++ /dev/null @@ -1,52 +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 - -Add support to configure the beacon tx mode in -the driver. - -Beacons can be sent out in burst(continuously in a single shot -one after another) or staggered (equally spread out over beacon -interval) mode. - -Use the below configuration in the hostapd/wpa_supplicant -for AP/MESH mode to configure the beacon tx mode. - -"beacon_tx_mode=N", where N = 1 for STAGGERED beacon mode -and N = 2 for BURST beacon mode. - -Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-00480-QCAHKSWPL_SILICONZ-1 - -Signed-off-by: Maharaja Kennadyrajan ---- - - drivers/net/wireless/ath/ath11k/mac.c | 10 +++++++--- - 1 file changed, 7 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 == WMI_BEACON_BURST_MODE) ? "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/nss/subsys/235-002-mac80211-Add-support-for-beacon-tx-mode.patch b/package/kernel/mac80211/patches/nss/subsys/235-002-mac80211-Add-support-for-beacon-tx-mode.patch deleted file mode 100644 index b500d000a19004..00000000000000 --- a/package/kernel/mac80211/patches/nss/subsys/235-002-mac80211-Add-support-for-beacon-tx-mode.patch +++ /dev/null @@ -1,174 +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 = 1 for STAGGERED beacon mode -and N = 2 for BURST beacon mode, default is STAGGERED mode -"N = 0". - -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 -@@ -1440,6 +1440,7 @@ struct cfg80211_unsol_bcast_probe_resp { - * @fils_discovery: FILS discovery transmission parameters - * @unsol_bcast_probe_resp: Unsolicited broadcast probe response parameters - * @mbssid_config: AP settings for multiple bssid -+ * @beacon_tx_mode: Beacon Tx Mode setting - * @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. -@@ -1477,6 +1478,7 @@ struct cfg80211_ap_settings { - struct cfg80211_fils_discovery fils_discovery; - struct cfg80211_unsol_bcast_probe_resp unsol_bcast_probe_resp; - struct cfg80211_mbssid_config mbssid_config; -+ enum nl80211_beacon_tx_mode beacon_tx_mode; - u16 punct_bitmap; - }; - -@@ -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 -@@ -656,6 +656,7 @@ struct ieee80211_fils_discovery { - * @tx_pwr_env_num: number of @tx_pwr_env. - * @pwr_reduction: power constraint of BSS. - * @eht_support: does this BSS support EHT -+ * @beacon_tx_mode: Beacon Tx Mode setting. - * @eht_puncturing: bitmap to indicate which channels are punctured in this BSS - * @csa_active: marks whether a channel switch is going on. Internally it is - * write-protected by sdata_lock and local->mtx so holding either is fine -@@ -766,6 +767,7 @@ struct ieee80211_bss_conf { - u8 tx_pwr_env_num; - u8 pwr_reduction; - bool eht_support; -+ enum nl80211_beacon_tx_mode beacon_tx_mode; - u16 eht_puncturing; - - bool csa_active; ---- a/include/uapi/linux/nl80211.h -+++ b/include/uapi/linux/nl80211.h -@@ -2758,6 +2758,13 @@ enum nl80211_commands { - * association request when used with NL80211_CMD_NEW_STATION). Can be set - * only if %NL80211_STA_FLAG_WME is set. - * -+ * @NL80211_ATTR_BEACON_TX_MODE: used to configure the beacon tx mode (u32), -+ * as specified in the &enum nl80211_beacon_tx_mode. The user-space -+ * can use this attribute to configure the tx mode of beacons. -+ * Beacons can be sent out in burst(continuously in a single shot -+ * one after another) or staggered (equally spread out over beacon -+ * interval) mode. -+ * - * @NL80211_ATTR_MLO_LINK_ID: A (u8) link ID for use with MLO, to be used with - * various commands that need a link ID to operate. - * @NL80211_ATTR_MLO_LINKS: A nested array of links, each containing some -@@ -3362,6 +3369,8 @@ enum nl80211_attrs { - - NL80211_ATTR_HE_MUEDCA_PARAMS, - -+ NL80211_ATTR_BEACON_TX_MODE, -+ - /* add attributes here, update the policy in nl80211.c */ - - __NL80211_ATTR_AFTER_LAST, -@@ -7849,4 +7858,16 @@ enum nl80211_ap_settings_flags { - NL80211_AP_SETTINGS_SA_QUERY_OFFLOAD_SUPPORT = 1 << 1, - }; - -+/** -+ * enum nl80211_beacon_tx_mode - Beacon Tx Mode enum. -+ * @NL80211_BEACON_STAGGERED_MODE: Used to configure beacon tx mode as -+ * staggered mode. This is the default beacon tx mode. -+ * @NL80211_BEACON_BURST_MODE: Used to configure beacon tx mode as burst mode. -+ */ -+enum nl80211_beacon_tx_mode { -+ NL80211_BEACON_DEFAULT_MODE = 0, -+ 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 = -@@ -2496,6 +2497,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 -@@ -796,8 +796,11 @@ static const struct nla_policy nl80211_p - [NL80211_ATTR_AP_SETTINGS_FLAGS] = { .type = NLA_U32 }, - [NL80211_ATTR_EHT_CAPABILITY] = - NLA_POLICY_BINARY_RANGE(NL80211_EHT_MIN_CAPABILITY_LEN, NL80211_EHT_MAX_CAPABILITY_LEN), -- [NL80211_ATTR_DISABLE_EHT] = { .type = NLA_FLAG }, -- [NL80211_ATTR_MLO_LINKS] = -+ [NL80211_ATTR_DISABLE_EHT] = { .type = NLA_FLAG }, -+ [NL80211_ATTR_BEACON_TX_MODE] = -+ NLA_POLICY_RANGE(NLA_U32, NL80211_BEACON_STAGGERED_MODE, -+ NL80211_BEACON_BURST_MODE), -+ [NL80211_ATTR_MLO_LINKS] = - NLA_POLICY_NESTED_ARRAY(nl80211_policy), - [NL80211_ATTR_MLO_LINK_ID] = - NLA_POLICY_RANGE(NLA_U8, 0, IEEE80211_MLD_MAX_NUM_LINKS), -@@ -5942,6 +5945,10 @@ static int nl80211_start_ap(struct sk_bu - 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); - if (err) -@@ -13037,6 +13044,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); From 971854b2ca382eb241618e9539a6d13f129c5f02 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Thu, 15 Feb 2024 18:18:17 -0500 Subject: [PATCH 114/225] ath11k_nss: Update release fix dependancies --- package/kernel/mac80211/Makefile | 2 +- package/kernel/mac80211/ath.mk | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 26d3c0533e1604..1f26ae16a4d6b6 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 PKG_VERSION:=6.5 -PKG_RELEASE:=12 +PKG_RELEASE:=13 # PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.15.58/ PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/ PKG_HASH:=908c22dceba185eab83caa5a1e58ce6b3ebdc58f099c3fd3e11c7352ebfab2d7 diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk index f5fbf965ffc505..1b4a4997c405ef 100644 --- a/package/kernel/mac80211/ath.mk +++ b/package/kernel/mac80211/ath.mk @@ -70,6 +70,7 @@ 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-$(CONFIG_ATH11K_NSS_MESH_SUPPORT) += ATH11K_NSS_MESH_SUPPORT config-$(call config_package,ath9k-htc) += ATH9K_HTC config-$(call config_package,ath10k) += ATH10K ATH10K_PCI @@ -347,6 +348,7 @@ define KernelPackage/ath11k/config config ATH11K_DEBUGFS_STA bool "Enable ath11k station statistics" + depends on PACKAGE_kmod-ath11k depends on PACKAGE_MAC80211_DEBUGFS default y help @@ -354,6 +356,7 @@ define KernelPackage/ath11k/config config ATH11K_DEBUGFS_HTT_STATS bool "Enable ath11k HTT statistics" + depends on PACKAGE_kmod-ath11k depends on PACKAGE_MAC80211_DEBUGFS default y help From 33808a623408b71bb9e2635f211d7b63b0dc8cb6 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Thu, 15 Feb 2024 18:35:01 -0500 Subject: [PATCH 115/225] ath11k_nss: mgmt and data ack rssi update Data ACK RSSI : Advertise NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT feature support for accounting and notifying "last ack signal" and "avg ack signal" to user space through NL interface. Enabled data ack rssi support for ethernet mode. Mgmt ACK RSSI: Enabled support for Tx-ACK RSSI in HTT over Management packets. --- ...91-ath11k-add-mgmt-and-data-ack-rssi.patch | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/191-ath11k-add-mgmt-and-data-ack-rssi.patch diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 new file mode 100644 index 00000000000000..55701c68d08760 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/191-ath11k-add-mgmt-and-data-ack-rssi.patch @@ -0,0 +1,21 @@ +--- 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 + 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/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -4065,6 +4065,7 @@ 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; From 9cbd8dca718dc14993106b8b121e73fd9f497eec Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 18 Feb 2024 01:36:48 -0500 Subject: [PATCH 116/225] nss-firmware: add support for ipq60xx/ipq50xx QUIC repository has NSS firmwares for IPQ6018 and IPQ5018. These should also be accounted for. Although IPQ50xx isn't officially a platform upstream, prepare for it if it's ever supported. --- package/firmware/nss-firmware/Makefile | 52 ++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/package/firmware/nss-firmware/Makefile b/package/firmware/nss-firmware/Makefile index 215f2d574d2579..6f95ce32b7ee9a 100644 --- a/package/firmware/nss-firmware/Makefile +++ b/package/firmware/nss-firmware/Makefile @@ -27,7 +27,12 @@ STRIP:=: VERSION_PATH=$(PKG_BUILD_DIR)/QCA_Networking_2022.SPF_12.0.0/ED1 +NSS_VER:=12.1 +NSS_REL:=022 +NSS_PROFILE:=R + define Package/nss-firmware-default + TITLE:=NSS firmware SECTION:=firmware CATEGORY:=Firmware URL:=$(PKG_SOURCE_URL) @@ -36,24 +41,55 @@ endef define Package/nss-firmware-ipq8074 $(Package/nss-firmware-default) - TITLE:=IPQ8074 NSS firmware - NSS_ARCHIVE:=$(VERSION_PATH)/IPQ8074.ATH.12.0.0/BIN-NSS.FW.12.1-022-HK.R.tar.bz2 + IPQ_PLATFORM=IPQ8074 + DEPENDS+= @TARGET_qualcommax_ipq807x + NSS_SOC:=HK endef -define Build/Compile +define Package/nss-firmware-ipq6018 +$(Package/nss-firmware-default) + IPQ_PLATFORM=IPQ6018 + DEPENDS+= @TARGET_qualcommax_ipq60xx + NSS_SOC:=CP +endef +define Package/nss-firmware-ipq5018 +$(Package/nss-firmware-default) + IPQ_PLATFORM=IPQ5018 + DEPENDS+= @TARGET_qualcommax_ipq50xx + NSS_SOC:=MP endef -define Package/nss-firmware-ipq8074/install - mkdir -p $(PKG_BUILD_DIR)/IPQ8074 - $(TAR) -C $(PKG_BUILD_DIR)/IPQ8074 -xf $(NSS_ARCHIVE) --strip-components=1 +define Build/Compile +endef + +define Package/nss-firmware/install + $(eval NSS_ARCHIVE := $(VERSION_PATH)/$(IPQ_PLATFORM).ATH.12.0.0/BIN-NSS.FW.$(NSS_VER)-$(NSS_REL)-$(NSS_SOC).$(NSS_PROFILE).tar.bz2) + mkdir -p $(PKG_BUILD_DIR)/$(IPQ_PLATFORM) + $(TAR) -C $(PKG_BUILD_DIR)/$(IPQ_PLATFORM) -xf $(NSS_ARCHIVE) --strip-components=1 $(INSTALL_DIR) $(1)/lib/firmware/ $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/IPQ8074/retail_router0.bin \ + $(PKG_BUILD_DIR)/$(IPQ_PLATFORM)/retail_router0.bin \ $(1)/lib/firmware/qca-nss0-retail.bin +ifeq ($(NSS_SOC),HK) $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/IPQ8074/retail_router1.bin \ + $(PKG_BUILD_DIR)/$(IPQ_PLATFORM)/retail_router1.bin \ $(1)/lib/firmware/qca-nss1-retail.bin +endif +endef + +define Package/nss-firmware-ipq8074/install + $(call Package/nss-firmware/install,$1) +endef + +define Package/nss-firmware-ipq6018/install + $(call Package/nss-firmware/install,$1) +endef + +define Package/nss-firmware-ipq5018/install + $(call Package/nss-firmware/install,$1) endef $(eval $(call BuildPackage,nss-firmware-ipq8074)) +$(eval $(call BuildPackage,nss-firmware-ipq6018)) +$(eval $(call BuildPackage,nss-firmware-ipq5018)) From a7983d684ceec8020ab6c17751ffd556914ef9f9 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 18 Feb 2024 01:41:24 -0500 Subject: [PATCH 117/225] feeds: Switch to fork that requires nss qdisc Without it, NSS based SQM doesn't work. --- feeds.conf.default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feeds.conf.default b/feeds.conf.default index 741b14a875d234..4527c3215a827e 100644 --- a/feeds.conf.default +++ b/feeds.conf.default @@ -3,7 +3,7 @@ src-git luci https://git.openwrt.org/project/luci.git src-git routing https://git.openwrt.org/feed/routing.git src-git telephony https://git.openwrt.org/feed/telephony.git src-git nss_packages https://github.com/qosmio/nss-packages.git;NSS-12.4-K6.1 -src-git sqm_scripts_nss https://github.com/rickkdotnet/sqm-scripts-nss.git +src-git sqm_scripts_nss https://github.com/qosmio/sqm-scripts-nss.git #src-git video https://github.com/openwrt/video.git #src-git targets https://github.com/openwrt/targets.git #src-git oldpackages http://git.openwrt.org/packages.git From b307d571a5b83f02f2e5e0c560d1700e7add9f6e Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 18 Feb 2024 17:44:36 -0500 Subject: [PATCH 118/225] Revert "Custom feed core" This reverts commit 9c5068900457c52424cb526f0124c17797322cf0. --- include/feeds.mk | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/feeds.mk b/include/feeds.mk index 18eb170dd79b90..632fecb4a3aaec 100644 --- a/include/feeds.mk +++ b/include/feeds.mk @@ -27,17 +27,15 @@ $(strip $(if $(CONFIG_PER_FEED_REPO), \ $(PACKAGE_DIR))) endef -EXCLUDE_FEEDS:=nss_packages - # 1: destination file define FeedSourcesAppend ( \ - echo 'src/gz %d_core https://openwrt.admincomps.ru/nss/$(shell date +"%Y%m%d")/packages'; \ + echo 'src/gz %d_core %U/targets/%S/packages'; \ $(strip $(if $(CONFIG_PER_FEED_REPO), \ echo 'src/gz %d_base %U/packages/%A/base'; \ $(if $(filter %SNAPSHOT-y,$(VERSION_NUMBER)-$(CONFIG_BUILDBOT)), \ echo 'src/gz %d_kmods %U/targets/%S/kmods/$(LINUX_VERSION)-$(LINUX_RELEASE)-$(LINUX_VERMAGIC)';) \ - $(foreach feed,$(filter-out $(EXCLUDE_FEEDS), $(FEEDS_AVAILABLE)), \ + $(foreach feed,$(FEEDS_AVAILABLE), \ $(if $(CONFIG_FEED_$(feed)), \ echo '$(if $(filter m,$(CONFIG_FEED_$(feed))),# )src/gz %d_$(feed) %U/packages/%A/$(feed)';)))) \ ) >> $(1) From 9f88c1ac2689389e8f2391b4f8180d70c32e0d2b Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 19 Feb 2024 01:43:33 -0500 Subject: [PATCH 119/225] ath11k: Reverto to latest 2.9.0.1-0189 Things have stablized on the NSS branch --- package/firmware/ath11k-firmware/Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package/firmware/ath11k-firmware/Makefile b/package/firmware/ath11k-firmware/Makefile index fc7968a95764a4..ea4977aa68ca1e 100644 --- a/package/firmware/ath11k-firmware/Makefile +++ b/package/firmware/ath11k-firmware/Makefile @@ -8,9 +8,9 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ath11k-firmware -PKG_SOURCE_DATE:=2023-03-31 -PKG_SOURCE_VERSION:=a039049a9349722fa5c74185452ab04644a0d351 -PKG_MIRROR_HASH:=ed401e3f6e91d70565b3396139193f7e815f410db93700697205ac8ed1b828c5 +PKG_SOURCE_DATE:=2023-08-22 +PKG_SOURCE_VERSION:=d8f82a98ff1aef330d65d8b5660b46d1a9809ee3 +PKG_MIRROR_HASH:=3dba19449758c3b17f117990d7ad4086554e012b579f1de16e9d9196a7fbaaa7 PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git @@ -60,14 +60,14 @@ $(eval $(call Download,qcn9074-board)) define Package/ath11k-firmware-ipq8074/install $(INSTALL_DIR) $(1)/lib/firmware/IPQ8074 $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/ath11k-firmware/IPQ8074/hw2.0/testing/2.9.0.1/WLAN.HK.2.9.0.1-01385-QCAHKSWPL_SILICONZ-1/* \ + $(PKG_BUILD_DIR)/ath11k-firmware/IPQ8074/hw2.0/2.9.0.1/WLAN.HK.2.9.0.1-01890-QCAHKSWPL_SILICONZ-1/* \ $(1)/lib/firmware/IPQ8074/ endef define Package/ath11k-firmware-qcn9074/install $(INSTALL_DIR) $(1)/lib/firmware/ath11k/QCN9074/hw1.0 $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/ath11k-firmware/QCN9074/hw1.0/testing/2.9.0.1/WLAN.HK.2.9.0.1-01385-QCAHKSWPL_SILICONZ-1/* \ + $(PKG_BUILD_DIR)/ath11k-firmware/QCN9074/hw1.0/2.9.0.1/WLAN.HK.2.9.0.1-01890-QCAHKSWPL_SILICONZ-1/* \ $(1)/lib/firmware/ath11k/QCN9074/hw1.0/ $(INSTALL_BIN) \ $(DL_DIR)/$(QCN9074_BOARD_FILE) $(1)/lib/firmware/ath11k/QCN9074/hw1.0/board-2.bin From c7f08d121869d11e8e9691aa54bee4c81818d9be Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 19 Feb 2024 01:46:23 -0500 Subject: [PATCH 120/225] Move non-upstream NSS packages back into repo To keep this fork as closely synced with upstream, move NSS packages back into repository. Not sure why they were moved out from my original fork. * nss-firmware * qca-nss-crypto * qca-nss-cfi nss_packages feed should also be updated https://github.com/qosmio/nss-packages/commit/8d54d726c2c04333b7f756c982f5bd9b6537139a --- package/firmware/nss-firmware/Makefile | 95 -- package/kernel/qca-nss-cfi/Makefile | 87 -- ...yptoapi-v2.0-fix-SHA1-header-include.patch | 62 - ...ptoapi-v2.0-make-ablkcipher-optional.patch | 116 -- ...emove-setting-crypto_ahash_type-for-.patch | 137 -- ...ead-add-downstream-crypto_tfm_alg_fl.patch | 28 - ...-cryptoapi-v2.0-remove-dropped-flags.patch | 97 -- ...6-cryptoapi-v2.0-convert-to-skcipher.patch | 1199 ----------------- package/kernel/qca-nss-crypto/Makefile | 70 - ...1-nss-crypto-fix-SHA1-header-include.patch | 27 - ...replace-ioremap_nocache-with-ioremap.patch | 94 -- ...rypto-fix-SHA-header-include-in-5.15.patch | 44 - 12 files changed, 2056 deletions(-) delete mode 100644 package/firmware/nss-firmware/Makefile delete mode 100644 package/kernel/qca-nss-cfi/Makefile delete mode 100644 package/kernel/qca-nss-cfi/patches/0001-cryptoapi-v2.0-fix-SHA1-header-include.patch delete mode 100644 package/kernel/qca-nss-cfi/patches/0002-cryptoapi-v2.0-make-ablkcipher-optional.patch delete mode 100644 package/kernel/qca-nss-cfi/patches/0003-cryptoapi-v2.0-remove-setting-crypto_ahash_type-for-.patch delete mode 100644 package/kernel/qca-nss-cfi/patches/0004-cryptoapi-v2.0-aead-add-downstream-crypto_tfm_alg_fl.patch delete mode 100644 package/kernel/qca-nss-cfi/patches/0005-cryptoapi-v2.0-remove-dropped-flags.patch delete mode 100644 package/kernel/qca-nss-cfi/patches/0006-cryptoapi-v2.0-convert-to-skcipher.patch delete mode 100644 package/kernel/qca-nss-crypto/Makefile delete mode 100644 package/kernel/qca-nss-crypto/patches/0001-nss-crypto-fix-SHA1-header-include.patch delete mode 100644 package/kernel/qca-nss-crypto/patches/0002-nss-crypto-replace-ioremap_nocache-with-ioremap.patch delete mode 100644 package/kernel/qca-nss-crypto/patches/0003-nss-crypto-fix-SHA-header-include-in-5.15.patch diff --git a/package/firmware/nss-firmware/Makefile b/package/firmware/nss-firmware/Makefile deleted file mode 100644 index 6f95ce32b7ee9a..00000000000000 --- a/package/firmware/nss-firmware/Makefile +++ /dev/null @@ -1,95 +0,0 @@ -# -# Copyright (C) 2022 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=nss-firmware -PKG_SOURCE_DATE:=2022-07-12 -PKG_SOURCE_VERSION:=ade6bff594377c9d9c79b45e39bf104303d919bc -PKG_MIRROR_HASH:=af0521893064b7bc52baab263e12c7db5462461ddac30d02647ed76d999b59fb -PKG_RELEASE:=1 - -PKG_SOURCE_PROTO:=git -PKG_SOURCE_URL:=https://github.com/quic/qca-sdk-nss-fw.git - -PKG_LICENSE_FILES:=LICENSE.md - -PKG_MAINTAINER:=Robert Marko - -include $(INCLUDE_DIR)/package.mk - -RSTRIP:=: -STRIP:=: - -VERSION_PATH=$(PKG_BUILD_DIR)/QCA_Networking_2022.SPF_12.0.0/ED1 - -NSS_VER:=12.1 -NSS_REL:=022 -NSS_PROFILE:=R - -define Package/nss-firmware-default - TITLE:=NSS firmware - SECTION:=firmware - CATEGORY:=Firmware - URL:=$(PKG_SOURCE_URL) - DEPENDS:=@TARGET_qualcommax -endef - -define Package/nss-firmware-ipq8074 -$(Package/nss-firmware-default) - IPQ_PLATFORM=IPQ8074 - DEPENDS+= @TARGET_qualcommax_ipq807x - NSS_SOC:=HK -endef - -define Package/nss-firmware-ipq6018 -$(Package/nss-firmware-default) - IPQ_PLATFORM=IPQ6018 - DEPENDS+= @TARGET_qualcommax_ipq60xx - NSS_SOC:=CP -endef - -define Package/nss-firmware-ipq5018 -$(Package/nss-firmware-default) - IPQ_PLATFORM=IPQ5018 - DEPENDS+= @TARGET_qualcommax_ipq50xx - NSS_SOC:=MP -endef - -define Build/Compile -endef - -define Package/nss-firmware/install - $(eval NSS_ARCHIVE := $(VERSION_PATH)/$(IPQ_PLATFORM).ATH.12.0.0/BIN-NSS.FW.$(NSS_VER)-$(NSS_REL)-$(NSS_SOC).$(NSS_PROFILE).tar.bz2) - mkdir -p $(PKG_BUILD_DIR)/$(IPQ_PLATFORM) - $(TAR) -C $(PKG_BUILD_DIR)/$(IPQ_PLATFORM) -xf $(NSS_ARCHIVE) --strip-components=1 - $(INSTALL_DIR) $(1)/lib/firmware/ - $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/$(IPQ_PLATFORM)/retail_router0.bin \ - $(1)/lib/firmware/qca-nss0-retail.bin -ifeq ($(NSS_SOC),HK) - $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/$(IPQ_PLATFORM)/retail_router1.bin \ - $(1)/lib/firmware/qca-nss1-retail.bin -endif -endef - -define Package/nss-firmware-ipq8074/install - $(call Package/nss-firmware/install,$1) -endef - -define Package/nss-firmware-ipq6018/install - $(call Package/nss-firmware/install,$1) -endef - -define Package/nss-firmware-ipq5018/install - $(call Package/nss-firmware/install,$1) -endef - -$(eval $(call BuildPackage,nss-firmware-ipq8074)) -$(eval $(call BuildPackage,nss-firmware-ipq6018)) -$(eval $(call BuildPackage,nss-firmware-ipq5018)) diff --git a/package/kernel/qca-nss-cfi/Makefile b/package/kernel/qca-nss-cfi/Makefile deleted file mode 100644 index f7197e38d62295..00000000000000 --- a/package/kernel/qca-nss-cfi/Makefile +++ /dev/null @@ -1,87 +0,0 @@ -include $(TOPDIR)/rules.mk - -PKG_NAME:=qca-nss-cfi -PKG_RELEASE:=1 - -PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-cfi.git -PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2022-12-15 -PKG_SOURCE_VERSION:=5cd07ce299ee3ce62dbe4f6783ad36361e57583b -PKG_MIRROR_HASH:=e449eee24fccc09b1cf0f1367bb54cedadcc46a30423934744e78272443197e7 - -PKG_BUILD_PARALLEL:=1 - -include $(INCLUDE_DIR)/kernel.mk -include $(INCLUDE_DIR)/package.mk - -ifneq (, $(findstring $(CONFIG_TARGET_SUBTARGET), "ipq807x")) -#4.4/5.4 + ipq807x/ipq60xx/ipq50xx - CFI_OCF_DIR:=ocf/v2.0 - CFI_CRYPTOAPI_DIR:=cryptoapi/v2.0 -else -#4.4 Kernel + ipq806x - CFI_CRYPTOAPI_DIR:=cryptoapi/v1.1 - CFI_OCF_DIR:=ocf/v1.0 - CFI_IPSEC_DIR:=ipsec/v1.0 -endif - -define KernelPackage/qca-nss-cfi-cryptoapi - SECTION:=kernel - CATEGORY:=Kernel modules - SUBMENU:=Cryptographic API modules - DEPENDS:=@TARGET_qualcommax +kmod-qca-nss-crypto +kmod-crypto-authenc - TITLE:=Kernel driver for NSS cfi - FILES:=$(PKG_BUILD_DIR)/$(CFI_CRYPTOAPI_DIR)/qca-nss-cfi-cryptoapi.ko - AUTOLOAD:=$(call AutoLoad,59,qca-nss-cfi-cryptoapi) -endef - -define Build/InstallDev - $(INSTALL_DIR) $(1)/usr/include/qca-nss-cfi - $(CP) $(PKG_BUILD_DIR)/$(CFI_CRYPTOAPI_DIR)/../exports/* $(1)/usr/include/qca-nss-cfi - $(CP) $(PKG_BUILD_DIR)/include/* $(1)/usr/include/qca-nss-cfi -endef - -define KernelPackage/qca-nss-cfi/Description -This package contains a NSS cfi driver for QCA chipset -endef - -EXTRA_CFLAGS+= \ - -DCONFIG_NSS_DEBUG_LEVEL=4 \ - -I$(LINUX_DIR)/crypto/ocf \ - -I$(STAGING_DIR)/usr/include/qca-nss-crypto \ - -I$(STAGING_DIR)/usr/include/crypto \ - -I$(STAGING_DIR)/usr/include/qca-nss-drv - -ifneq (, $(findstring $(CONFIG_TARGET_SUBTARGET), "ipq807x")) -EXTRA_CFLAGS+= -I$(STAGING_DIR)/usr/include/qca-nss-clients -endif - -# Build individual packages if selected -ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-cfi-cryptoapi),) -MAKE_OPTS+= \ - cryptoapi=y \ - NSS_CRYPTOAPI_ABLK=n \ - NSS_CRYPTOAPI_SKCIPHER=y -endif - -ifeq ($(CONFIG_TARGET_BOARD), "qualcommax") - SOC:=$(CONFIG_TARGET_SUBTARGET) -endif - -define Build/Compile - +$(MAKE) -C "$(LINUX_DIR)" $(strip $(MAKE_OPTS)) \ - CROSS_COMPILE="$(TARGET_CROSS)" \ - ARCH="$(LINUX_KARCH)" \ - M="$(PKG_BUILD_DIR)" \ - EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ - CC="$(TARGET_CC)" \ - CFI_CRYPTOAPI_DIR=$(CFI_CRYPTOAPI_DIR) \ - CFI_OCF_DIR=$(CFI_OCF_DIR) \ - CFI_IPSEC_DIR=$(CFI_IPSEC_DIR) \ - SoC=$(SOC) \ - $(KERNEL_MAKE_FLAGS) \ - $(PKG_JOBS) \ - modules -endef - -$(eval $(call KernelPackage,qca-nss-cfi-cryptoapi)) diff --git a/package/kernel/qca-nss-cfi/patches/0001-cryptoapi-v2.0-fix-SHA1-header-include.patch b/package/kernel/qca-nss-cfi/patches/0001-cryptoapi-v2.0-fix-SHA1-header-include.patch deleted file mode 100644 index 12df90fdcf7321..00000000000000 --- a/package/kernel/qca-nss-cfi/patches/0001-cryptoapi-v2.0-fix-SHA1-header-include.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 1569ac3b6bbcae9c3f4898e0d34aec8f88297ee6 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Sun, 22 Jan 2023 21:45:23 +0100 -Subject: [PATCH 1/5] cryptoapi: v2.0: fix SHA1 header include - -SHA1 header has been merged to the generic SHA one, -and with that the cryptohash.h was dropped. - -So, fix include in kernels 5.8 and newer. - -Signed-off-by: Robert Marko ---- - cryptoapi/v2.0/nss_cryptoapi.c | 5 +++++ - cryptoapi/v2.0/nss_cryptoapi_aead.c | 5 +++++ - cryptoapi/v2.0/nss_cryptoapi_ahash.c | 5 +++++ - 3 files changed, 15 insertions(+) - ---- a/cryptoapi/v2.0/nss_cryptoapi.c -+++ b/cryptoapi/v2.0/nss_cryptoapi.c -@@ -39,7 +39,12 @@ - - #include - #include -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) - #include -+#else -+#include -+#include -+#endif - #include - #include - #include ---- a/cryptoapi/v2.0/nss_cryptoapi_aead.c -+++ b/cryptoapi/v2.0/nss_cryptoapi_aead.c -@@ -39,7 +39,12 @@ - - #include - #include -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) - #include -+#else -+#include -+#include -+#endif - #include - #include - #include ---- a/cryptoapi/v2.0/nss_cryptoapi_ahash.c -+++ b/cryptoapi/v2.0/nss_cryptoapi_ahash.c -@@ -38,7 +38,12 @@ - - #include - #include -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) - #include -+#else -+#include -+#include -+#endif - #include - #include - #include diff --git a/package/kernel/qca-nss-cfi/patches/0002-cryptoapi-v2.0-make-ablkcipher-optional.patch b/package/kernel/qca-nss-cfi/patches/0002-cryptoapi-v2.0-make-ablkcipher-optional.patch deleted file mode 100644 index e9702eb33a7705..00000000000000 --- a/package/kernel/qca-nss-cfi/patches/0002-cryptoapi-v2.0-make-ablkcipher-optional.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 26cca5006bddb0da57398452616e07ee7b11edb1 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Sun, 22 Jan 2023 22:01:34 +0100 -Subject: [PATCH 2/5] cryptoapi: v2.0: make ablkcipher optional - -albkcipher has been removed from the kernel in v5.5, so until it has been -converted to skcipher, lets make it optional to at least have hashes -working. - -Signed-off-by: Robert Marko ---- - cryptoapi/v2.0/Makefile | 3 +++ - cryptoapi/v2.0/nss_cryptoapi.c | 10 ++++++++++ - cryptoapi/v2.0/nss_cryptoapi_private.h | 2 ++ - 3 files changed, 15 insertions(+) - ---- a/cryptoapi/v2.0/Makefile -+++ b/cryptoapi/v2.0/Makefile -@@ -5,7 +5,10 @@ NSS_CRYPTOAPI_MOD_NAME=qca-nss-cfi-crypt - obj-m += $(NSS_CRYPTOAPI_MOD_NAME).o - $(NSS_CRYPTOAPI_MOD_NAME)-objs = nss_cryptoapi.o - $(NSS_CRYPTOAPI_MOD_NAME)-objs += nss_cryptoapi_aead.o -+ifneq "$(NSS_CRYPTOAPI_ABLK)" "n" - $(NSS_CRYPTOAPI_MOD_NAME)-objs += nss_cryptoapi_ablk.o -+ccflags-y += -DNSS_CRYPTOAPI_ABLK -+endif - $(NSS_CRYPTOAPI_MOD_NAME)-objs += nss_cryptoapi_ahash.o - - obj ?= . ---- a/cryptoapi/v2.0/nss_cryptoapi.c -+++ b/cryptoapi/v2.0/nss_cryptoapi.c -@@ -1367,6 +1367,7 @@ struct aead_alg cryptoapi_aead_algs[] = - /* - * ABLK cipher algorithms - */ -+#if defined(NSS_CRYPTOAPI_ABLK) - static struct crypto_alg cryptoapi_ablkcipher_algs[] = { - { - .cra_name = "cbc(aes)", -@@ -1466,6 +1467,7 @@ static struct crypto_alg cryptoapi_ablkc - }, - } - }; -+#endif - - /* - * AHASH algorithms -@@ -2189,7 +2191,9 @@ void nss_cryptoapi_add_ctx2debugfs(struc - */ - void nss_cryptoapi_attach_user(void *app_data, struct nss_crypto_user *user) - { -+#if defined(NSS_CRYPTOAPI_ABLK) - struct crypto_alg *ablk = cryptoapi_ablkcipher_algs; -+#endif - struct aead_alg *aead = cryptoapi_aead_algs; - struct ahash_alg *ahash = cryptoapi_ahash_algs; - struct nss_cryptoapi *sc = app_data; -@@ -2212,6 +2216,7 @@ void nss_cryptoapi_attach_user(void *app - g_cryptoapi.user = user; - } - -+#if defined(NSS_CRYPTOAPI_ABLK) - for (i = 0; enable_ablk && (i < ARRAY_SIZE(cryptoapi_ablkcipher_algs)); i++, ablk++) { - info = nss_cryptoapi_cra_name_lookup(ablk->cra_name); - if(!info || !nss_crypto_algo_is_supp(info->algo)) -@@ -2222,6 +2227,7 @@ void nss_cryptoapi_attach_user(void *app - ablk->cra_flags = 0; - } - } -+#endif - - for (i = 0; enable_aead && (i < ARRAY_SIZE(cryptoapi_aead_algs)); i++, aead++) { - info = nss_cryptoapi_cra_name_lookup(aead->base.cra_name); -@@ -2257,7 +2263,9 @@ void nss_cryptoapi_attach_user(void *app - */ - void nss_cryptoapi_detach_user(void *app_data, struct nss_crypto_user *user) - { -+#if defined(NSS_CRYPTOAPI_ABLK) - struct crypto_alg *ablk = cryptoapi_ablkcipher_algs; -+#endif - struct aead_alg *aead = cryptoapi_aead_algs; - struct ahash_alg *ahash = cryptoapi_ahash_algs; - struct nss_cryptoapi *sc = app_data; -@@ -2270,6 +2278,7 @@ void nss_cryptoapi_detach_user(void *app - */ - atomic_set(&g_cryptoapi.registered, 0); - -+#if defined(NSS_CRYPTOAPI_ABLK) - for (i = 0; enable_ablk && (i < ARRAY_SIZE(cryptoapi_ablkcipher_algs)); i++, ablk++) { - if (!ablk->cra_flags) - continue; -@@ -2277,6 +2286,7 @@ void nss_cryptoapi_detach_user(void *app - crypto_unregister_alg(ablk); - nss_cfi_info("%px: ABLK unregister succeeded, algo: %s\n", sc, ablk->cra_name); - } -+#endif - - for (i = 0; enable_aead && (i < ARRAY_SIZE(cryptoapi_aead_algs)); i++, aead++) { - if (!aead->base.cra_flags) ---- a/cryptoapi/v2.0/nss_cryptoapi_private.h -+++ b/cryptoapi/v2.0/nss_cryptoapi_private.h -@@ -250,12 +250,14 @@ extern void nss_cryptoapi_aead_tx_proc(s - /* - * ABLKCIPHER - */ -+#if defined(NSS_CRYPTOAPI_ABLK) - extern int nss_cryptoapi_ablkcipher_init(struct crypto_tfm *tfm); - extern void nss_cryptoapi_ablkcipher_exit(struct crypto_tfm *tfm); - extern int nss_cryptoapi_ablk_setkey(struct crypto_ablkcipher *cipher, const u8 *key, unsigned int len); - extern int nss_cryptoapi_ablk_encrypt(struct ablkcipher_request *req); - extern int nss_cryptoapi_ablk_decrypt(struct ablkcipher_request *req); - extern void nss_cryptoapi_copy_iv(struct nss_cryptoapi_ctx *ctx, struct scatterlist *sg, uint8_t *iv, uint8_t iv_len); -+#endif - - /* - * AHASH diff --git a/package/kernel/qca-nss-cfi/patches/0003-cryptoapi-v2.0-remove-setting-crypto_ahash_type-for-.patch b/package/kernel/qca-nss-cfi/patches/0003-cryptoapi-v2.0-remove-setting-crypto_ahash_type-for-.patch deleted file mode 100644 index ad11b8b35741f0..00000000000000 --- a/package/kernel/qca-nss-cfi/patches/0003-cryptoapi-v2.0-remove-setting-crypto_ahash_type-for-.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 797b5166783cda0886038ffb22f5386b9363a961 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Sun, 22 Jan 2023 22:08:27 +0100 -Subject: [PATCH 3/5] cryptoapi: v2.0: remove setting crypto_ahash_type for - newer kernels - -Upstream has stopped exporting crypto_ahash_type and removed setting it -on ahash algos since v4.19 as its easily identifiable by the struct type -and its being set in the core directly, so lets do the same. - -Signed-off-by: Robert Marko ---- - cryptoapi/v2.0/nss_cryptoapi.c | 24 ++++++++++++++++++++++++ - 1 file changed, 24 insertions(+) - ---- a/cryptoapi/v2.0/nss_cryptoapi.c -+++ b/cryptoapi/v2.0/nss_cryptoapi.c -@@ -1495,7 +1495,9 @@ static struct ahash_alg cryptoapi_ahash_ - .cra_blocksize = MD5_HMAC_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), - .cra_alignmask = 0, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) - .cra_type = &crypto_ahash_type, -+#endif - .cra_module = THIS_MODULE, - .cra_init = nss_cryptoapi_ahash_cra_init, - .cra_exit = nss_cryptoapi_ahash_cra_exit, -@@ -1521,7 +1523,9 @@ static struct ahash_alg cryptoapi_ahash_ - .cra_blocksize = SHA1_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), - .cra_alignmask = 0, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) - .cra_type = &crypto_ahash_type, -+#endif - .cra_module = THIS_MODULE, - .cra_init = nss_cryptoapi_ahash_cra_init, - .cra_exit = nss_cryptoapi_ahash_cra_exit, -@@ -1547,7 +1551,9 @@ static struct ahash_alg cryptoapi_ahash_ - .cra_blocksize = SHA224_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), - .cra_alignmask = 0, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) - .cra_type = &crypto_ahash_type, -+#endif - .cra_module = THIS_MODULE, - .cra_init = nss_cryptoapi_ahash_cra_init, - .cra_exit = nss_cryptoapi_ahash_cra_exit, -@@ -1573,7 +1579,9 @@ static struct ahash_alg cryptoapi_ahash_ - .cra_blocksize = SHA256_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), - .cra_alignmask = 0, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) - .cra_type = &crypto_ahash_type, -+#endif - .cra_module = THIS_MODULE, - .cra_init = nss_cryptoapi_ahash_cra_init, - .cra_exit = nss_cryptoapi_ahash_cra_exit, -@@ -1599,7 +1607,9 @@ static struct ahash_alg cryptoapi_ahash_ - .cra_blocksize = SHA384_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), - .cra_alignmask = 0, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) - .cra_type = &crypto_ahash_type, -+#endif - .cra_module = THIS_MODULE, - .cra_init = nss_cryptoapi_ahash_cra_init, - .cra_exit = nss_cryptoapi_ahash_cra_exit, -@@ -1625,7 +1635,9 @@ static struct ahash_alg cryptoapi_ahash_ - .cra_blocksize = SHA512_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), - .cra_alignmask = 0, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) - .cra_type = &crypto_ahash_type, -+#endif - .cra_module = THIS_MODULE, - .cra_init = nss_cryptoapi_ahash_cra_init, - .cra_exit = nss_cryptoapi_ahash_cra_exit, -@@ -1655,7 +1667,9 @@ static struct ahash_alg cryptoapi_ahash_ - .cra_blocksize = MD5_HMAC_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), - .cra_alignmask = 0, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) - .cra_type = &crypto_ahash_type, -+#endif - .cra_module = THIS_MODULE, - .cra_init = nss_cryptoapi_ahash_cra_init, - .cra_exit = nss_cryptoapi_ahash_cra_exit, -@@ -1681,7 +1695,9 @@ static struct ahash_alg cryptoapi_ahash_ - .cra_blocksize = SHA1_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), - .cra_alignmask = 0, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) - .cra_type = &crypto_ahash_type, -+#endif - .cra_module = THIS_MODULE, - .cra_init = nss_cryptoapi_ahash_cra_init, - .cra_exit = nss_cryptoapi_ahash_cra_exit, -@@ -1707,7 +1723,9 @@ static struct ahash_alg cryptoapi_ahash_ - .cra_blocksize = SHA224_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), - .cra_alignmask = 0, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) - .cra_type = &crypto_ahash_type, -+#endif - .cra_module = THIS_MODULE, - .cra_init = nss_cryptoapi_ahash_cra_init, - .cra_exit = nss_cryptoapi_ahash_cra_exit, -@@ -1733,7 +1751,9 @@ static struct ahash_alg cryptoapi_ahash_ - .cra_blocksize = SHA256_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), - .cra_alignmask = 0, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) - .cra_type = &crypto_ahash_type, -+#endif - .cra_module = THIS_MODULE, - .cra_init = nss_cryptoapi_ahash_cra_init, - .cra_exit = nss_cryptoapi_ahash_cra_exit, -@@ -1759,7 +1779,9 @@ static struct ahash_alg cryptoapi_ahash_ - .cra_blocksize = SHA384_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), - .cra_alignmask = 0, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) - .cra_type = &crypto_ahash_type, -+#endif - .cra_module = THIS_MODULE, - .cra_init = nss_cryptoapi_ahash_cra_init, - .cra_exit = nss_cryptoapi_ahash_cra_exit, -@@ -1785,7 +1807,9 @@ static struct ahash_alg cryptoapi_ahash_ - .cra_blocksize = SHA512_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), - .cra_alignmask = 0, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) - .cra_type = &crypto_ahash_type, -+#endif - .cra_module = THIS_MODULE, - .cra_init = nss_cryptoapi_ahash_cra_init, - .cra_exit = nss_cryptoapi_ahash_cra_exit, diff --git a/package/kernel/qca-nss-cfi/patches/0004-cryptoapi-v2.0-aead-add-downstream-crypto_tfm_alg_fl.patch b/package/kernel/qca-nss-cfi/patches/0004-cryptoapi-v2.0-aead-add-downstream-crypto_tfm_alg_fl.patch deleted file mode 100644 index a872321fb3fc98..00000000000000 --- a/package/kernel/qca-nss-cfi/patches/0004-cryptoapi-v2.0-aead-add-downstream-crypto_tfm_alg_fl.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 8db77add1a794bdee8eef0a351e40bf1cdf6dfa9 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Sun, 22 Jan 2023 22:09:51 +0100 -Subject: [PATCH 4/5] cryptoapi: v2.0: aead: add downstream - crypto_tfm_alg_flags - -crypto_tfm_alg_flags newer made it upstream, but as a temporary stopgap -until a better solution is figured out lets add it. - -Signed-off-by: Robert Marko ---- - cryptoapi/v2.0/nss_cryptoapi_aead.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/cryptoapi/v2.0/nss_cryptoapi_aead.c -+++ b/cryptoapi/v2.0/nss_cryptoapi_aead.c -@@ -61,6 +61,11 @@ - #include - #include "nss_cryptoapi_private.h" - -+static inline u32 crypto_tfm_alg_flags(struct crypto_tfm *tfm) -+{ -+ return tfm->__crt_alg->cra_flags & ~CRYPTO_ALG_TYPE_MASK; -+} -+ - /* - * nss_cryptoapi_aead_ctx2session() - * Cryptoapi function to get the session ID for an AEAD diff --git a/package/kernel/qca-nss-cfi/patches/0005-cryptoapi-v2.0-remove-dropped-flags.patch b/package/kernel/qca-nss-cfi/patches/0005-cryptoapi-v2.0-remove-dropped-flags.patch deleted file mode 100644 index 645633abc53e3c..00000000000000 --- a/package/kernel/qca-nss-cfi/patches/0005-cryptoapi-v2.0-remove-dropped-flags.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 62bbb188e1a72d28916e1eca31f4cb9fbbf51cd1 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Sun, 22 Jan 2023 22:11:06 +0100 -Subject: [PATCH 5/5] cryptoapi: v2.0: remove dropped flags - -Upstream has dropped these flags as there was no use for them, so lets do -the same. - -Signed-off-by: Robert Marko ---- - cryptoapi/v2.0/nss_cryptoapi_aead.c | 6 ------ - cryptoapi/v2.0/nss_cryptoapi_ahash.c | 4 ---- - 2 files changed, 10 deletions(-) - ---- a/cryptoapi/v2.0/nss_cryptoapi_aead.c -+++ b/cryptoapi/v2.0/nss_cryptoapi_aead.c -@@ -207,7 +207,6 @@ int nss_cryptoapi_aead_setkey_noauth(str - ctx->info = nss_cryptoapi_cra_name2info(crypto_tfm_alg_name(tfm), keylen, 0); - if (!ctx->info) { - nss_cfi_err("%px: Unable to find algorithm with keylen\n", ctx); -- crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); - return -ENOENT; - } - -@@ -239,7 +238,6 @@ int nss_cryptoapi_aead_setkey_noauth(str - status = nss_crypto_session_alloc(ctx->user, &data, &ctx->sid); - if (status < 0) { - nss_cfi_err("%px: Unable to allocate crypto session(%d)\n", ctx, status); -- crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_FLAGS); - return status; - } - -@@ -271,14 +269,12 @@ int nss_cryptoapi_aead_setkey(struct cry - */ - if (crypto_authenc_extractkeys(&keys, key, keylen) != 0) { - nss_cfi_err("%px: Unable to extract keys\n", ctx); -- crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); - return -EIO; - } - - ctx->info = nss_cryptoapi_cra_name2info(crypto_tfm_alg_name(tfm), keys.enckeylen, crypto_aead_maxauthsize(aead)); - if (!ctx->info) { - nss_cfi_err("%px: Unable to find algorithm with keylen\n", ctx); -- crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); - return -ENOENT; - } - -@@ -299,7 +295,6 @@ int nss_cryptoapi_aead_setkey(struct cry - */ - if (keys.authkeylen > ctx->info->auth_blocksize) { - nss_cfi_err("%px: Auth keylen(%d) exceeds supported\n", ctx, keys.authkeylen); -- crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); - return -EINVAL; - } - -@@ -342,7 +337,6 @@ int nss_cryptoapi_aead_setkey(struct cry - status = nss_crypto_session_alloc(ctx->user, &data, &ctx->sid); - if (status < 0) { - nss_cfi_err("%px: Unable to allocate crypto session(%d)\n", ctx, status); -- crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_FLAGS); - return status; - } - ---- a/cryptoapi/v2.0/nss_cryptoapi_ahash.c -+++ b/cryptoapi/v2.0/nss_cryptoapi_ahash.c -@@ -192,7 +192,6 @@ int nss_cryptoapi_ahash_setkey(struct cr - - ctx->info = nss_cryptoapi_cra_name2info(crypto_tfm_alg_name(tfm), 0, crypto_ahash_digestsize(ahash)); - if (!ctx->info) { -- crypto_ahash_set_flags(ahash, CRYPTO_TFM_RES_BAD_KEY_LEN); - return -EINVAL; - } - -@@ -215,7 +214,6 @@ int nss_cryptoapi_ahash_setkey(struct cr - status = nss_crypto_session_alloc(ctx->user, &data, &ctx->sid); - if (status < 0) { - nss_cfi_warn("%px: Unable to allocate crypto session(%d)\n", ctx, status); -- crypto_ahash_set_flags(ahash, CRYPTO_TFM_RES_BAD_FLAGS); - return status; - } - -@@ -299,7 +297,6 @@ int nss_cryptoapi_ahash_init(struct ahas - */ - ctx->info = nss_cryptoapi_cra_name2info(crypto_tfm_alg_name(tfm), 0, 0); - if (!ctx->info) { -- crypto_ahash_set_flags(ahash, CRYPTO_TFM_RES_BAD_KEY_LEN); - return -EINVAL; - } - -@@ -314,7 +311,6 @@ int nss_cryptoapi_ahash_init(struct ahas - status = nss_crypto_session_alloc(ctx->user, &data, &ctx->sid); - if (status < 0) { - nss_cfi_err("%px: Unable to allocate crypto session(%d)\n", ctx, status); -- crypto_ahash_set_flags(ahash, CRYPTO_TFM_RES_BAD_FLAGS); - return status; - } - diff --git a/package/kernel/qca-nss-cfi/patches/0006-cryptoapi-v2.0-convert-to-skcipher.patch b/package/kernel/qca-nss-cfi/patches/0006-cryptoapi-v2.0-convert-to-skcipher.patch deleted file mode 100644 index f85e3d892c9be2..00000000000000 --- a/package/kernel/qca-nss-cfi/patches/0006-cryptoapi-v2.0-convert-to-skcipher.patch +++ /dev/null @@ -1,1199 +0,0 @@ -From 1b30927548c2498c76b815b87f604f9a1de40a48 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Sun, 22 Jan 2023 23:31:09 +0100 -Subject: [PATCH] cryptoapi: v2.0: convert to skcipher - -Finally convert the driver from ablkcipher that was dropped in v5.5 to -skcipher. - -Signed-off-by: Robert Marko ---- - cryptoapi/v2.0/Makefile | 6 +- - cryptoapi/v2.0/nss_cryptoapi.c | 200 ++++++++---------- - cryptoapi/v2.0/nss_cryptoapi_private.h | 14 +- - ...ptoapi_ablk.c => nss_cryptoapi_skcipher.c} | 116 +++++----- - 4 files changed, 145 insertions(+), 191 deletions(-) - rename cryptoapi/v2.0/{nss_cryptoapi_ablk.c => nss_cryptoapi_skcipher.c} (74%) - ---- a/cryptoapi/v2.0/Makefile -+++ b/cryptoapi/v2.0/Makefile -@@ -5,9 +5,9 @@ NSS_CRYPTOAPI_MOD_NAME=qca-nss-cfi-crypt - obj-m += $(NSS_CRYPTOAPI_MOD_NAME).o - $(NSS_CRYPTOAPI_MOD_NAME)-objs = nss_cryptoapi.o - $(NSS_CRYPTOAPI_MOD_NAME)-objs += nss_cryptoapi_aead.o --ifneq "$(NSS_CRYPTOAPI_ABLK)" "n" --$(NSS_CRYPTOAPI_MOD_NAME)-objs += nss_cryptoapi_ablk.o --ccflags-y += -DNSS_CRYPTOAPI_ABLK -+ifneq "$(NSS_CRYPTOAPI_SKCIPHER)" "n" -+$(NSS_CRYPTOAPI_MOD_NAME)-objs += nss_cryptoapi_skcipher.o -+ccflags-y += -DNSS_CRYPTOAPI_SKCIPHER - endif - $(NSS_CRYPTOAPI_MOD_NAME)-objs += nss_cryptoapi_ahash.o - ---- a/cryptoapi/v2.0/nss_cryptoapi.c -+++ b/cryptoapi/v2.0/nss_cryptoapi.c -@@ -1367,104 +1367,78 @@ struct aead_alg cryptoapi_aead_algs[] = - /* - * ABLK cipher algorithms - */ --#if defined(NSS_CRYPTOAPI_ABLK) --static struct crypto_alg cryptoapi_ablkcipher_algs[] = { -+#if defined(NSS_CRYPTOAPI_SKCIPHER) -+static struct skcipher_alg cryptoapi_skcipher_algs[] = { - { -- .cra_name = "cbc(aes)", -- .cra_driver_name = "nss-cbc-aes", -- .cra_priority = 10000, -- .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, -- .cra_blocksize = AES_BLOCK_SIZE, -- .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), -- .cra_alignmask = 0, -- .cra_type = &crypto_ablkcipher_type, -- .cra_module = THIS_MODULE, -- .cra_init = nss_cryptoapi_ablkcipher_init, -- .cra_exit = nss_cryptoapi_ablkcipher_exit, -- .cra_u = { -- .ablkcipher = { -- .ivsize = AES_BLOCK_SIZE, -- .min_keysize = AES_MIN_KEY_SIZE, -- .max_keysize = AES_MAX_KEY_SIZE, -- .setkey = nss_cryptoapi_ablk_setkey, -- .encrypt = nss_cryptoapi_ablk_encrypt, -- .decrypt = nss_cryptoapi_ablk_decrypt, -- }, -- }, -- }, -- { -- .cra_name = "rfc3686(ctr(aes))", -- .cra_driver_name = "nss-rfc3686-ctr-aes", -- .cra_priority = 30000, -- .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, -- .cra_blocksize = AES_BLOCK_SIZE, -- .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), -- .cra_alignmask = 0, -- .cra_type = &crypto_ablkcipher_type, -- .cra_module = THIS_MODULE, -- .cra_init = nss_cryptoapi_ablkcipher_init, -- .cra_exit = nss_cryptoapi_ablkcipher_exit, -- .cra_u = { -- .ablkcipher = { -- .ivsize = CTR_RFC3686_IV_SIZE, --/* -- * geniv deprecated from kernel version 5.0 and above -- */ --#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) -- .geniv = "seqiv", --#endif -- .min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, -- .max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, -- .setkey = nss_cryptoapi_ablk_setkey, -- .encrypt = nss_cryptoapi_ablk_encrypt, -- .decrypt = nss_cryptoapi_ablk_decrypt, -- }, -- }, -- }, -- { -- .cra_name = "ecb(aes)", -- .cra_driver_name = "nss-ecb-aes", -- .cra_priority = 10000, -- .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, -- .cra_blocksize = AES_BLOCK_SIZE, -- .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), -- .cra_alignmask = 0, -- .cra_type = &crypto_ablkcipher_type, -- .cra_module = THIS_MODULE, -- .cra_init = nss_cryptoapi_ablkcipher_init, -- .cra_exit = nss_cryptoapi_ablkcipher_exit, -- .cra_u = { -- .ablkcipher = { -- .min_keysize = AES_MIN_KEY_SIZE, -- .max_keysize = AES_MAX_KEY_SIZE, -- .setkey = nss_cryptoapi_ablk_setkey, -- .encrypt = nss_cryptoapi_ablk_encrypt, -- .decrypt = nss_cryptoapi_ablk_decrypt, -- }, -- }, -- }, -- { -- .cra_name = "cbc(des3_ede)", -- .cra_driver_name = "nss-cbc-des-ede", -- .cra_priority = 10000, -- .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, -- .cra_blocksize = DES3_EDE_BLOCK_SIZE, -- .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), -- .cra_alignmask = 0, -- .cra_type = &crypto_ablkcipher_type, -- .cra_module = THIS_MODULE, -- .cra_init = nss_cryptoapi_ablkcipher_init, -- .cra_exit = nss_cryptoapi_ablkcipher_exit, -- .cra_u = { -- .ablkcipher = { -- .ivsize = DES3_EDE_BLOCK_SIZE, -- .min_keysize = DES3_EDE_KEY_SIZE, -- .max_keysize = DES3_EDE_KEY_SIZE, -- .setkey = nss_cryptoapi_ablk_setkey, -- .encrypt = nss_cryptoapi_ablk_encrypt, -- .decrypt = nss_cryptoapi_ablk_decrypt, -- }, -- }, -+ .base.cra_name = "cbc(aes)", -+ .base.cra_driver_name = "nss-cbc-aes", -+ .base.cra_priority = 10000, -+ .base.cra_flags = CRYPTO_ALG_ASYNC, -+ .base.cra_blocksize = AES_BLOCK_SIZE, -+ .base.cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), -+ .base.cra_alignmask = 0, -+ .base.cra_module = THIS_MODULE, -+ .init = nss_cryptoapi_skcipher_init, -+ .exit = nss_cryptoapi_skcipher_exit, -+ .ivsize = AES_BLOCK_SIZE, -+ .min_keysize = AES_MIN_KEY_SIZE, -+ .max_keysize = AES_MAX_KEY_SIZE, -+ .setkey = nss_cryptoapi_skcipher_setkey, -+ .encrypt = nss_cryptoapi_skcipher_encrypt, -+ .decrypt = nss_cryptoapi_skcipher_decrypt, -+ }, -+ { -+ .base.cra_name = "rfc3686(ctr(aes))", -+ .base.cra_driver_name = "nss-rfc3686-ctr-aes", -+ .base.cra_priority = 30000, -+ .base.cra_flags = CRYPTO_ALG_ASYNC, -+ .base.cra_blocksize = AES_BLOCK_SIZE, -+ .base.cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), -+ .base.cra_alignmask = 0, -+ .base.cra_module = THIS_MODULE, -+ .init = nss_cryptoapi_skcipher_init, -+ .exit = nss_cryptoapi_skcipher_exit, -+ .ivsize = CTR_RFC3686_IV_SIZE, -+ .min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, -+ .max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, -+ .setkey = nss_cryptoapi_skcipher_setkey, -+ .encrypt = nss_cryptoapi_skcipher_encrypt, -+ .decrypt = nss_cryptoapi_skcipher_decrypt, -+ }, -+ { -+ .base.cra_name = "ecb(aes)", -+ .base.cra_driver_name = "nss-ecb-aes", -+ .base.cra_priority = 10000, -+ .base.cra_flags = CRYPTO_ALG_ASYNC, -+ .base.cra_blocksize = AES_BLOCK_SIZE, -+ .base.cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), -+ .base.cra_alignmask = 0, -+ .base.cra_module = THIS_MODULE, -+ .init = nss_cryptoapi_skcipher_init, -+ .exit = nss_cryptoapi_skcipher_exit, -+ .min_keysize = AES_MIN_KEY_SIZE, -+ .max_keysize = AES_MAX_KEY_SIZE, -+ .setkey = nss_cryptoapi_skcipher_setkey, -+ .encrypt = nss_cryptoapi_skcipher_encrypt, -+ .decrypt = nss_cryptoapi_skcipher_decrypt, -+ }, -+ { -+ .base.cra_name = "cbc(des3_ede)", -+ .base.cra_driver_name = "nss-cbc-des-ede", -+ .base.cra_priority = 10000, -+ .base.cra_flags = CRYPTO_ALG_ASYNC, -+ .base.cra_blocksize = DES3_EDE_BLOCK_SIZE, -+ .base.cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), -+ .base.cra_alignmask = 0, -+ .base.cra_module = THIS_MODULE, -+ .init = nss_cryptoapi_skcipher_init, -+ .exit = nss_cryptoapi_skcipher_exit, -+ .ivsize = DES3_EDE_BLOCK_SIZE, -+ .min_keysize = DES3_EDE_KEY_SIZE, -+ .max_keysize = DES3_EDE_KEY_SIZE, -+ .setkey = nss_cryptoapi_skcipher_setkey, -+ .encrypt = nss_cryptoapi_skcipher_encrypt, -+ .decrypt = nss_cryptoapi_skcipher_decrypt, - } - }; - #endif -@@ -2215,8 +2189,8 @@ void nss_cryptoapi_add_ctx2debugfs(struc - */ - void nss_cryptoapi_attach_user(void *app_data, struct nss_crypto_user *user) - { --#if defined(NSS_CRYPTOAPI_ABLK) -- struct crypto_alg *ablk = cryptoapi_ablkcipher_algs; -+#if defined(NSS_CRYPTOAPI_SKCIPHER) -+ struct skcipher_alg *ablk = cryptoapi_skcipher_algs; - #endif - struct aead_alg *aead = cryptoapi_aead_algs; - struct ahash_alg *ahash = cryptoapi_ahash_algs; -@@ -2240,15 +2214,15 @@ void nss_cryptoapi_attach_user(void *app - g_cryptoapi.user = user; - } - --#if defined(NSS_CRYPTOAPI_ABLK) -- for (i = 0; enable_ablk && (i < ARRAY_SIZE(cryptoapi_ablkcipher_algs)); i++, ablk++) { -- info = nss_cryptoapi_cra_name_lookup(ablk->cra_name); -+#if defined(NSS_CRYPTOAPI_SKCIPHER) -+ for (i = 0; enable_ablk && (i < ARRAY_SIZE(cryptoapi_skcipher_algs)); i++, ablk++) { -+ info = nss_cryptoapi_cra_name_lookup(ablk->base.cra_name); - if(!info || !nss_crypto_algo_is_supp(info->algo)) - continue; - -- if (crypto_register_alg(ablk)) { -- nss_cfi_err("%px: ABLK registration failed(%s)\n", sc, ablk->cra_name); -- ablk->cra_flags = 0; -+ if (crypto_register_skcipher(ablk)) { -+ nss_cfi_err("%px: skcipher registration failed(%s)\n", sc, ablk->base.cra_name); -+ ablk->base.cra_flags = 0; - } - } - #endif -@@ -2287,8 +2261,8 @@ void nss_cryptoapi_attach_user(void *app - */ - void nss_cryptoapi_detach_user(void *app_data, struct nss_crypto_user *user) - { --#if defined(NSS_CRYPTOAPI_ABLK) -- struct crypto_alg *ablk = cryptoapi_ablkcipher_algs; -+#if defined(NSS_CRYPTOAPI_SKCIPHER) -+ struct skcipher_alg *ablk = cryptoapi_skcipher_algs; - #endif - struct aead_alg *aead = cryptoapi_aead_algs; - struct ahash_alg *ahash = cryptoapi_ahash_algs; -@@ -2302,13 +2276,13 @@ void nss_cryptoapi_detach_user(void *app - */ - atomic_set(&g_cryptoapi.registered, 0); - --#if defined(NSS_CRYPTOAPI_ABLK) -- for (i = 0; enable_ablk && (i < ARRAY_SIZE(cryptoapi_ablkcipher_algs)); i++, ablk++) { -- if (!ablk->cra_flags) -+#if defined(NSS_CRYPTOAPI_SKCIPHER) -+ for (i = 0; enable_ablk && (i < ARRAY_SIZE(cryptoapi_skcipher_algs)); i++, ablk++) { -+ if (!ablk->base.cra_flags) - continue; - -- crypto_unregister_alg(ablk); -- nss_cfi_info("%px: ABLK unregister succeeded, algo: %s\n", sc, ablk->cra_name); -+ crypto_unregister_skcipher(ablk); -+ nss_cfi_info("%px: skcipher unregister succeeded, algo: %s\n", sc, ablk->base.cra_name); - } - #endif - ---- a/cryptoapi/v2.0/nss_cryptoapi_private.h -+++ b/cryptoapi/v2.0/nss_cryptoapi_private.h -@@ -248,14 +248,14 @@ extern void nss_cryptoapi_aead_tx_proc(s - struct nss_cryptoapi_info *info, bool encrypt); - - /* -- * ABLKCIPHER -+ * SKCIPHER - */ --#if defined(NSS_CRYPTOAPI_ABLK) --extern int nss_cryptoapi_ablkcipher_init(struct crypto_tfm *tfm); --extern void nss_cryptoapi_ablkcipher_exit(struct crypto_tfm *tfm); --extern int nss_cryptoapi_ablk_setkey(struct crypto_ablkcipher *cipher, const u8 *key, unsigned int len); --extern int nss_cryptoapi_ablk_encrypt(struct ablkcipher_request *req); --extern int nss_cryptoapi_ablk_decrypt(struct ablkcipher_request *req); -+#if defined(NSS_CRYPTOAPI_SKCIPHER) -+extern int nss_cryptoapi_skcipher_init(struct crypto_skcipher *tfm); -+extern void nss_cryptoapi_skcipher_exit(struct crypto_skcipher *tfm); -+extern int nss_cryptoapi_skcipher_setkey(struct crypto_skcipher *cipher, const u8 *key, unsigned int len); -+extern int nss_cryptoapi_skcipher_encrypt(struct skcipher_request *req); -+extern int nss_cryptoapi_skcipher_decrypt(struct skcipher_request *req); - extern void nss_cryptoapi_copy_iv(struct nss_cryptoapi_ctx *ctx, struct scatterlist *sg, uint8_t *iv, uint8_t iv_len); - #endif - ---- a/cryptoapi/v2.0/nss_cryptoapi_ablk.c -+++ /dev/null -@@ -1,458 +0,0 @@ --/* Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. -- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. -- * -- * Permission to use, copy, modify, and/or distribute this software for any -- * purpose with or without fee is hereby granted, provided that the above -- * copyright notice and this permission notice appear in all copies. -- * -- * -- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -- * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT -- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -- * PERFORMANCE OF THIS SOFTWARE. -- * -- * -- */ -- --/** -- * nss_cryptoapi_ablk.c -- * Interface to communicate Native Linux crypto framework specific data -- * to Crypto core specific data -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include --#include --#include --#include --#include --#include --#include --#include "nss_cryptoapi_private.h" -- --extern struct nss_cryptoapi g_cryptoapi; -- --/* -- * nss_cryptoapi_skcipher_ctx2session() -- * Cryptoapi function to get the session ID for an skcipher -- */ --int nss_cryptoapi_skcipher_ctx2session(struct crypto_skcipher *sk, uint32_t *sid) --{ -- struct crypto_tfm *tfm = crypto_skcipher_tfm(sk); -- struct crypto_ablkcipher **actx, *ablk; -- struct ablkcipher_tfm *ablk_tfm; -- struct nss_cryptoapi_ctx *ctx; -- -- if (strncmp("nss-", crypto_tfm_alg_driver_name(tfm), 4)) -- return -EINVAL; -- -- /* Get the ablkcipher from the skcipher */ -- actx = crypto_skcipher_ctx(sk); -- if (!actx || !(*actx)) -- return -EINVAL; -- -- /* -- * The ablkcipher now obtained is a wrapper around the actual -- * ablkcipher that is created when the skcipher is created. -- * Hence we derive the required ablkcipher through ablkcipher_tfm. -- */ -- ablk_tfm = crypto_ablkcipher_crt(*actx); -- if (!ablk_tfm) -- return -EINVAL; -- -- ablk = ablk_tfm->base; -- if (!ablk) -- return -EINVAL; -- -- /* Get the nss_cryptoapi context stored in the ablkcipher */ -- ctx = crypto_ablkcipher_ctx(ablk); -- -- BUG_ON(!ctx); -- NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); -- -- *sid = ctx->sid; -- return 0; --} --EXPORT_SYMBOL(nss_cryptoapi_skcipher_ctx2session); -- --/* -- * nss_cryptoapi_ablkcipher_init() -- * Cryptoapi ablkcipher init function. -- */ --int nss_cryptoapi_ablkcipher_init(struct crypto_tfm *tfm) --{ -- struct nss_cryptoapi_ctx *ctx = crypto_tfm_ctx(tfm); -- -- BUG_ON(!ctx); -- NSS_CRYPTOAPI_SET_MAGIC(ctx); -- -- memset(ctx, 0, sizeof(struct nss_cryptoapi_ctx)); -- -- ctx->user = g_cryptoapi.user; -- ctx->stats.init++; -- ctx->sid = NSS_CRYPTO_SESSION_MAX; -- init_completion(&ctx->complete); -- -- return 0; --} -- --/* -- * nss_cryptoapi_ablkcipher_exit() -- * Cryptoapi ablkcipher exit function. -- */ --void nss_cryptoapi_ablkcipher_exit(struct crypto_tfm *tfm) --{ -- struct nss_cryptoapi_ctx *ctx = crypto_tfm_ctx(tfm); -- int ret; -- -- BUG_ON(!ctx); -- NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); -- -- ctx->stats.exit++; -- -- /* -- * When fallback_req is set, it means that fallback tfm was used -- * we didn't create any sessions. -- */ -- if (ctx->fallback_req) { -- ctx->stats.failed_fallback++; -- return; -- } -- -- if (!atomic_read(&ctx->active)) { -- ctx->stats.failed_exit++; -- return; -- } -- -- /* -- * Mark cryptoapi context as inactive -- */ -- atomic_set(&ctx->active, 0); -- -- if (!atomic_sub_and_test(1, &ctx->refcnt)) { -- /* -- * We need to wait for any outstanding packet using this ctx. -- * Once the last packet get processed, reference count will become -- * 0 this ctx. We will wait for the reference to go down to 0. -- */ -- ret = wait_for_completion_timeout(&ctx->complete, NSS_CRYPTOAPI_REQ_TIMEOUT_TICKS); -- WARN_ON(!ret); -- } -- -- if (ctx->sid != NSS_CRYPTO_SESSION_MAX) { -- nss_crypto_session_free(ctx->user, ctx->sid); -- debugfs_remove_recursive(ctx->dentry); -- ctx->sid = NSS_CRYPTO_SESSION_MAX; -- } -- -- NSS_CRYPTOAPI_CLEAR_MAGIC(ctx); --} -- --/* -- * nss_cryptoapi_ablk_setkey() -- * Cryptoapi setkey routine for aes. -- */ --int nss_cryptoapi_ablk_setkey(struct crypto_ablkcipher *cipher, const u8 *key, unsigned int keylen) --{ -- struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); -- struct nss_cryptoapi_ctx *ctx = crypto_tfm_ctx(tfm); -- struct nss_crypto_session_data data = {0}; -- int status; -- -- /* -- * Validate magic number - init should be called before setkey -- */ -- NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); -- -- ctx->info = nss_cryptoapi_cra_name2info(crypto_tfm_alg_name(tfm), keylen, 0); -- if (!ctx->info) { -- crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN); -- return -EINVAL; -- } -- -- ctx->iv_size = crypto_ablkcipher_ivsize(cipher); -- -- if (ctx->info->cipher_mode == NSS_CRYPTOAPI_CIPHER_MODE_CTR_RFC3686) { -- keylen = keylen - CTR_RFC3686_NONCE_SIZE; -- memcpy(ctx->ctx_iv, key + keylen, CTR_RFC3686_NONCE_SIZE); -- ctx->ctx_iv[3] = ntohl(0x1); -- ctx->iv_size += CTR_RFC3686_NONCE_SIZE + sizeof(uint32_t); -- } -- -- /* -- * Fill NSS crypto session data -- */ -- data.algo = ctx->info->algo; -- data.cipher_key = key; -- -- if (data.algo >= NSS_CRYPTO_CMN_ALGO_MAX) -- return -ERANGE; -- -- if (ctx->sid != NSS_CRYPTO_SESSION_MAX) { -- nss_crypto_session_free(ctx->user, ctx->sid); -- debugfs_remove_recursive(ctx->dentry); -- ctx->sid = NSS_CRYPTO_SESSION_MAX; -- } -- -- status = nss_crypto_session_alloc(ctx->user, &data, &ctx->sid); -- if (status < 0) { -- nss_cfi_err("%px: Unable to allocate crypto session(%d)\n", ctx, status); -- crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_FLAGS); -- return status; -- } -- -- nss_cryptoapi_add_ctx2debugfs(ctx); -- atomic_set(&ctx->active, 1); -- atomic_set(&ctx->refcnt, 1); -- return 0; --} -- --/* -- * nss_cryptoapi_ablkcipher_done() -- * Cipher operation completion callback function -- */ --void nss_cryptoapi_ablkcipher_done(void *app_data, struct nss_crypto_hdr *ch, uint8_t status) --{ -- struct ablkcipher_request *req = app_data; -- struct nss_cryptoapi_ctx *ctx = crypto_tfm_ctx(req->base.tfm); -- int error; -- -- BUG_ON(!ch); -- -- /* -- * Check cryptoapi context magic number. -- */ -- NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); -- -- /* -- * For skcipher decryption case, the last block of encrypted data is used as -- * an IV for the next data -- */ -- if (ch->op == NSS_CRYPTO_OP_DIR_ENC) { -- nss_cryptoapi_copy_iv(ctx, req->dst, req->info, ch->iv_len); -- } -- -- /* -- * Free crypto hdr -- */ -- nss_crypto_hdr_free(ctx->user, ch); -- -- nss_cfi_dbg("data dump after transformation\n"); -- nss_cfi_dbg_data(sg_virt(req->dst), req->nbytes, ' '); -- -- /* -- * Check if there is any error reported by hardware -- */ -- error = nss_cryptoapi_status2error(ctx, status); -- ctx->stats.completed++; -- -- /* -- * Decrement cryptoapi reference -- */ -- nss_cryptoapi_ref_dec(ctx); -- req->base.complete(&req->base, error); --} -- --/* -- * nss_cryptoapi_ablk_encrypt() -- * Crytoapi encrypt for AES and 3DES algorithms. -- */ --int nss_cryptoapi_ablk_encrypt(struct ablkcipher_request *req) --{ -- struct nss_cryptoapi_info info = {.op_dir = NSS_CRYPTO_OP_DIR_ENC}; -- struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(req); -- struct nss_cryptoapi_ctx *ctx = crypto_ablkcipher_ctx(cipher); -- struct crypto_tfm *tfm = req->base.tfm; -- struct scatterlist *cur; -- int tot_len = 0; -- int i; -- -- /* -- * Check cryptoapi context magic number. -- */ -- NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); -- -- /* -- * Check if cryptoapi context is active or not -- */ -- if (!atomic_read(&ctx->active)) -- return -EINVAL; -- -- if (sg_nents(req->src) != sg_nents(req->dst)) { -- ctx->stats.failed_req++; -- return -EINVAL; -- } -- -- /* -- * Block size not aligned. -- * AES-CTR requires only a one-byte block size alignment. -- */ -- if (!IS_ALIGNED(req->nbytes, crypto_tfm_alg_blocksize(tfm)) && ctx->info->blk_align) { -- ctx->stats.failed_align++; -- crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_BLOCK_LEN); -- return -EFAULT; -- } -- -- /* -- * Fill the request information structure -- */ -- info.iv = req->info; -- info.src.nsegs = sg_nents(req->src); -- info.dst.nsegs = sg_nents(req->dst); -- info.op_dir = NSS_CRYPTO_OP_DIR_ENC; -- info.cb = nss_cryptoapi_ablkcipher_done; -- info.iv_size = ctx->iv_size; -- info.src.first_sg = req->src; -- info.dst.first_sg = req->dst; -- info.dst.last_sg = sg_last(req->dst, info.dst.nsegs); -- -- /* out and in length will be same as ablk does only encrypt/decryt operation */ -- info.total_in_len = info.total_out_len = req->nbytes; -- info.in_place = (req->src == req->dst) ? true : false; -- -- /* -- * The exact length of data that needs to be ciphered for an ABLK -- * request is stored in req->nbytes. Hence we may have to reduce -- * the DMA length to what is specified in req->nbytes and later -- * restore the length of scatterlist back to its original value. -- */ -- for_each_sg(req->src, cur, info.src.nsegs, i) { -- if (!cur) -- break; -- -- tot_len += cur->length; -- if (!sg_next(cur)) -- break; -- } -- -- /* -- * We only support (2^16 - 1) length. -- */ -- if (tot_len > U16_MAX) { -- ctx->stats.failed_len++; -- return -EFBIG; -- } -- -- info.src.last_sg = cur; -- info.ahash_skip = tot_len - req->nbytes; -- -- if (!atomic_inc_not_zero(&ctx->refcnt)) -- return -ENOENT; -- -- return nss_cryptoapi_transform(ctx, &info, (void *)req, false); --} -- --/* -- * nss_cryptoapi_ablk_decrypt() -- * Crytoapi decrypt for AES and 3DES CBC algorithms. -- */ --int nss_cryptoapi_ablk_decrypt(struct ablkcipher_request *req) --{ -- struct nss_cryptoapi_info info = {.op_dir = NSS_CRYPTO_OP_DIR_DEC}; -- struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(req); -- struct nss_cryptoapi_ctx *ctx = crypto_ablkcipher_ctx(cipher); -- struct crypto_tfm *tfm = req->base.tfm; -- struct scatterlist *cur; -- int tot_len = 0; -- int i; -- -- /* -- * Check cryptoapi context magic number. -- */ -- NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); -- -- /* -- * Check if cryptoapi context is active or not -- */ -- if (!atomic_read(&ctx->active)) -- return -EINVAL; -- -- if (sg_nents(req->src) != sg_nents(req->dst)) { -- ctx->stats.failed_req++; -- return -EINVAL; -- } -- -- /* -- * Block size not aligned -- */ -- if (!IS_ALIGNED(req->nbytes, crypto_tfm_alg_blocksize(tfm)) && ctx->info->blk_align) { -- ctx->stats.failed_align++; -- crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_BLOCK_LEN); -- return -EFAULT; -- } -- -- /* -- * Fill the request information structure -- * Note: For CTR mode, IV size will be set to AES_BLOCK_SIZE. -- * This is because linux gives iv size as 8 while we need to alloc 16 bytes -- * in crypto hdr to accomodate -- * - 4 bytes of nonce -- * - 8 bytes of IV -- * - 4 bytes of initial counter -- */ -- info.iv = req->info; -- info.src.nsegs = sg_nents(req->src); -- info.dst.nsegs = sg_nents(req->dst); -- info.iv_size = ctx->iv_size; -- info.op_dir = NSS_CRYPTO_OP_DIR_DEC; -- info.cb = nss_cryptoapi_ablkcipher_done; -- info.src.first_sg = req->src; -- info.dst.first_sg = req->dst; -- info.dst.last_sg = sg_last(req->dst, info.dst.nsegs); -- -- /* out and in length will be same as ablk does only encrypt/decryt operation */ -- info.total_in_len = info.total_out_len = req->nbytes; -- info.in_place = (req->src == req->dst) ? true : false; -- -- /* -- * The exact length of data that needs to be ciphered for an ABLK -- * request is stored in req->nbytes. Hence we may have to reduce -- * the DMA length to what is specified in req->nbytes and later -- * restore the length of scatterlist back to its original value. -- */ -- for_each_sg(req->src, cur, info.src.nsegs, i) { -- tot_len += cur->length; -- if (!sg_next(cur)) -- break; -- } -- -- /* -- * We only support (2^16 - 1) length. -- */ -- if (tot_len > U16_MAX) { -- ctx->stats.failed_len++; -- return -EFBIG; -- } -- -- info.ahash_skip = tot_len - req->nbytes; -- info.src.last_sg = cur; -- -- if (!atomic_inc_not_zero(&ctx->refcnt)) -- return -ENOENT; -- -- return nss_cryptoapi_transform(ctx, &info, (void *)req, false); --} ---- /dev/null -+++ b/cryptoapi/v2.0/nss_cryptoapi_skcipher.c -@@ -0,0 +1,438 @@ -+/* Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. -+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT -+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -+ * PERFORMANCE OF THIS SOFTWARE. -+ * -+ * -+ */ -+ -+/** -+ * nss_cryptoapi_ablk.c -+ * Interface to communicate Native Linux crypto framework specific data -+ * to Crypto core specific data -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) -+#include -+#else -+#include -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "nss_cryptoapi_private.h" -+ -+extern struct nss_cryptoapi g_cryptoapi; -+ -+/* -+ * nss_cryptoapi_skcipher_ctx2session() -+ * Cryptoapi function to get the session ID for an skcipher -+ */ -+int nss_cryptoapi_skcipher_ctx2session(struct crypto_skcipher *sk, uint32_t *sid) -+{ -+ struct crypto_tfm *tfm = crypto_skcipher_tfm(sk); -+ struct nss_cryptoapi_ctx *ctx; -+ -+ if (strncmp("nss-", crypto_tfm_alg_driver_name(tfm), 4)) -+ return -EINVAL; -+ -+ /* Get the nss_cryptoapi context stored in skcipher */ -+ ctx = crypto_skcipher_ctx(sk); -+ BUG_ON(!ctx); -+ NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); -+ -+ *sid = ctx->sid; -+ return 0; -+} -+EXPORT_SYMBOL(nss_cryptoapi_skcipher_ctx2session); -+ -+/* -+ * nss_cryptoapi_skcipher_init() -+ * Cryptoapi skcipher init function. -+ */ -+int nss_cryptoapi_skcipher_init(struct crypto_skcipher *tfm) -+{ -+ struct nss_cryptoapi_ctx *ctx = crypto_skcipher_ctx(tfm); -+ -+ BUG_ON(!ctx); -+ NSS_CRYPTOAPI_SET_MAGIC(ctx); -+ -+ memset(ctx, 0, sizeof(struct nss_cryptoapi_ctx)); -+ -+ ctx->user = g_cryptoapi.user; -+ ctx->stats.init++; -+ ctx->sid = NSS_CRYPTO_SESSION_MAX; -+ init_completion(&ctx->complete); -+ -+ return 0; -+} -+ -+/* -+ * nss_cryptoapi_skcipher_exit() -+ * Cryptoapi skcipher exit function. -+ */ -+void nss_cryptoapi_skcipher_exit(struct crypto_skcipher *tfm) -+{ -+ struct nss_cryptoapi_ctx *ctx = crypto_skcipher_ctx(tfm); -+ int ret; -+ -+ BUG_ON(!ctx); -+ NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); -+ -+ ctx->stats.exit++; -+ -+ /* -+ * When fallback_req is set, it means that fallback tfm was used -+ * we didn't create any sessions. -+ */ -+ if (ctx->fallback_req) { -+ ctx->stats.failed_fallback++; -+ return; -+ } -+ -+ if (!atomic_read(&ctx->active)) { -+ ctx->stats.failed_exit++; -+ return; -+ } -+ -+ /* -+ * Mark cryptoapi context as inactive -+ */ -+ atomic_set(&ctx->active, 0); -+ -+ if (!atomic_sub_and_test(1, &ctx->refcnt)) { -+ /* -+ * We need to wait for any outstanding packet using this ctx. -+ * Once the last packet get processed, reference count will become -+ * 0 this ctx. We will wait for the reference to go down to 0. -+ */ -+ ret = wait_for_completion_timeout(&ctx->complete, NSS_CRYPTOAPI_REQ_TIMEOUT_TICKS); -+ WARN_ON(!ret); -+ } -+ -+ if (ctx->sid != NSS_CRYPTO_SESSION_MAX) { -+ nss_crypto_session_free(ctx->user, ctx->sid); -+ debugfs_remove_recursive(ctx->dentry); -+ ctx->sid = NSS_CRYPTO_SESSION_MAX; -+ } -+ -+ NSS_CRYPTOAPI_CLEAR_MAGIC(ctx); -+} -+ -+/* -+ * nss_cryptoapi_skcipher_setkey() -+ * Cryptoapi setkey routine for aes. -+ */ -+int nss_cryptoapi_skcipher_setkey(struct crypto_skcipher *cipher, const u8 *key, unsigned int keylen) -+{ -+ struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); -+ struct nss_cryptoapi_ctx *ctx = crypto_skcipher_ctx(cipher); -+ struct nss_crypto_session_data data = {0}; -+ int status; -+ -+ /* -+ * Validate magic number - init should be called before setkey -+ */ -+ NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); -+ -+ ctx->info = nss_cryptoapi_cra_name2info(crypto_tfm_alg_name(tfm), keylen, 0); -+ if (!ctx->info) { -+ return -EINVAL; -+ } -+ -+ ctx->iv_size = crypto_skcipher_ivsize(cipher); -+ -+ if (ctx->info->cipher_mode == NSS_CRYPTOAPI_CIPHER_MODE_CTR_RFC3686) { -+ keylen = keylen - CTR_RFC3686_NONCE_SIZE; -+ memcpy(ctx->ctx_iv, key + keylen, CTR_RFC3686_NONCE_SIZE); -+ ctx->ctx_iv[3] = ntohl(0x1); -+ ctx->iv_size += CTR_RFC3686_NONCE_SIZE + sizeof(uint32_t); -+ } -+ -+ /* -+ * Fill NSS crypto session data -+ */ -+ data.algo = ctx->info->algo; -+ data.cipher_key = key; -+ -+ if (data.algo >= NSS_CRYPTO_CMN_ALGO_MAX) -+ return -ERANGE; -+ -+ if (ctx->sid != NSS_CRYPTO_SESSION_MAX) { -+ nss_crypto_session_free(ctx->user, ctx->sid); -+ debugfs_remove_recursive(ctx->dentry); -+ ctx->sid = NSS_CRYPTO_SESSION_MAX; -+ } -+ -+ status = nss_crypto_session_alloc(ctx->user, &data, &ctx->sid); -+ if (status < 0) { -+ nss_cfi_err("%px: Unable to allocate crypto session(%d)\n", ctx, status); -+ return status; -+ } -+ -+ nss_cryptoapi_add_ctx2debugfs(ctx); -+ atomic_set(&ctx->active, 1); -+ atomic_set(&ctx->refcnt, 1); -+ return 0; -+} -+ -+/* -+ * nss_cryptoapi_skcipher_done() -+ * Cipher operation completion callback function -+ */ -+void nss_cryptoapi_skcipher_done(void *app_data, struct nss_crypto_hdr *ch, uint8_t status) -+{ -+ struct skcipher_request *req = app_data; -+ struct nss_cryptoapi_ctx *ctx = skcipher_request_ctx(req); -+ int error; -+ -+ BUG_ON(!ch); -+ -+ /* -+ * Check cryptoapi context magic number. -+ */ -+ NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); -+ -+ /* -+ * For skcipher decryption case, the last block of encrypted data is used as -+ * an IV for the next data -+ */ -+ if (ch->op == NSS_CRYPTO_OP_DIR_ENC) { -+ nss_cryptoapi_copy_iv(ctx, req->dst, req->iv, ch->iv_len); -+ } -+ -+ /* -+ * Free crypto hdr -+ */ -+ nss_crypto_hdr_free(ctx->user, ch); -+ -+ nss_cfi_dbg("data dump after transformation\n"); -+ nss_cfi_dbg_data(sg_virt(req->dst), req->cryptlen, ' '); -+ -+ /* -+ * Check if there is any error reported by hardware -+ */ -+ error = nss_cryptoapi_status2error(ctx, status); -+ ctx->stats.completed++; -+ -+ /* -+ * Decrement cryptoapi reference -+ */ -+ nss_cryptoapi_ref_dec(ctx); -+ req->base.complete(&req->base, error); -+} -+ -+/* -+ * nss_cryptoapi_skcipher_encrypt() -+ * Crytoapi encrypt for AES and 3DES algorithms. -+ */ -+int nss_cryptoapi_skcipher_encrypt(struct skcipher_request *req) -+{ -+ struct nss_cryptoapi_info info = {.op_dir = NSS_CRYPTO_OP_DIR_ENC}; -+ struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req); -+ struct nss_cryptoapi_ctx *ctx = crypto_skcipher_ctx(cipher); -+ struct crypto_tfm *tfm = req->base.tfm; -+ struct scatterlist *cur; -+ int tot_len = 0; -+ int i; -+ -+ /* -+ * Check cryptoapi context magic number. -+ */ -+ NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); -+ -+ /* -+ * Check if cryptoapi context is active or not -+ */ -+ if (!atomic_read(&ctx->active)) -+ return -EINVAL; -+ -+ if (sg_nents(req->src) != sg_nents(req->dst)) { -+ ctx->stats.failed_req++; -+ return -EINVAL; -+ } -+ -+ /* -+ * Block size not aligned. -+ * AES-CTR requires only a one-byte block size alignment. -+ */ -+ if (!IS_ALIGNED(req->cryptlen, crypto_tfm_alg_blocksize(tfm)) && ctx->info->blk_align) { -+ ctx->stats.failed_align++; -+ return -EFAULT; -+ } -+ -+ /* -+ * Fill the request information structure -+ */ -+ info.iv = req->iv; -+ info.src.nsegs = sg_nents(req->src); -+ info.dst.nsegs = sg_nents(req->dst); -+ info.op_dir = NSS_CRYPTO_OP_DIR_ENC; -+ info.cb = nss_cryptoapi_skcipher_done; -+ info.iv_size = ctx->iv_size; -+ info.src.first_sg = req->src; -+ info.dst.first_sg = req->dst; -+ info.dst.last_sg = sg_last(req->dst, info.dst.nsegs); -+ -+ /* out and in length will be same as ablk does only encrypt/decryt operation */ -+ info.total_in_len = info.total_out_len = req->cryptlen; -+ info.in_place = (req->src == req->dst) ? true : false; -+ -+ /* -+ * The exact length of data that needs to be ciphered for an ABLK -+ * request is stored in req->cryptlen. Hence we may have to reduce -+ * the DMA length to what is specified in req->cryptlen and later -+ * restore the length of scatterlist back to its original value. -+ */ -+ for_each_sg(req->src, cur, info.src.nsegs, i) { -+ if (!cur) -+ break; -+ -+ tot_len += cur->length; -+ if (!sg_next(cur)) -+ break; -+ } -+ -+ /* -+ * We only support (2^16 - 1) length. -+ */ -+ if (tot_len > U16_MAX) { -+ ctx->stats.failed_len++; -+ return -EFBIG; -+ } -+ -+ info.src.last_sg = cur; -+ info.ahash_skip = tot_len - req->cryptlen; -+ -+ if (!atomic_inc_not_zero(&ctx->refcnt)) -+ return -ENOENT; -+ -+ return nss_cryptoapi_transform(ctx, &info, (void *)req, false); -+} -+ -+/* -+ * nss_cryptoapi_skcipher_decrypt() -+ * Crytoapi decrypt for AES and 3DES CBC algorithms. -+ */ -+int nss_cryptoapi_skcipher_decrypt(struct skcipher_request *req) -+{ -+ struct nss_cryptoapi_info info = {.op_dir = NSS_CRYPTO_OP_DIR_DEC}; -+ struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req); -+ struct nss_cryptoapi_ctx *ctx = crypto_skcipher_ctx(cipher); -+ struct crypto_tfm *tfm = req->base.tfm; -+ struct scatterlist *cur; -+ int tot_len = 0; -+ int i; -+ -+ /* -+ * Check cryptoapi context magic number. -+ */ -+ NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); -+ -+ /* -+ * Check if cryptoapi context is active or not -+ */ -+ if (!atomic_read(&ctx->active)) -+ return -EINVAL; -+ -+ if (sg_nents(req->src) != sg_nents(req->dst)) { -+ ctx->stats.failed_req++; -+ return -EINVAL; -+ } -+ -+ /* -+ * Block size not aligned -+ */ -+ if (!IS_ALIGNED(req->cryptlen, crypto_tfm_alg_blocksize(tfm)) && ctx->info->blk_align) { -+ ctx->stats.failed_align++; -+ return -EFAULT; -+ } -+ -+ /* -+ * Fill the request information structure -+ * Note: For CTR mode, IV size will be set to AES_BLOCK_SIZE. -+ * This is because linux gives iv size as 8 while we need to alloc 16 bytes -+ * in crypto hdr to accomodate -+ * - 4 bytes of nonce -+ * - 8 bytes of IV -+ * - 4 bytes of initial counter -+ */ -+ info.iv = req->iv; -+ info.src.nsegs = sg_nents(req->src); -+ info.dst.nsegs = sg_nents(req->dst); -+ info.iv_size = ctx->iv_size; -+ info.op_dir = NSS_CRYPTO_OP_DIR_DEC; -+ info.cb = nss_cryptoapi_skcipher_done; -+ info.src.first_sg = req->src; -+ info.dst.first_sg = req->dst; -+ info.dst.last_sg = sg_last(req->dst, info.dst.nsegs); -+ -+ /* out and in length will be same as ablk does only encrypt/decryt operation */ -+ info.total_in_len = info.total_out_len = req->cryptlen; -+ info.in_place = (req->src == req->dst) ? true : false; -+ -+ /* -+ * The exact length of data that needs to be ciphered for an ABLK -+ * request is stored in req->cryptlen. Hence we may have to reduce -+ * the DMA length to what is specified in req->cryptlen and later -+ * restore the length of scatterlist back to its original value. -+ */ -+ for_each_sg(req->src, cur, info.src.nsegs, i) { -+ tot_len += cur->length; -+ if (!sg_next(cur)) -+ break; -+ } -+ -+ /* -+ * We only support (2^16 - 1) length. -+ */ -+ if (tot_len > U16_MAX) { -+ ctx->stats.failed_len++; -+ return -EFBIG; -+ } -+ -+ info.ahash_skip = tot_len - req->cryptlen; -+ info.src.last_sg = cur; -+ -+ if (!atomic_inc_not_zero(&ctx->refcnt)) -+ return -ENOENT; -+ -+ return nss_cryptoapi_transform(ctx, &info, (void *)req, false); -+} diff --git a/package/kernel/qca-nss-crypto/Makefile b/package/kernel/qca-nss-crypto/Makefile deleted file mode 100644 index 19b55133d88857..00000000000000 --- a/package/kernel/qca-nss-crypto/Makefile +++ /dev/null @@ -1,70 +0,0 @@ -include $(TOPDIR)/rules.mk - -PKG_NAME:=qca-nss-crypto -PKG_RELEASE:=1 - -PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-crypto.git -PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2022-12-15 -PKG_SOURCE_VERSION:=3c5a574ce99d7f0b9f892002020f1bf9bfc57a81 -PKG_MIRROR_HASH:=ff487c5574481f548eef7b61129fa7be1d83ae285dcc3356a06be237440d8782 - -PKG_BUILD_PARALLEL:=1 - -include $(INCLUDE_DIR)/kernel.mk -include $(INCLUDE_DIR)/package.mk - -# v1.0 is for Akronite -# v2.0 is for Hawkeye/Cypress/Maple -ifneq (, $(findstring $(CONFIG_TARGET_SUBTARGET), "ipq807x")) -NSS_CRYPTO_DIR:=v2.0 -else -NSS_CRYPTO_DIR:=v1.0 -endif - -define KernelPackage/qca-nss-crypto - SECTION:=kernel - CATEGORY:=Kernel modules - SUBMENU:=Cryptographic API modules - DEPENDS:=@TARGET_qualcommax +kmod-qca-nss-drv - TITLE:=Kernel driver for NSS crypto driver - FILES:=$(PKG_BUILD_DIR)/$(NSS_CRYPTO_DIR)/src/qca-nss-crypto.ko \ - $(PKG_BUILD_DIR)/$(NSS_CRYPTO_DIR)/tool/qca-nss-crypto-tool.ko - AUTOLOAD:=$(call AutoProbe,qca-nss-crypto) -endef - -define KernelPackage/qca-nss-crypto/Description -This package contains a NSS crypto driver for QCA chipset -endef - -define Build/InstallDev - $(INSTALL_DIR) $(1)/usr/include/qca-nss-crypto - $(CP) $(PKG_BUILD_DIR)/$(NSS_CRYPTO_DIR)/include/* $(1)/usr/include/qca-nss-crypto -endef - -EXTRA_CFLAGS+= \ - -DCONFIG_NSS_DEBUG_LEVEL=4 \ - -I$(STAGING_DIR)/usr/include/qca-nss-crypto \ - -I$(STAGING_DIR)/usr/include/qca-nss-drv \ - -I$(PKG_BUILD_DIR)/$(NSS_CRYPTO_DIR)/include \ - -I$(PKG_BUILD_DIR)/$(NSS_CRYPTO_DIR)/src - -ifeq ($(CONFIG_TARGET_BOARD), "qualcommax") - SOC:=$(CONFIG_TARGET_SUBTARGET) -endif - -define Build/Compile - +$(MAKE) -C "$(LINUX_DIR)" \ - CC="$(TARGET_CC)" \ - CROSS_COMPILE="$(TARGET_CROSS)" \ - ARCH="$(LINUX_KARCH)" \ - M="$(PKG_BUILD_DIR)" \ - EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ - NSS_CRYPTO_DIR=$(NSS_CRYPTO_DIR) \ - SoC=$(SOC) \ - $(KERNEL_MAKE_FLAGS) \ - $(PKG_JOBS) \ - modules -endef - -$(eval $(call KernelPackage,qca-nss-crypto)) diff --git a/package/kernel/qca-nss-crypto/patches/0001-nss-crypto-fix-SHA1-header-include.patch b/package/kernel/qca-nss-crypto/patches/0001-nss-crypto-fix-SHA1-header-include.patch deleted file mode 100644 index c9849a2e8d739b..00000000000000 --- a/package/kernel/qca-nss-crypto/patches/0001-nss-crypto-fix-SHA1-header-include.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0c6c593783f2d64a429ad38523661a915aa462fc Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Sun, 13 Mar 2022 13:44:47 +0100 -Subject: [PATCH 1/3] nss-crypto: fix SHA1 header include - -SHA1 header has been merged to the generic SHA one, -and with that the cryptohash.h was dropped. - -So, fix include in kernels 5.8 and newer. - -Signed-off-by: Robert Marko ---- - v2.0/src/nss_crypto_hlos.h | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/v2.0/src/nss_crypto_hlos.h -+++ b/v2.0/src/nss_crypto_hlos.h -@@ -55,7 +55,9 @@ - #include - #include - #include -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0) - #include -+#endif - #include - #include - #include diff --git a/package/kernel/qca-nss-crypto/patches/0002-nss-crypto-replace-ioremap_nocache-with-ioremap.patch b/package/kernel/qca-nss-crypto/patches/0002-nss-crypto-replace-ioremap_nocache-with-ioremap.patch deleted file mode 100644 index 19454c457b3018..00000000000000 --- a/package/kernel/qca-nss-crypto/patches/0002-nss-crypto-replace-ioremap_nocache-with-ioremap.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 8baa8e747247403c6f814ea5dc3e463c70e0415f Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Tue, 8 Jun 2021 22:14:34 +0200 -Subject: [PATCH 2/3] nss-crypto: replace ioremap_nocache() with ioremap - -ioremap_nocache() was dropped in kernel 5.5 as regular -ioremap() was exactly the same. - -So, simply replace all of the ioremap_nocache() calls -with ioremap(). - -Signed-off-by: Robert Marko ---- - v1.0/src/nss_crypto_dtsi.c | 4 ++-- - v1.0/src/nss_crypto_platform.c | 4 ++-- - v2.0/src/hal/ipq50xx/nss_crypto_ce5.c | 4 ++-- - v2.0/src/hal/ipq60xx/nss_crypto_eip197.c | 2 +- - v2.0/src/hal/ipq807x/nss_crypto_eip197.c | 2 +- - 5 files changed, 8 insertions(+), 8 deletions(-) - ---- a/v1.0/src/nss_crypto_dtsi.c -+++ b/v1.0/src/nss_crypto_dtsi.c -@@ -311,11 +311,11 @@ static int nss_crypto_probe(struct platf - e_ctrl->dev = &pdev->dev; - - e_ctrl->cmd_base = crypto_res.start; -- e_ctrl->crypto_base = ioremap_nocache(e_ctrl->cmd_base, resource_size(&crypto_res)); -+ e_ctrl->crypto_base = ioremap(e_ctrl->cmd_base, resource_size(&crypto_res)); - nss_crypto_assert(e_ctrl->crypto_base); - - e_ctrl->bam_pbase = bam_res.start; -- e_ctrl->bam_base = ioremap_nocache(e_ctrl->bam_pbase, resource_size(&bam_res)); -+ e_ctrl->bam_base = ioremap(e_ctrl->bam_pbase, resource_size(&bam_res)); - nss_crypto_assert(e_ctrl->bam_base); - - e_ctrl->bam_ee = bam_ee; ---- a/v1.0/src/nss_crypto_platform.c -+++ b/v1.0/src/nss_crypto_platform.c -@@ -134,11 +134,11 @@ static int nss_crypto_probe(struct platf - e_ctrl->bam_ee = res->bam_ee; - - e_ctrl->cmd_base = res->crypto_pbase; -- e_ctrl->crypto_base = ioremap_nocache(res->crypto_pbase, res->crypto_pbase_sz); -+ e_ctrl->crypto_base = ioremap(res->crypto_pbase, res->crypto_pbase_sz); - nss_crypto_assert(e_ctrl->crypto_base); - - e_ctrl->bam_pbase = res->bam_pbase; -- e_ctrl->bam_base = ioremap_nocache(res->bam_pbase, res->bam_pbase_sz); -+ e_ctrl->bam_base = ioremap(res->bam_pbase, res->bam_pbase_sz); - nss_crypto_assert(e_ctrl->bam_base); - - /* ---- a/v2.0/src/hal/ipq50xx/nss_crypto_ce5.c -+++ b/v2.0/src/hal/ipq50xx/nss_crypto_ce5.c -@@ -288,7 +288,7 @@ int nss_crypto_ce5_engine_init(struct pl - * remap the I/O addresses for crypto - */ - eng->crypto_paddr = crypto_res->start; -- eng->crypto_vaddr = ioremap_nocache(crypto_res->start, resource_size(crypto_res)); -+ eng->crypto_vaddr = ioremap(crypto_res->start, resource_size(crypto_res)); - if (!eng->crypto_vaddr) { - nss_crypto_warn("%px: unable to remap crypto_addr(0x%px)\n", node, (void *)eng->crypto_paddr); - nss_crypto_engine_free(eng); -@@ -299,7 +299,7 @@ int nss_crypto_ce5_engine_init(struct pl - * remap the I/O addresses for bam - */ - eng->dma_paddr = bam_res->start; -- eng->dma_vaddr = ioremap_nocache(bam_res->start, resource_size(bam_res)); -+ eng->dma_vaddr = ioremap(bam_res->start, resource_size(bam_res)); - if (!eng->dma_vaddr) { - iounmap(eng->crypto_vaddr); - nss_crypto_warn("%px: unable to remap dma_addr(0x%px)\n", node, (void *)eng->dma_paddr); ---- a/v2.0/src/hal/ipq60xx/nss_crypto_eip197.c -+++ b/v2.0/src/hal/ipq60xx/nss_crypto_eip197.c -@@ -490,7 +490,7 @@ int nss_crypto_eip197_engine_init(struct - * remap the I/O addresses - */ - paddr = res->start + offset; -- vaddr = ioremap_nocache(paddr, resource_size(res)); -+ vaddr = ioremap(paddr, resource_size(res)); - if (!vaddr) { - nss_crypto_warn("%px: unable to remap crypto_addr(0x%px)\n", node, (void *)paddr); - return -EIO; ---- a/v2.0/src/hal/ipq807x/nss_crypto_eip197.c -+++ b/v2.0/src/hal/ipq807x/nss_crypto_eip197.c -@@ -490,7 +490,7 @@ int nss_crypto_eip197_engine_init(struct - * remap the I/O addresses - */ - paddr = res->start + offset; -- vaddr = ioremap_nocache(paddr, resource_size(res)); -+ vaddr = ioremap(paddr, resource_size(res)); - if (!vaddr) { - nss_crypto_warn("%px: unable to remap crypto_addr(0x%px)\n", node, (void *)paddr); - return -EIO; diff --git a/package/kernel/qca-nss-crypto/patches/0003-nss-crypto-fix-SHA-header-include-in-5.15.patch b/package/kernel/qca-nss-crypto/patches/0003-nss-crypto-fix-SHA-header-include-in-5.15.patch deleted file mode 100644 index 61df791fdd7e9d..00000000000000 --- a/package/kernel/qca-nss-crypto/patches/0003-nss-crypto-fix-SHA-header-include-in-5.15.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 96da3ca01ac172e5d858209b3d3d9aefad04423c Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Sun, 13 Mar 2022 13:47:24 +0100 -Subject: [PATCH 3/3] nss-crypto: fix SHA header include in 5.15 - -SHA header was split into SHA-1 and SHA-2 headers in kernel 5.11, so -fix the include for newer kernels. - -Signed-off-by: Robert Marko ---- - v2.0/src/nss_crypto_ctrl.c | 6 ++++++ - v2.0/src/nss_crypto_hlos.h | 4 ++++ - 2 files changed, 10 insertions(+) - ---- a/v2.0/src/nss_crypto_ctrl.c -+++ b/v2.0/src/nss_crypto_ctrl.c -@@ -38,7 +38,13 @@ - #include - #include - #include -+#include -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) - #include -+#else -+#include -+#include -+#endif - #include - #include - #include ---- a/v2.0/src/nss_crypto_hlos.h -+++ b/v2.0/src/nss_crypto_hlos.h -@@ -58,7 +58,11 @@ - #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0) - #include - #endif -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) - #include -+#else -+#include -+#endif - #include - #include - #include From c156f0525e02f4fa1504abb25ace6d3cfc4ea65f Mon Sep 17 00:00:00 2001 From: Qosmio Date: Thu, 22 Feb 2024 20:38:42 -0500 Subject: [PATCH 121/225] qca-ssdk: Fix broken patch Recent commit `d08d53346b993431e309797d5e6de8da20147c3c` qca-ssdk: support selecting PCS channel for PORT3 on IPQ6018 Ends up breaking patch. Updated to address the following: Applying patch 102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch patching file include/init/ssdk_dts.h Hunk #1 succeeded at 99 (offset -2 lines). Hunk #2 succeeded at 161 (offset -3 lines). patching file src/adpt/cppe/adpt_cppe_portctrl.c patching file src/adpt/hppe/adpt_hppe_uniphy.c Hunk #1 succeeded at 1152 (offset 30 lines). Hunk #2 succeeded at 1161 (offset 30 lines). patching file src/init/ssdk_dts.c Hunk #1 FAILED at 279. Hunk #2 succeeded at 305 (offset -8 lines). Hunk #3 succeeded at 1310 (offset -16 lines). 1 out of 3 hunks FAILED -- rejects in file src/init/ssdk_dts.c Patch 102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch does not apply (enforce with -f) --- .../patches/0004-fix-compile-warnings.patch | 18 +++++----- ...-selecting-PCS-channel-for-PORT3-on-.patch | 33 +++++++------------ 2 files changed, 20 insertions(+), 31 deletions(-) diff --git a/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch b/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch index 47a7e824c78e8a..fa1cd895c2c0a5 100644 --- a/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch +++ b/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch @@ -9,9 +9,9 @@ -#else - /* fall through */ -#endif - case CHIP_HPPE: - if (g_adpt_api[dev_id] == NULL) { - g_adpt_api[dev_id] = aos_mem_alloc(sizeof(adpt_api_t)); + case CHIP_HPPE: + if (g_adpt_api[dev_id] == NULL) { + g_adpt_api[dev_id] = aos_mem_alloc(sizeof(adpt_api_t)); --- a/src/fal/fal_port_ctrl.c +++ b/src/fal/fal_port_ctrl.c @@ -2089,7 +2089,7 @@ fal_port_hibernate_get (a_uint32_t dev_i @@ -22,7 +22,7 @@ + fal_cable_status_t * cable_status, a_uint32_t * cable_len) { sw_error_t rv; - + --- a/src/fal/fal_portvlan.c +++ b/src/fal/fal_portvlan.c @@ -2173,7 +2173,7 @@ fal_netisolate_get(a_uint32_t dev_id, a_ @@ -33,7 +33,7 @@ +fal_eg_trans_filter_bypass_en_set(a_uint32_t dev_id, a_uint32_t enable) { sw_error_t rv; - + @@ -2190,7 +2190,7 @@ fal_eg_trans_filter_bypass_en_set(a_uint * @return SW_OK or error code */ @@ -42,7 +42,7 @@ +fal_eg_trans_filter_bypass_en_get(a_uint32_t dev_id, a_uint32_t* enable) { sw_error_t rv; - + --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ all: $(BIN_DIR) kslib @@ -51,6 +51,6 @@ modules: $(BIN_DIR) kslib_c - mkdir -p ./temp/;cp * ./temp -a;cd ./temp;cp ../Makefile.modules ./Makefile; + mkdir -p ./temp/;cp app config include ko_Makefile make Makefile.modules src ./temp -a;cd ./temp;cp ../Makefile.modules ./Makefile; - make -C $(SYS_PATH) M=$(PRJ_PATH)/temp $(LNX_MAKEOPTS) modules - cp $(PRJ_PATH)/temp/Module.symvers $(PRJ_PATH)/Module.symvers; - cp temp/*.ko build/bin; + make -C $(SYS_PATH) M=$(PRJ_PATH)/temp $(LNX_MAKEOPTS) modules + cp $(PRJ_PATH)/temp/Module.symvers $(PRJ_PATH)/Module.symvers; + cp temp/*.ko build/bin; diff --git a/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch b/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch index a8863bf4630b74..abe322718ba507 100644 --- a/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch +++ b/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch @@ -22,11 +22,9 @@ Signed-off-by: Mantas Pucka src/init/ssdk_dts.c | 27 +++++++++++++++++++++++++++ 4 files changed, 32 insertions(+), 8 deletions(-) -diff --git a/include/init/ssdk_dts.h b/include/init/ssdk_dts.h -index 00fa4c1..210c788 100755 --- a/include/init/ssdk_dts.h +++ b/include/init/ssdk_dts.h -@@ -101,6 +101,7 @@ typedef struct +@@ -99,6 +99,7 @@ typedef struct a_uint32_t emu_chip_ver; /*only valid when is_emulation is true*/ a_uint32_t clk_mode; a_uint32_t pcie_hw_base; @@ -34,7 +32,7 @@ index 00fa4c1..210c788 100755 } ssdk_dt_cfg; #define SSDK_MAX_NR_ETH 6 -@@ -163,6 +164,7 @@ a_uint32_t ssdk_device_id_get(a_uint32_t index); +@@ -160,6 +161,7 @@ a_uint32_t ssdk_device_id_get(a_uint32_t struct device_node *ssdk_dts_node_get(a_uint32_t dev_id); struct clk *ssdk_dts_essclk_get(a_uint32_t dev_id); struct clk *ssdk_dts_cmnclk_get(a_uint32_t dev_id); @@ -42,8 +40,6 @@ index 00fa4c1..210c788 100755 int ssdk_switch_device_num_init(void); void ssdk_switch_device_num_exit(void); -diff --git a/src/adpt/cppe/adpt_cppe_portctrl.c b/src/adpt/cppe/adpt_cppe_portctrl.c -index 00d0404..6b32f79 100755 --- a/src/adpt/cppe/adpt_cppe_portctrl.c +++ b/src/adpt/cppe/adpt_cppe_portctrl.c @@ -33,6 +33,7 @@ @@ -54,7 +50,7 @@ index 00d0404..6b32f79 100755 #include "adpt.h" #include "adpt_hppe.h" #include "adpt_cppe_portctrl.h" -@@ -60,8 +61,7 @@ _adpt_cppe_port_mux_mac_set(a_uint32_t dev_id, fal_port_t port_id, +@@ -60,8 +61,7 @@ _adpt_cppe_port_mux_mac_set(a_uint32_t d case SSDK_PHYSICAL_PORT3: case SSDK_PHYSICAL_PORT4: if (mode0 == PORT_WRAPPER_PSGMII) { @@ -64,11 +60,9 @@ index 00d0404..6b32f79 100755 cppe_port_mux_ctrl.bf.port3_pcs_sel = CPPE_PORT3_PCS_SEL_PCS0_CHANNEL4; cppe_port_mux_ctrl.bf.port4_pcs_sel = -diff --git a/src/adpt/hppe/adpt_hppe_uniphy.c b/src/adpt/hppe/adpt_hppe_uniphy.c -index 5e36602..bad1eab 100644 --- a/src/adpt/hppe/adpt_hppe_uniphy.c +++ b/src/adpt/hppe/adpt_hppe_uniphy.c -@@ -1122,9 +1122,6 @@ __adpt_hppe_uniphy_psgmii_mode_set(a_uint32_t dev_id, a_uint32_t uniphy_index) +@@ -1152,9 +1152,6 @@ __adpt_hppe_uniphy_psgmii_mode_set(a_uin { a_uint32_t i; sw_error_t rv = SW_OK; @@ -78,7 +72,7 @@ index 5e36602..bad1eab 100644 union uniphy_mode_ctrl_u uniphy_mode_ctrl; -@@ -1134,9 +1131,7 @@ __adpt_hppe_uniphy_psgmii_mode_set(a_uint32_t dev_id, a_uint32_t uniphy_index) +@@ -1164,9 +1161,7 @@ __adpt_hppe_uniphy_psgmii_mode_set(a_uin SSDK_DEBUG("uniphy %d is psgmii mode\n", uniphy_index); #if defined(CPPE) if (adpt_ppe_type_get(dev_id) == CPPE_TYPE) { @@ -89,25 +83,23 @@ index 5e36602..bad1eab 100644 SSDK_INFO("cypress uniphy %d is qca8072 psgmii mode\n", uniphy_index); rv = __adpt_cppe_uniphy_mode_set(dev_id, uniphy_index, PORT_WRAPPER_PSGMII); -diff --git a/src/init/ssdk_dts.c b/src/init/ssdk_dts.c -index 686b6d2..70b0a09 100644 --- a/src/init/ssdk_dts.c +++ b/src/init/ssdk_dts.c -@@ -279,6 +279,13 @@ struct clk *ssdk_dts_cmnclk_get(a_uint32_t dev_id) +@@ -272,6 +272,13 @@ struct clk *ssdk_dts_cmnclk_get(a_uint32 return cfg->cmnblk_clk; } +a_uint32_t ssdk_dts_port3_pcs_channel_get(a_uint32_t dev_id) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; -+ ++ + return cfg->port3_pcs_channel; +} + - #ifndef BOARD_AR71XX #if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) static void ssdk_dt_parse_mac_mode(a_uint32_t dev_id, -@@ -313,6 +320,25 @@ static void ssdk_dt_parse_mac_mode(a_uint32_t dev_id, + struct device_node *switch_node, ssdk_init_cfg *cfg) +@@ -305,6 +312,25 @@ static void ssdk_dt_parse_mac_mode(a_uin return; } @@ -117,7 +109,7 @@ index 686b6d2..70b0a09 100644 +{ + const __be32 *port3_pcs_channel; + a_uint32_t len = 0; -+ ++ + port3_pcs_channel = of_get_property(switch_node, "port3_pcs_channel", &len); + if (!port3_pcs_channel) { + ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->port3_pcs_channel = 2; @@ -133,7 +125,7 @@ index 686b6d2..70b0a09 100644 #ifdef IN_UNIPHY static void ssdk_dt_parse_uniphy(a_uint32_t dev_id) { -@@ -1307,6 +1333,7 @@ sw_error_t ssdk_dt_parse(ssdk_init_cfg *cfg, a_uint32_t num, a_uint32_t *dev_id) +@@ -1291,6 +1317,7 @@ sw_error_t ssdk_dt_parse(ssdk_init_cfg * rv = ssdk_dt_parse_access_mode(switch_node, ssdk_dt_priv); SW_RTN_ON_ERROR(rv); ssdk_dt_parse_mac_mode(*dev_id, switch_node, cfg); @@ -141,6 +133,3 @@ index 686b6d2..70b0a09 100644 ssdk_dt_parse_mdio(*dev_id, switch_node, cfg); ssdk_dt_parse_port_bmp(*dev_id, switch_node, cfg); ssdk_dt_parse_interrupt(*dev_id, switch_node); --- -2.7.4 - From 90e15f6b1705520780ee7ef22c2f7b2d1a689543 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Tue, 27 Feb 2024 00:44:25 -0500 Subject: [PATCH 122/225] ath11k_nss: add missing support to enable/disable bss color collision detection --- ...ort-to-enable-disable-bss-color-coll.patch | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 package/kernel/mac80211/patches/nss/subsys/649-nl80211-Add-support-to-enable-disable-bss-color-coll.patch diff --git a/package/kernel/mac80211/patches/nss/subsys/649-nl80211-Add-support-to-enable-disable-bss-color-coll.patch b/package/kernel/mac80211/patches/nss/subsys/649-nl80211-Add-support-to-enable-disable-bss-color-coll.patch new file mode 100644 index 00000000000000..058d983c8a15f6 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/subsys/649-nl80211-Add-support-to-enable-disable-bss-color-coll.patch @@ -0,0 +1,78 @@ +From e4439779d28949a61228b359a27f399df9b42b1a Mon Sep 17 00:00:00 2001 +From: Rameshkumar Sundaram +Date: Mon, 25 Oct 2021 19:06:04 +0530 +Subject: [PATCH 1/2] nl80211: add support to enable/disable bss color + collision detection + +As per 802.11ax-2021, STAs shall process BSS Color Change Announcement +(BCCA) from AP and switch to new color, but some STAs aren't processing +BCCA from AP and not doing color switch, causing them to drop data +frames from AP post color change. + +Provide an option to disable color collision detection and therefore +not to do BCCA to mitigate the same from AP. If it's required in case +where STA supports BCCA handling, then it can enabled in AP using this +option. + +Signed-off-by: Rameshkumar Sundaram +Signed-off-by: Dinesh Karthikeyan +--- + include/net/cfg80211.h | 2 ++ + include/uapi/linux/nl80211.h | 3 +++ + net/wireless/nl80211.c | 3 +++ + 3 files changed, 8 insertions(+) + +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -312,11 +312,13 @@ struct ieee80211_he_obss_pd { + * @color: the current color. + * @enabled: HE BSS color is used + * @partial: define the AID equation. ++ * @collision_detection_enabled: HE BSS color collision detection is enabled. + */ + struct cfg80211_he_bss_color { + u8 color; + bool enabled; + bool partial; ++ bool collision_detection_enabled; + }; + + /** +--- a/include/uapi/linux/nl80211.h ++++ b/include/uapi/linux/nl80211.h +@@ -7566,6 +7566,8 @@ enum nl80211_obss_pd_attributes { + * @NL80211_HE_BSS_COLOR_ATTR_COLOR: the current BSS Color. + * @NL80211_HE_BSS_COLOR_ATTR_DISABLED: is BSS coloring disabled. + * @NL80211_HE_BSS_COLOR_ATTR_PARTIAL: the AID equation to be used.. ++ * @NL80211_HE_BSS_COLOR_ATTR_COLLISION_DETECTION_DISABLED: is BSS ++ * color collision detection disabled. + * + * @__NL80211_HE_BSS_COLOR_ATTR_LAST: Internal + * @NL80211_HE_BSS_COLOR_ATTR_MAX: highest BSS Color attribute. +@@ -7576,6 +7578,7 @@ enum nl80211_bss_color_attributes { + NL80211_HE_BSS_COLOR_ATTR_COLOR, + NL80211_HE_BSS_COLOR_ATTR_DISABLED, + NL80211_HE_BSS_COLOR_ATTR_PARTIAL, ++ NL80211_HE_BSS_COLOR_ATTR_COLLISION_DETECTION_DISABLED, + + /* keep last */ + __NL80211_HE_BSS_COLOR_ATTR_LAST, +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -378,6 +378,7 @@ he_bss_color_policy[NL80211_HE_BSS_COLOR + [NL80211_HE_BSS_COLOR_ATTR_COLOR] = NLA_POLICY_RANGE(NLA_U8, 1, 63), + [NL80211_HE_BSS_COLOR_ATTR_DISABLED] = { .type = NLA_FLAG }, + [NL80211_HE_BSS_COLOR_ATTR_PARTIAL] = { .type = NLA_FLAG }, ++ [NL80211_HE_BSS_COLOR_ATTR_COLLISION_DETECTION_DISABLED] = { .type = NLA_FLAG }, + }; + + static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = { +@@ -5495,6 +5496,8 @@ static int nl80211_parse_he_bss_color(st + !nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_DISABLED]); + he_bss_color->partial = + nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_PARTIAL]); ++ he_bss_color->collision_detection_enabled = ++ !nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_COLLISION_DETECTION_DISABLED]); + + return 0; + } From 55521df200092945d93b231690408faefa4da05a Mon Sep 17 00:00:00 2001 From: Qosmio Date: Tue, 27 Feb 2024 00:45:32 -0500 Subject: [PATCH 123/225] ath11k_nss: 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. --- ...03-mac80211-ath11k-fw-dynamic-muedca.patch | 162 ++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/203-mac80211-ath11k-fw-dynamic-muedca.patch 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 00000000000000..a91d4aa97cbbca --- /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 From 64ceafc6d5210af6b3025fe0adcfe77b801c1d72 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Tue, 27 Feb 2024 00:46:09 -0500 Subject: [PATCH 124/225] ath11k_nss: refresh patches --- .../068-ath11k-add-rx-histogram-stats.patch | 10 ++-- ...080-ath11k-ethernet-rx-decap-offload.patch | 6 +-- ...dma-counter-always-zero-in-peer-stat.patch | 6 +-- ...dma-counter-increamenting-improperly.patch | 6 +-- ...ul-ofdma-ru-allocation-in-peer-stats.patch | 14 +++--- .../113-ath11k-add-8023-undecap-support.patch | 4 +- ...-adding-support-for-mgmt-frame-stats.patch | 20 ++++---- .../188-ath11k-m3-ssr-dump-collection.patch | 2 +- ...91-ath11k-add-mgmt-and-data-ack-rssi.patch | 2 +- ...-ath11k_nss-add-nss-driver-interface.patch | 6 +-- .../199-003-ath11k-add-nss-support.patch | 40 ++++++++-------- ...-ath11k-Add-support-for-dynamic-vlan.patch | 4 +- ...207-ath11k-Enable-256_512MB-profiles.patch | 4 +- ...load-changes-to-NSS-driver-interface.patch | 22 ++++----- ...-support-on-NSS-offload-for-STA-mode.patch | 22 ++++----- ...14-ath11k-qos-null-frame-tx-over-wmi.patch | 46 +++++++++--------- ...pport-for-WDS-offload-in-NSS-offload.patch | 34 ++++++------- ...dev-in-NSS-for-dynamic-VLAN-handling.patch | 12 ++--- ...-dynamic-VLAN-support-in-NSS-offload.patch | 48 +++++++++---------- ...ow-fast-rx-by-bypassing-stats-update.patch | 7 ++- ...ow-fast-rx-by-bypassing-stats-update.patch | 26 +++++----- .../nss/ath11k/244-ath11k-dp-tx-perf.patch | 12 ++--- .../patches/nss/ath11k/270-iphone-issue.patch | 2 +- .../300-ath11k-nss-mesh-offload-support.patch | 18 +++---- .../301-ath11k-nss-mcbc-exception.patch | 32 ++++++------- ...lookup-failure-in-mgmt-tx-completion.patch | 12 ++--- ...e-free-of-peer-rx_tid-during-reo-cmd.patch | 2 +- ...30-ath11k-sync-wds_ast_entry-updates.patch | 10 ++-- ...TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch | 2 +- ...ing-rx-stats-with-monitor-vif-enable.patch | 8 ++-- ...1k-skip-status-ring-entry-processing.patch | 8 ++-- ...rt-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch | 2 +- ...356-ath11k-invalid-desc-sanity-check.patch | 4 +- ...-fix-clear-peer-keys-during-disassoc.patch | 4 +- ...-fix-tkip-encryption-traffic-failure.patch | 2 +- ...ct-ast-index-assignment-for-wds-peer.patch | 12 ++--- ...Fix-ppdu_id-from-firmware-PPDU-stats.patch | 8 ++-- ...Add-retry-mechanism-for-update_rx_qu.patch | 30 ++++++------ ...treaming-not-working-for-wan-to-wlan.patch | 9 +--- ...-event-handler-support-for-link-desc.patch | 8 ++-- ...th11k-Advertise-TX_QUEUE-mac-hw-flag.patch | 7 +-- ...oid-memset-of-ppdu-info-for-next-skb.patch | 12 ++--- ...support-to-send-the-QoS-Null-Data-fr.patch | 2 +- ...11k-remove-invalid-peer-create-logic.patch | 4 +- ...th11k-rename-ath11k_start_vdev_delay.patch | 4 +- ...ation-of-ath11k_mac_start_vdev_delay.patch | 6 +-- ...ailure-due-to-unexpected-peer-delete.patch | 20 ++++---- ...k-make-debugfs-sta-htt-stats-modular.patch | 8 ++-- .../subsys/007-fix_compilation_issue.patch | 20 ++++---- ...-when-using-encapsulation-offloading.patch | 2 +- .../199-001-mac80211-add-nss-support.patch | 38 +++++++-------- ...t-callback-when-hwencap-enable-in-st.patch | 2 +- ...03-mac80211-ath11k-fw-dynamic-muedca.patch | 20 ++++---- ...-ath11k-Add-support-for-dynamic-vlan.patch | 4 +- ...07-mac80211-add-nss-redirect-support.patch | 10 ++-- ...N-iftype-support-on-NSS-offload-case.patch | 12 ++--- ...-dynamic-VLAN-support-on-NSS-offload.patch | 6 +-- .../nss/subsys/245-compilation_fix.patch | 10 ++-- .../300-ath11k-nss-mesh-offload-support.patch | 40 ++++++++-------- ...TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch | 6 +-- ...-0005-mac80211-simple-tx-for-AP-mode.patch | 4 +- .../336-mac80211-Mesh-Fast-rx-support.patch | 10 ++-- ...mac80211-fix-unconditional-sta-usage.patch | 4 +- .../345-mac80211-fix-mixed-declaration.patch | 9 +--- ...change-to-40Mhz-during-channel-switc.patch | 7 +-- ...unused-RX_FLAGS-from-mac80211_rx_fla.patch | 6 +-- ...ncapsulation-of-EAPOL-frames-if-OFFL.patch | 30 ++++++------ ...fix-RCU-stall-in-mesh-fast-xmit-path.patch | 6 +-- ...-the-frame-to-driver-tx-ops-directly.patch | 4 +- ...se-HW-checksum-offload-only-for-ethm.patch | 16 +++---- ...1-Add-mac-hw-flag-to-avoid-queue-skb.patch | 38 +++++++-------- .../829-mac80211-fix-mesh-ping-issue.patch | 8 ++-- ...x-memory-corruption-during-mesh-beac.patch | 6 +-- 73 files changed, 443 insertions(+), 464 deletions(-) diff --git a/package/kernel/mac80211/patches/nss/ath11k/068-ath11k-add-rx-histogram-stats.patch b/package/kernel/mac80211/patches/nss/ath11k/068-ath11k-add-rx-histogram-stats.patch index c4b6d2339deea1..e4ac1ee17b0b2e 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/068-ath11k-add-rx-histogram-stats.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/068-ath11k-add-rx-histogram-stats.patch @@ -269,7 +269,7 @@ Signed-off-by: Manikanta Pubbisetty &fops_htt_peer_stats); --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -2756,10 +2756,43 @@ exit: +@@ -2762,10 +2762,43 @@ exit: return total_msdu_reaped; } @@ -313,7 +313,7 @@ Signed-off-by: Manikanta Pubbisetty u32 num_msdu; int i; -@@ -2769,6 +2802,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); @@ -322,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; -@@ -2785,18 +2820,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; } @@ -341,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; -@@ -2825,8 +2848,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; @@ -350,7 +350,7 @@ Signed-off-by: Manikanta Pubbisetty BUILD_BUG_ON(ARRAY_SIZE(arsta->chain_signal) > ARRAY_SIZE(ppdu_info->rssi_chain_pri20)); -@@ -2835,6 +2856,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; 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 index d5e6ec621fcbb3..3334ef52f8ec78 100644 --- 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 @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c -@@ -26,10 +26,10 @@ module_param_named(crypto_mode, ath11k_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 */ @@ -11,5 +11,5 @@ - "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)"); + "Datapath frame mode (0: raw, 1: native wifi, 2: ethernet(default))"); - struct ath11k_base *ath11k_soc[MAX_SOCS]; - + 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 index 6a96689002eedb..b46a32c09210ea 100644 --- 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 @@ -31,7 +31,7 @@ Signed-off-by: Miles Hu 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 -@@ -1480,6 +1480,7 @@ ath11k_hal_rx_parse_mon_status_tlv(struc +@@ -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; @@ -39,7 +39,7 @@ Signed-off-by: Miles Hu /* TODO: Please note that the combined rssi will not be accurate * in MU case. Rssi in MU needs to be retrieved from -@@ -1489,6 +1490,22 @@ ath11k_hal_rx_parse_mon_status_tlv(struc +@@ -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)); @@ -64,7 +64,7 @@ Signed-off-by: Miles Hu ppdu_info->rssi_chain_pri20[i] = --- a/drivers/net/wireless/ath/ath11k/hal_rx.h +++ b/drivers/net/wireless/ath/ath11k/hal_rx.h -@@ -408,6 +408,15 @@ struct hal_rx_he_sig_b2_ofdma_info { +@@ -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) diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 1365bff54c1bbe..52e2509b796c3d 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -5376,8 +5376,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/nss/ath11k/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 index c9dc6912d0d185..18477cd5234f1b 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -15,7 +15,7 @@ --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -2893,11 +2893,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; -@@ -2919,10 +2920,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; -@@ -2980,7 +2984,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)); -@@ -2998,10 +3001,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 && -@@ -3034,7 +3037,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 @@ } -@@ -5372,6 +5488,55 @@ static void ath11k_dp_rx_mon_dest_proces +@@ -5380,6 +5496,55 @@ static void ath11k_dp_rx_mon_dest_proces } } @@ -247,7 +247,7 @@ int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id, struct napi_struct *napi, int budget) { -@@ -5445,8 +5610,13 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -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)) { diff --git a/package/kernel/mac80211/patches/nss/ath11k/113-ath11k-add-8023-undecap-support.patch b/package/kernel/mac80211/patches/nss/ath11k/113-ath11k-add-8023-undecap-support.patch index 0dfdd6a297a7a1..2ba2411c3ef54b 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -2297,6 +2297,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, -@@ -2338,7 +2374,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/nss/ath11k/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 index 9b74a712452d8b..c069cc8ff9f58a 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -312,6 +312,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; -@@ -370,6 +380,8 @@ struct ath11k_vif { +@@ -372,6 +382,8 @@ struct ath11k_vif { #ifdef CPTCFG_ATH11K_DEBUGFS struct dentry *debugfs_twt; #endif /* CPTCFG_ATH11K_DEBUGFS */ @@ -128,7 +128,7 @@ debugfs_create_file("dfs_simulate_radar", 0200, --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6151,9 +6151,9 @@ static int ath11k_mac_mgmt_tx(struct ath +@@ -6148,9 +6148,9 @@ static int ath11k_mac_mgmt_tx(struct ath */ if (is_prb_rsp && atomic_read(&ar->num_pending_mgmt_tx) > ATH11K_PRB_RSP_DROP_THRESHOLD) { @@ -140,7 +140,7 @@ } if (skb_queue_len_lockless(q) >= ATH11K_TX_MGMT_NUM_PENDING_MAX) { -@@ -6179,9 +6179,11 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6176,9 +6176,11 @@ static void ath11k_mac_op_tx(struct ieee struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_key_conf *key = info->control.hw_key; @@ -152,7 +152,7 @@ int ret; memset(skb_cb, 0, sizeof(*skb_cb)); -@@ -6195,12 +6197,21 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6192,12 +6194,21 @@ static void ath11k_mac_op_tx(struct ieee if (info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { skb_cb->flags |= ATH11K_SKB_HW_80211_ENCAP; } else if (ieee80211_is_mgmt(hdr->frame_control)) { @@ -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; @@ -198,7 +198,7 @@ int peer_id; --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -5825,6 +5825,12 @@ static int wmi_process_mgmt_tx_comp(stru +@@ -5823,6 +5823,12 @@ static int wmi_process_mgmt_tx_comp(stru struct sk_buff *msdu; struct ieee80211_tx_info *info; struct ath11k_skb_cb *skb_cb; @@ -211,7 +211,7 @@ int num_mgmt; spin_lock_bh(&ar->txmgmt_idr_lock); -@@ -5852,6 +5858,31 @@ static int wmi_process_mgmt_tx_comp(stru +@@ -5850,6 +5856,31 @@ static int wmi_process_mgmt_tx_comp(stru info->status.ack_signal = tx_compl_param->ack_rssi; } @@ -243,7 +243,7 @@ ieee80211_tx_status_irqsafe(ar->hw, msdu); num_mgmt = atomic_dec_if_positive(&ar->num_pending_mgmt_tx); -@@ -7521,6 +7552,11 @@ static void ath11k_mgmt_rx_event(struct +@@ -7519,6 +7550,11 @@ static void ath11k_mgmt_rx_event(struct struct ieee80211_hdr *hdr; u16 fc; struct ieee80211_supported_band *sband; @@ -255,7 +255,7 @@ if (ath11k_pull_mgmt_rx_params_tlv(ab, skb, &rx_ev) != 0) { ath11k_warn(ab, "failed to extract mgmt rx event"); -@@ -7586,7 +7622,34 @@ static void ath11k_mgmt_rx_event(struct +@@ -7584,7 +7620,34 @@ static void ath11k_mgmt_rx_event(struct hdr = (struct ieee80211_hdr *)skb->data; fc = le16_to_cpu(hdr->frame_control); diff --git a/package/kernel/mac80211/patches/nss/ath11k/188-ath11k-m3-ssr-dump-collection.patch b/package/kernel/mac80211/patches/nss/ath11k/188-ath11k-m3-ssr-dump-collection.patch index 47b29fd19e19bb..1fe5317105c137 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/188-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/nss/ath11k/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 index 55701c68d08760..22cdb4dccb4d5d 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 +@@ -9579,6 +9579,8 @@ static int __ath11k_mac_register(struct wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index c39580e79e1a43..851e4ed0225a95 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -2803,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, @@ -2845,7 +2845,7 @@ Signed-off-by: Sriram R enum hal_pn_type pn_type) --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -1166,6 +1166,44 @@ int ath11k_wmi_send_pdev_set_regdomain(s +@@ -1164,6 +1164,44 @@ int ath11k_wmi_send_pdev_set_regdomain(s return ret; } @@ -2995,7 +2995,7 @@ Signed-off-by: Sriram R int ath11k_dp_pdev_reo_setup(struct ath11k_base *ab); --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6370,6 +6370,16 @@ static int ath11k_mac_op_start(struct ie +@@ -6367,6 +6367,16 @@ static int ath11k_mac_op_start(struct ie goto err; } diff --git a/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch b/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch index 2f043fd65c86b9..2234cb6bc4cc1d 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch @@ -357,7 +357,7 @@ Signed-off-by: Sriram R if (ar->ab->hw_params.rxdma1_enable) { rx_ring = &dp->rxdma_mon_buf_ring; -@@ -2029,7 +2032,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; } @@ -366,7 +366,7 @@ Signed-off-by: Sriram R enum hal_encrypt_type enctype) { switch (enctype) { -@@ -2056,7 +2059,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; } @@ -375,7 +375,7 @@ Signed-off-by: Sriram R enum hal_encrypt_type enctype) { switch (enctype) { -@@ -2084,7 +2087,7 @@ static int ath11k_dp_rx_crypto_param_len +@@ -2090,7 +2093,7 @@ static int ath11k_dp_rx_crypto_param_len return 0; } @@ -384,7 +384,7 @@ Signed-off-by: Sriram R enum hal_encrypt_type enctype) { switch (enctype) { -@@ -2820,6 +2823,22 @@ static void ath11k_dp_rx_process_receive +@@ -2826,6 +2829,22 @@ static void ath11k_dp_rx_process_receive } } @@ -407,7 +407,7 @@ Signed-off-by: Sriram R int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id, struct napi_struct *napi, int budget) { -@@ -3127,6 +3146,13 @@ static void ath11k_dp_rx_update_user_sta +@@ -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; @@ -421,7 +421,7 @@ Signed-off-by: Sriram R if (!rx_stats) return; -@@ -3203,8 +3229,10 @@ static void ath11k_dp_rx_update_peer_mu_ +@@ -3209,8 +3235,10 @@ static void ath11k_dp_rx_update_peer_mu_ { u32 num_users, i; @@ -433,7 +433,7 @@ Signed-off-by: Sriram R num_users = ppdu_info->num_users; if (num_users > HAL_MAX_UL_MU_USERS) -@@ -5607,7 +5635,7 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -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; @@ -442,7 +442,7 @@ Signed-off-by: Sriram R int num_buffs_reaped = 0; u32 rx_buf_sz; u16 log_type; -@@ -5675,6 +5703,7 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -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); @@ -623,7 +623,7 @@ Signed-off-by: Sriram R exit: mutex_unlock(&ar->conf_mutex); return ret; -@@ -6219,10 +6282,14 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6216,10 +6279,14 @@ static void ath11k_mac_op_tx(struct ieee if (control->sta) arsta = ath11k_sta_to_arsta(control->sta); @@ -639,7 +639,7 @@ Signed-off-by: Sriram R } } -@@ -6244,6 +6311,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; @@ -648,7 +648,7 @@ Signed-off-by: Sriram R if (ath11k_debugfs_rx_filter(ar)) tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar); } -@@ -6542,7 +6611,7 @@ static int ath11k_mac_setup_vdev_create_ +@@ -6539,7 +6608,7 @@ static int ath11k_mac_setup_vdev_create_ return 0; } @@ -657,7 +657,7 @@ Signed-off-by: Sriram R struct ieee80211_vif *vif) { struct ath11k *ar = hw->priv; -@@ -6588,6 +6657,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; } @@ -666,7 +666,7 @@ Signed-off-by: Sriram R } static bool ath11k_mac_vif_ap_active_any(struct ath11k_base *ab) -@@ -6718,6 +6789,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); @@ -675,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", -@@ -6858,7 +6931,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); @@ -711,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, -@@ -6982,6 +7082,7 @@ err_peer_del: +@@ -6979,6 +7079,7 @@ err_peer_del: } err_vdev_del: @@ -719,7 +719,7 @@ Signed-off-by: Sriram R ath11k_mac_vdev_delete(ar, arvif); spin_lock_bh(&ar->data_lock); list_del(&arvif->list); -@@ -7492,6 +7593,10 @@ ath11k_mac_update_vif_chan(struct ath11k +@@ -7489,6 +7590,10 @@ ath11k_mac_update_vif_chan(struct ath11k arvif->vdev_id, ret); continue; } @@ -730,7 +730,7 @@ Signed-off-by: Sriram R } /* Restart the internal monitor vdev on new channel */ -@@ -8720,6 +8825,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); @@ -739,7 +739,7 @@ Signed-off-by: Sriram R } #if IS_ENABLED(CONFIG_IPV6) -@@ -9139,6 +9246,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, @@ -747,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, -@@ -9524,7 +9632,8 @@ static int __ath11k_mac_register(struct +@@ -9529,7 +9637,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); @@ -757,7 +757,7 @@ Signed-off-by: Sriram R } ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; -@@ -9637,6 +9746,9 @@ static int __ath11k_mac_register(struct +@@ -9644,6 +9753,9 @@ static int __ath11k_mac_register(struct ab->hw_params.bios_sar_capa) ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa; diff --git a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Add-support-for-dynamic-vlan.patch b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Add-support-for-dynamic-vlan.patch index d90c39c77c9a4f..54a6d1528422db 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -117,6 +117,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 -@@ -9763,6 +9763,9 @@ static int __ath11k_mac_register(struct +@@ -9770,6 +9770,9 @@ static int __ath11k_mac_register(struct */ ar->hw->wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MONITOR); diff --git a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch index d18b213cf27607..d89b500015fc33 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch @@ -246,8 +246,8 @@ Signed-off-by: Ramya Gnanasekar { .hw_rev = ATH11K_HW_IPQ6018_HW10, @@ -177,7 +180,7 @@ static struct ath11k_hw_params ath11k_hw - .coldboot_cal_mm = true, - .coldboot_cal_ftm = true, + .coldboot_cal_mm = false, + .coldboot_cal_ftm = false, .cbcal_restart_fw = true, - .fw_mem_mode = 0, + .fw_mem_mode = ATH11K_QMI_TARGET_MEM_MODE, diff --git a/package/kernel/mac80211/patches/nss/ath11k/211-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 index 0d2de0ae895d6f..a470ba934507f1 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/211-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,7 +13,7 @@ Signed-off-by: Sathishkumar Muruganandam --- a/drivers/net/wireless/ath/ath11k/nss.c +++ b/drivers/net/wireless/ath/ath11k/nss.c -@@ -306,6 +306,22 @@ void ath11k_nss_wifili_event_receive(str +@@ -307,6 +307,22 @@ void ath11k_nss_wifili_event_receive(str case NSS_WIFILI_TID_REOQ_SETUP_MSG: /* TODO setup tidq */ break; @@ -36,7 +36,7 @@ Signed-off-by: Sathishkumar Muruganandam default: ath11k_dbg(ab, ATH11K_DBG_NSS, "unhandled event %d\n", msg_type); break; -@@ -416,13 +432,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) -@@ -546,11 +555,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; -@@ -590,28 +827,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; } -@@ -1320,7 +1545,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; -@@ -1334,9 +1559,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; } -@@ -1409,8 +1635,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; -@@ -1467,17 +1694,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; -@@ -1496,6 +1729,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) -@@ -1886,7 +2312,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; } -@@ -1940,7 +2366,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) { diff --git a/package/kernel/mac80211/patches/nss/ath11k/211-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 index 016ace4edd7501..8ad2cc71f8981d 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/211-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 @@ -34,7 +34,7 @@ Signed-off-by: Sathishkumar Muruganandam #endif struct ath11k_pdev_dp dp; u8 mac_addr[ETH_ALEN]; -@@ -1042,6 +1043,9 @@ struct ath11k_base { +@@ -1047,6 +1048,9 @@ struct ath11k_base { } testmode; #endif @@ -67,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 -@@ -1849,6 +1849,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; @@ -76,7 +76,7 @@ Signed-off-by: Sathishkumar Muruganandam ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "dp_htt rx msg type :0x%0x\n", type); -@@ -1884,15 +1886,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); @@ -776,7 +776,7 @@ Signed-off-by: Sathishkumar Muruganandam #endif /* _PEER_H_ */ --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -154,6 +154,8 @@ static const struct wmi_tlv_policy wmi_t +@@ -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) }, @@ -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) { -@@ -6362,6 +6409,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) { -@@ -7277,6 +7354,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: -@@ -8717,6 +8795,22 @@ static void ath11k_wmi_gtk_offload_statu +@@ -8797,6 +8875,22 @@ exit: kfree(tb); } @@ -905,7 +905,7 @@ 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; -@@ -8844,6 +8938,9 @@ static void ath11k_wmi_tlv_op_rx(struct +@@ -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; @@ -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 -@@ -3009,6 +3009,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; -@@ -4611,6 +4626,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 */ -@@ -6400,6 +6430,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/nss/ath11k/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 index 59816b1883be1d..5f31f4ded2358c 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -22,7 +22,7 @@ Signed-off-by: Sowmiya Sree Elavalagan --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6132,6 +6132,16 @@ static int ath11k_mac_mgmt_tx_wmi(struct +@@ -6129,6 +6129,16 @@ static int ath11k_mac_mgmt_tx_wmi(struct ATH11K_SKB_CB(skb)->paddr = paddr; @@ -39,7 +39,7 @@ Signed-off-by: Sowmiya Sree Elavalagan ret = ath11k_wmi_mgmt_send(ar, arvif->vdev_id, buf_id, skb); if (ret) { ath11k_warn(ar->ab, "failed to send mgmt frame: %d\n", ret); -@@ -6199,8 +6209,8 @@ static void ath11k_mgmt_over_wmi_tx_work +@@ -6196,8 +6206,8 @@ static void ath11k_mgmt_over_wmi_tx_work } } @@ -50,7 +50,7 @@ Signed-off-by: Sowmiya Sree Elavalagan { struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue; -@@ -6262,7 +6272,7 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6259,7 +6269,7 @@ static void ath11k_mac_op_tx(struct ieee } else if (ieee80211_is_mgmt(hdr->frame_control)) { frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, hdr->frame_control); is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control); @@ -59,7 +59,7 @@ Signed-off-by: Sowmiya Sree Elavalagan if (ret) { if (ret != -EBUSY) ath11k_warn(ar->ab, "failed to queue management frame %d\n", -@@ -6277,6 +6287,20 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6274,6 +6284,20 @@ static void ath11k_mac_op_tx(struct ieee spin_unlock_bh(&ar->data_lock); } return; @@ -91,7 +91,7 @@ Signed-off-by: Sowmiya Sree Elavalagan [WMI_TAG_SCAN_EVENT] = { .min_len = sizeof(struct wmi_scan_event) }, [WMI_TAG_PEER_STA_KICKOUT_EVENT] -@@ -699,6 +699,55 @@ int ath11k_wmi_mgmt_send(struct ath11k * +@@ -701,6 +701,55 @@ int ath11k_wmi_mgmt_send(struct ath11k * return ret; } @@ -147,7 +147,7 @@ Signed-off-by: Sowmiya Sree Elavalagan int ath11k_wmi_vdev_create(struct ath11k *ar, u8 *macaddr, struct vdev_create_params *param) { -@@ -5857,8 +5906,8 @@ static int ath11k_pull_mgmt_rx_params_tl +@@ -5905,8 +5954,8 @@ static int ath11k_pull_mgmt_rx_params_tl return 0; } @@ -158,7 +158,7 @@ Signed-off-by: Sowmiya Sree Elavalagan { struct sk_buff *msdu; struct ieee80211_tx_info *info; -@@ -5896,6 +5945,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; } @@ -170,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); -@@ -5914,10 +5968,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; @@ -188,7 +188,7 @@ Signed-off-by: Sowmiya Sree Elavalagan spin_unlock_bh(&ar->data_lock); skip_mgmt_stats: -@@ -5939,12 +5996,13 @@ skip_mgmt_stats: +@@ -5987,12 +6044,13 @@ skip_mgmt_stats: return 0; } @@ -206,7 +206,7 @@ Signed-off-by: Sowmiya Sree Elavalagan int ret; tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); -@@ -5954,7 +6012,7 @@ static int ath11k_pull_mgmt_tx_compl_par +@@ -6002,7 +6060,7 @@ static int ath11k_pull_mgmt_tx_compl_par return ret; } @@ -215,7 +215,7 @@ Signed-off-by: Sowmiya Sree Elavalagan if (!ev) { ath11k_warn(ab, "failed to fetch mgmt tx compl ev"); kfree(tb); -@@ -7731,10 +7789,11 @@ exit: +@@ -7810,10 +7868,11 @@ exit: static void ath11k_mgmt_tx_compl_event(struct ath11k_base *ab, struct sk_buff *skb) { @@ -229,7 +229,7 @@ Signed-off-by: Sowmiya Sree Elavalagan ath11k_warn(ab, "failed to extract mgmt tx compl event"); return; } -@@ -7747,7 +7806,7 @@ static void ath11k_mgmt_tx_compl_event(s +@@ -7826,7 +7885,7 @@ static void ath11k_mgmt_tx_compl_event(s goto exit; } @@ -238,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", -@@ -7758,6 +7817,36 @@ exit: +@@ -7837,6 +7896,36 @@ exit: rcu_read_unlock(); } @@ -275,9 +275,9 @@ 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) -@@ -8844,6 +8933,10 @@ 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); @@ -305,7 +305,7 @@ Signed-off-by: Sowmiya Sree Elavalagan WMI_TX_DELBA_COMPLETE_EVENTID = WMI_TLV_CMD(WMI_GRP_BA_NEG), WMI_TX_ADDBA_COMPLETE_EVENTID, WMI_BA_RSP_SSN_EVENTID, -@@ -1878,6 +1881,9 @@ enum wmi_tlv_tag { +@@ -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, @@ -315,7 +315,7 @@ Signed-off-by: Sowmiya Sree Elavalagan 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, @@ -333,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 @@ -341,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) @@ -354,7 +354,7 @@ Signed-off-by: Sowmiya Sree Elavalagan u32 tlv_header; u32 tx_params_dword0; u32 tx_params_dword1; -@@ -4917,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]; }; @@ -363,7 +363,7 @@ Signed-off-by: Sowmiya Sree Elavalagan u32 desc_id; u32 status; u32 pdev_id; -@@ -5748,6 +5766,17 @@ struct wmi_debug_log_config_cmd_fixed_pa +@@ -5790,6 +5808,17 @@ struct wmi_debug_log_config_cmd_fixed_pa u32 value; } __packed; @@ -381,7 +381,7 @@ Signed-off-by: Sowmiya Sree Elavalagan #define WMI_MAX_MEM_REQS 32 #define MAX_RADIOS 3 -@@ -6358,6 +6387,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/nss/ath11k/235-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 index 429b781199f132..729ee80199b9a2 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/235-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 @@ -43,7 +43,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 -@@ -4748,6 +4748,11 @@ static void ath11k_sta_rc_update_wk(stru +@@ -4744,6 +4744,11 @@ static void ath11k_sta_rc_update_wk(stru arvif = arsta->arvif; ar = arvif->ar; @@ -55,7 +55,7 @@ Signed-off-by: Sathishkumar Muruganandam if (WARN_ON(ath11k_mac_vif_chan(arvif->vif, &def))) return; -@@ -4919,17 +4924,28 @@ err_rc_bw_changed: +@@ -4915,17 +4920,28 @@ err_rc_bw_changed: static void ath11k_sta_set_4addr_wk(struct work_struct *wk) { struct ath11k *ar; @@ -86,7 +86,7 @@ Signed-off-by: Sathishkumar Muruganandam "setting USE_4ADDR for peer %pM\n", sta->addr); ret = ath11k_wmi_set_peer_param(ar, sta->addr, -@@ -4937,8 +4953,93 @@ static void ath11k_sta_set_4addr_wk(stru +@@ -4933,8 +4949,93 @@ static void ath11k_sta_set_4addr_wk(stru WMI_PEER_USE_4ADDR, 1); if (ret) @@ -181,7 +181,7 @@ Signed-off-by: Sathishkumar Muruganandam } static int ath11k_mac_inc_num_stations(struct ath11k_vif *arvif, -@@ -5268,9 +5369,32 @@ static void ath11k_mac_op_sta_set_4addr( +@@ -5264,9 +5365,32 @@ static void ath11k_mac_op_sta_set_4addr( struct ieee80211_sta *sta, bool enabled) { struct ath11k *ar = hw->priv; @@ -214,7 +214,7 @@ Signed-off-by: Sathishkumar Muruganandam ieee80211_queue_work(ar->hw, &arsta->set_4addr_wk); arsta->use_4addr_set = true; } -@@ -6654,6 +6778,9 @@ static int ath11k_mac_op_update_vif_offl +@@ -6646,6 +6770,9 @@ static int ath11k_mac_op_update_vif_offl u32 param_id, param_value; int ret; @@ -224,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 && -@@ -6874,7 +7001,8 @@ static int ath11k_mac_op_add_interface(s +@@ -6866,7 +6993,8 @@ static int ath11k_mac_op_add_interface(s goto err; } @@ -234,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; -@@ -6894,6 +7022,28 @@ static int ath11k_mac_op_add_interface(s +@@ -6886,6 +7014,28 @@ static int ath11k_mac_op_add_interface(s arvif->vif = vif; INIT_LIST_HEAD(&arvif->list); @@ -263,7 +263,7 @@ Signed-off-by: Sathishkumar Muruganandam INIT_DELAYED_WORK(&arvif->connection_loss_work, ath11k_mac_vif_sta_connection_loss_work); -@@ -6923,6 +7073,7 @@ static int ath11k_mac_op_add_interface(s +@@ -6915,6 +7065,7 @@ static int ath11k_mac_op_add_interface(s fallthrough; case NL80211_IFTYPE_AP: arvif->vdev_type = WMI_VDEV_TYPE_AP; @@ -271,7 +271,7 @@ Signed-off-by: Sathishkumar Muruganandam break; case NL80211_IFTYPE_MONITOR: arvif->vdev_type = WMI_VDEV_TYPE_MONITOR; -@@ -7145,13 +7296,30 @@ static void ath11k_mac_op_remove_interfa +@@ -7137,13 +7288,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; @@ -304,7 +304,7 @@ Signed-off-by: Sathishkumar Muruganandam ath11k_dbg(ab, ATH11K_DBG_MAC, "remove interface (vdev %d)\n", arvif->vdev_id); -@@ -7168,6 +7336,14 @@ static void ath11k_mac_op_remove_interfa +@@ -7160,6 +7328,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); @@ -319,7 +319,7 @@ Signed-off-by: Sathishkumar Muruganandam } ret = ath11k_mac_vdev_delete(ar, arvif); -@@ -7211,8 +7387,7 @@ err_vdev_del: +@@ -7203,8 +7379,7 @@ err_vdev_del: ath11k_debugfs_remove_interface(arvif); @@ -329,7 +329,7 @@ Signed-off-by: Sathishkumar Muruganandam mutex_unlock(&ar->conf_mutex); } -@@ -7272,16 +7447,17 @@ static int ath11k_mac_op_ampdu_action(st +@@ -7264,16 +7439,17 @@ static int ath11k_mac_op_ampdu_action(st struct ieee80211_ampdu_params *params) { struct ath11k *ar = hw->priv; @@ -349,7 +349,7 @@ Signed-off-by: Sathishkumar Muruganandam break; case IEEE80211_AMPDU_TX_START: case IEEE80211_AMPDU_TX_STOP_CONT: -@@ -8804,6 +8980,7 @@ static void ath11k_mac_op_sta_statistics +@@ -8796,6 +8972,7 @@ static void ath11k_mac_op_sta_statistics { struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); struct ath11k *ar = arsta->arvif->ar; @@ -357,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); -@@ -8860,7 +9037,8 @@ static void ath11k_mac_op_sta_statistics +@@ -8852,7 +9029,8 @@ static void ath11k_mac_op_sta_statistics ATH11K_DEFAULT_NOISE_FLOOR; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); @@ -369,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 -@@ -5070,6 +5070,8 @@ enum wmi_vdev_subtype { +@@ -5082,6 +5082,8 @@ enum wmi_vdev_subtype { WMI_VDEV_SUBTYPE_MESH_11S, }; @@ -380,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 -@@ -1156,12 +1156,13 @@ err_mem_free: +@@ -1121,12 +1121,13 @@ err_mem_free: return ret; } @@ -396,7 +396,7 @@ Signed-off-by: Sathishkumar Muruganandam int ret; ret = ath11k_peer_rx_tid_setup(ar, params->sta->addr, vdev_id, -@@ -1173,13 +1174,13 @@ int ath11k_dp_rx_ampdu_start(struct ath1 +@@ -1138,13 +1139,13 @@ int ath11k_dp_rx_ampdu_start(struct ath1 return ret; } diff --git a/package/kernel/mac80211/patches/nss/ath11k/236-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 index bad782747c57a1..cb1e39f149e409 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/236-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 -@@ -1526,14 +1526,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, -@@ -1561,7 +1558,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); -@@ -1570,14 +1568,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"); -@@ -1586,8 +1589,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; } -@@ -1616,7 +1619,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; -@@ -1729,6 +1732,86 @@ free: +@@ -1730,6 +1733,86 @@ free: return ret; } diff --git a/package/kernel/mac80211/patches/nss/ath11k/236-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 index 3687af833b5082..80b8a5fc67d7ea 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/236-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 -@@ -97,6 +97,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 : -@@ -324,6 +329,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,7 +69,7 @@ Signed-off-by: Sathishkumar Muruganandam struct ath11k_vif { u32 vdev_id; enum wmi_vdev_type vdev_type; -@@ -388,6 +407,11 @@ struct ath11k_vif { +@@ -390,6 +409,11 @@ struct ath11k_vif { struct arvif_nss nss; #endif struct list_head ap_vlan_arvifs; @@ -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 -@@ -346,6 +346,10 @@ enum nl80211_he_gi ath11k_mac_he_gi_to_n +@@ -351,6 +351,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; -@@ -718,6 +722,33 @@ u8 ath11k_mac_get_target_pdev_id(struct +@@ -723,6 +727,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; -@@ -4167,6 +4198,9 @@ static int ath11k_install_key(struct ath +@@ -4172,6 +4203,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; -@@ -4256,15 +4290,40 @@ static int ath11k_clear_peer_keys(struct +@@ -4261,15 +4295,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; -@@ -4282,17 +4341,38 @@ static int ath11k_mac_op_set_key(struct +@@ -4287,17 +4346,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. */ -@@ -4337,6 +4417,74 @@ static int ath11k_mac_op_set_key(struct +@@ -4342,6 +4422,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); -@@ -4359,6 +4507,27 @@ static int ath11k_mac_op_set_key(struct +@@ -4364,6 +4512,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) { -@@ -4368,18 +4537,23 @@ static int ath11k_mac_op_set_key(struct +@@ -4373,18 +4542,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); } @@ -354,7 +354,7 @@ Signed-off-by: Sathishkumar Muruganandam switch (key->cipher) { case WLAN_CIPHER_SUITE_TKIP: -@@ -5186,6 +5360,33 @@ static u32 ath11k_mac_ieee80211_sta_bw_t +@@ -5191,6 +5365,33 @@ static u32 ath11k_mac_ieee80211_sta_bw_t return bw; } @@ -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, -@@ -5295,6 +5496,34 @@ static int ath11k_mac_op_sta_state(struc +@@ -5300,6 +5501,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) { -@@ -7027,7 +7256,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7018,7 +7247,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; -@@ -7040,6 +7269,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7031,6 +7260,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; } -@@ -7064,6 +7294,20 @@ static int ath11k_mac_op_add_interface(s +@@ -7055,6 +7285,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: -@@ -7104,7 +7348,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7095,7 +7339,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++; -@@ -7263,7 +7507,7 @@ err_peer_del: +@@ -7254,7 +7498,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 } } -@@ -7274,6 +7518,8 @@ err_vdev_del: +@@ -7265,6 +7509,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); -@@ -7371,6 +7617,7 @@ err_vdev_del: +@@ -7362,6 +7608,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, -@@ -9959,8 +10206,11 @@ static int __ath11k_mac_register(struct +@@ -9960,8 +10207,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 -@@ -1939,6 +1939,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; @@ -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; -@@ -5774,6 +5775,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 index ee1e977310c046..bbf4f20ac2326c 100644 --- 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 @@ -1,8 +1,8 @@ --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -1048,6 +1049,7 @@ struct ath11k_base { - } testmode; - #endif +@@ -1076,6 +1076,7 @@ struct ath11k_base { + u32 max_ast_index; + u32 num_ast_entries; + bool stats_disable; /* must be last */ @@ -99,4 +99,3 @@ ret = 0; - diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 8034b6186ee671..61077309338ffb 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -55,7 +55,7 @@ Signed-off-by: P Praneesh tlv_tag, ptr - begin, len, tlv_len); return -EINVAL; } -@@ -2448,10 +2454,60 @@ ath11k_dp_rx_h_find_peer(struct ath11k_b +@@ -2454,10 +2460,60 @@ ath11k_dp_rx_h_find_peer(struct ath11k_b return peer; } @@ -117,7 +117,7 @@ Signed-off-by: P Praneesh { bool fill_crypto_hdr; enum hal_encrypt_type enctype; -@@ -2462,9 +2518,13 @@ 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; @@ -132,7 +132,7 @@ Signed-off-by: P Praneesh rxcb->is_mcbc = fill_crypto_hdr; if (rxcb->is_mcbc) { -@@ -2475,6 +2535,26 @@ static void ath11k_dp_rx_h_mpdu(struct a +@@ -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) { @@ -159,7 +159,7 @@ Signed-off-by: P Praneesh if (rxcb->is_mcbc) enctype = peer->sec_type_grp; else -@@ -2484,6 +2564,8 @@ static void ath11k_dp_rx_h_mpdu(struct a +@@ -2490,6 +2570,8 @@ static void ath11k_dp_rx_h_mpdu(struct a } spin_unlock_bh(&ar->ab->base_lock); @@ -168,7 +168,7 @@ Signed-off-by: P Praneesh 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) -@@ -2725,7 +2807,8 @@ static void ath11k_dp_rx_deliver_msdu(st +@@ -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, @@ -178,7 +178,7 @@ Signed-off-by: P Praneesh { struct ath11k_base *ab = ar->ab; struct hal_rx_desc *rx_desc, *lrx_desc; -@@ -2792,8 +2875,13 @@ static int ath11k_dp_rx_process_msdu(str +@@ -2798,8 +2881,13 @@ static int ath11k_dp_rx_process_msdu(str } } @@ -193,7 +193,7 @@ Signed-off-by: P Praneesh rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; -@@ -2808,10 +2896,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) { @@ -206,7 +206,7 @@ Signed-off-by: P Praneesh if (skb_queue_empty(msdu_list)) return; -@@ -2828,7 +2918,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))) { @@ -220,7 +220,7 @@ Signed-off-by: P Praneesh if (unlikely(ret)) { ath11k_dbg(ab, ATH11K_DBG_DATA, "Unable to process msdu %d", ret); -@@ -2836,7 +2931,10 @@ static void ath11k_dp_rx_process_receive +@@ -2842,7 +2937,10 @@ static void ath11k_dp_rx_process_receive continue; } @@ -232,7 +232,7 @@ Signed-off-by: P Praneesh } } -@@ -2845,11 +2943,12 @@ void ath11k_dp_rx_from_nss(struct ath11k +@@ -2851,11 +2949,12 @@ void ath11k_dp_rx_from_nss(struct ath11k { struct ieee80211_rx_status rx_status = {0}; struct ath11k_skb_rxcb *rxcb; @@ -246,7 +246,7 @@ Signed-off-by: P Praneesh rx_status.flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; -@@ -4316,6 +4415,7 @@ static int ath11k_dp_rx_h_null_q_desc(st +@@ -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) { @@ -254,7 +254,7 @@ Signed-off-by: P Praneesh u16 msdu_len; struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; struct rx_attention *rx_attention; -@@ -4365,7 +4465,8 @@ static int ath11k_dp_rx_h_null_q_desc(st +@@ -4371,7 +4471,8 @@ static int ath11k_dp_rx_h_null_q_desc(st } ath11k_dp_rx_h_ppdu(ar, desc, status); @@ -328,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 -@@ -5536,6 +5536,14 @@ static int ath11k_mac_op_sta_state(struc +@@ -5532,6 +5532,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/nss/ath11k/244-ath11k-dp-tx-perf.patch b/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch index 3c4d324161644c..7535883c4763d0 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch @@ -430,7 +430,7 @@ Signed-off-by: P Praneesh --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6643,12 +6643,22 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6669,12 +6669,22 @@ static void ath11k_mac_op_tx(struct ieee if (control->sta) arsta = ath11k_sta_to_arsta(control->sta); @@ -454,7 +454,7 @@ Signed-off-by: P Praneesh ieee80211_free_txskb(ar->hw, skb); return; } -@@ -7596,7 +7606,7 @@ err_vdev_del: +@@ -7622,7 +7632,7 @@ err_vdev_del: idr_for_each(&ar->txmgmt_idr, ath11k_mac_vif_txmgmt_idr_remove, vif); @@ -490,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 -@@ -186,7 +186,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, @@ -498,7 +498,7 @@ Signed-off-by: P Praneesh .hal_params = &ath11k_hw_hal_params_ipq8074, .supports_dynamic_smps_6ghz = false, .alloc_cacheable_memory = true, -@@ -212,6 +211,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, @@ -507,7 +507,7 @@ Signed-off-by: P Praneesh }, { .name = "qca6390 hw2.0", -@@ -381,6 +382,8 @@ static struct ath11k_hw_params ath11k_hw +@@ -380,6 +381,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, @@ -516,7 +516,7 @@ Signed-off-by: P Praneesh }, { .name = "wcn6855 hw2.0", -@@ -2146,6 +2149,9 @@ int ath11k_core_pre_init(struct ath11k_b +@@ -2143,6 +2146,9 @@ int ath11k_core_pre_init(struct ath11k_b if (nss_offload) ab->nss.stats_enabled = 1; diff --git a/package/kernel/mac80211/patches/nss/ath11k/270-iphone-issue.patch b/package/kernel/mac80211/patches/nss/ath11k/270-iphone-issue.patch index 5890fa6a784a08..4260d0e5337451 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/270-iphone-issue.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/270-iphone-issue.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -5898,6 +5898,8 @@ static int ath11k_mac_copy_he_cap(struct +@@ -6267,6 +6267,8 @@ static int ath11k_mac_copy_he_cap(struct memcpy(he_cap_elem->phy_cap_info, band_cap->he_cap_phy_info, sizeof(he_cap_elem->phy_cap_info)); 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 index f11c9d28710d53..b31809f689548b 100644 --- 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 @@ -1046,7 +1046,7 @@ Signed-off-by: Vasanthakumar Thiagarajan #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 -@@ -1403,6 +1403,71 @@ static int ath11k_htt_tlv_ppdu_stats_par +@@ -1409,6 +1409,71 @@ static int ath11k_htt_tlv_ppdu_stats_par return 0; } @@ -1118,7 +1118,7 @@ Signed-off-by: Vasanthakumar Thiagarajan static void ath11k_update_per_peer_tx_stats(struct ath11k *ar, struct htt_ppdu_stats *ppdu_stats, u8 user) -@@ -1426,6 +1491,9 @@ ath11k_update_per_peer_tx_stats(struct a +@@ -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; @@ -1128,7 +1128,7 @@ Signed-off-by: Vasanthakumar Thiagarajan 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); -@@ -1559,6 +1627,8 @@ ath11k_update_per_peer_tx_stats(struct a +@@ -1565,6 +1633,8 @@ ath11k_update_per_peer_tx_stats(struct a ath11k_debugfs_sta_add_tx_stats(arsta, peer_stats, rate_idx); } @@ -1137,7 +1137,7 @@ Signed-off-by: Vasanthakumar Thiagarajan spin_unlock_bh(&ab->base_lock); rcu_read_unlock(); } -@@ -1679,6 +1749,69 @@ int ath11k_dp_htt_tlv_iter(struct ath11k +@@ -1685,6 +1755,69 @@ int ath11k_dp_htt_tlv_iter(struct ath11k return 0; } @@ -1207,7 +1207,7 @@ Signed-off-by: Vasanthakumar Thiagarajan static int ath11k_htt_pull_ppdu_stats(struct ath11k_base *ab, struct sk_buff *skb) { -@@ -1697,6 +1830,15 @@ static int ath11k_htt_pull_ppdu_stats(st +@@ -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; @@ -1223,7 +1223,7 @@ Signed-off-by: Vasanthakumar Thiagarajan rcu_read_lock(); ar = ath11k_mac_get_ar_by_pdev_id(ab, pdev_id); if (!ar) { -@@ -1764,6 +1906,12 @@ static int ath11k_htt_pull_ppdu_stats(st +@@ -1770,6 +1912,12 @@ static int ath11k_htt_pull_ppdu_stats(st } } @@ -1257,7 +1257,7 @@ Signed-off-by: Vasanthakumar Thiagarajan mutex_unlock(&ar->conf_mutex); } -@@ -9700,6 +9712,28 @@ err_fallback: +@@ -9714,6 +9726,28 @@ err_fallback: return 0; } @@ -1286,7 +1286,7 @@ Signed-off-by: Vasanthakumar Thiagarajan static const struct ieee80211_ops ath11k_ops = { .tx = ath11k_mac_op_tx, .wake_tx_queue = ieee80211_handle_wake_tx_queue, -@@ -9757,6 +9791,9 @@ static const struct ieee80211_ops ath11k +@@ -9771,6 +9805,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, @@ -1296,7 +1296,7 @@ Signed-off-by: Vasanthakumar Thiagarajan }; static void ath11k_mac_update_ch_list(struct ath11k *ar, -@@ -10215,6 +10252,8 @@ static int __ath11k_mac_register(struct +@@ -10231,6 +10268,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); diff --git a/package/kernel/mac80211/patches/nss/ath11k/301-ath11k-nss-mcbc-exception.patch b/package/kernel/mac80211/patches/nss/ath11k/301-ath11k-nss-mcbc-exception.patch index 6f4793b5a0afd5..2fa70d0f395ab3 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -568,7 +568,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; -@@ -604,8 +604,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); -@@ -649,8 +647,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; -@@ -672,7 +669,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,8 +53,8 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 break; case NSS_WIFI_VDEV_WDS_TYPE_MEC: ath11k_nss_mec_handler(ar, (u8 *)(skb->data)); -@@ -739,10 +736,12 @@ ath11k_nss_vdev_special_data_receive(str - struct ieee80211_vif *vif; +@@ -775,10 +772,12 @@ ath11k_nss_vdev_special_data_receive(str + struct nss_wifi_vdev_wds_per_packet_metadata *wds_metadata = NULL; struct ath11k_vif *arvif; struct ath11k_base *ab; - bool drop = false; @@ -65,9 +65,9 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 + struct ath11k_skb_rxcb *rxcb; + struct ath11k_peer *ta_peer = NULL; - if (!dev) { - dev_kfree_skb_any(skb); -@@ -791,15 +790,50 @@ ath11k_nss_vdev_special_data_receive(str + arvif = ath11k_nss_get_arvif_from_dev(dev); + if (!arvif) { +@@ -810,15 +809,50 @@ ath11k_nss_vdev_special_data_receive(str return; } @@ -126,7 +126,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 } static void -@@ -1006,6 +1040,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; @@ -136,7 +136,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 default: return -EINVAL; } -@@ -1247,12 +1284,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) { @@ -167,9 +167,9 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 + goto unregister_vdev; + } break; - default: - ret = -ENOTSUPP; -@@ -1526,7 +1582,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; @@ -177,7 +177,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 u32 features = 0; if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN || arvif->nss.ctx) -@@ -1540,7 +1595,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", @@ -188,7 +188,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 --- a/drivers/net/wireless/ath/ath11k/nss.h +++ b/drivers/net/wireless/ath/ath11k/nss.h -@@ -109,8 +109,12 @@ 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, 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 index ed3cde7c8e00ec..cb4fba0a2ffdcd 100644 --- 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 @@ -23,7 +23,7 @@ Signed-off-by: Rameshkumar Sundaram --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -7640,8 +7640,10 @@ err_vdev_del: +@@ -7643,8 +7643,10 @@ err_vdev_del: kfree(arvif->vlan_keyid_map); ath11k_peer_cleanup(ar, arvif->vdev_id); @@ -36,7 +36,7 @@ Signed-off-by: Rameshkumar Sundaram 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 -@@ -6125,13 +6125,13 @@ static int wmi_process_tx_comp(struct at +@@ -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; @@ -51,7 +51,7 @@ Signed-off-by: Rameshkumar Sundaram spin_lock_bh(&ar->txmgmt_idr_lock); msdu = idr_find(&ar->txmgmt_idr, tx_compl_param->desc_id); -@@ -6139,6 +6139,7 @@ static int wmi_process_tx_comp(struct at +@@ -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); @@ -59,7 +59,7 @@ Signed-off-by: Rameshkumar Sundaram return -ENOENT; } -@@ -6147,6 +6148,28 @@ static int wmi_process_tx_comp(struct at +@@ -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); @@ -87,8 +87,8 @@ Signed-off-by: Rameshkumar Sundaram + spin_unlock_bh(&ar->data_lock); info = IEEE80211_SKB_CB(msdu); - if ((!(info->flags & IEEE80211_TX_CTL_NO_ACK)) && !tx_compl_param->status) -@@ -6161,34 +6184,6 @@ static int wmi_process_tx_comp(struct at + 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; diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 6bf1ba225e0bd5..d733219b38aa7f 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -1440,6 +1440,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/nss/ath11k/330-ath11k-sync-wds_ast_entry-updates.patch b/package/kernel/mac80211/patches/nss/ath11k/330-ath11k-sync-wds_ast_entry-updates.patch index 98fb7325850498..662e11697f4d9c 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -2235,6 +2235,7 @@ struct ath11k_base *ath11k_core_alloc(st +@@ -2212,6 +2212,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); -@@ -2248,6 +2249,8 @@ struct ath11k_base *ath11k_core_alloc(st +@@ -2225,6 +2226,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); @@ -159,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 -@@ -288,8 +288,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); @@ -170,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, -@@ -409,8 +409,8 @@ static inline int ath11k_nss_map_wds_pee +@@ -413,8 +413,8 @@ static inline int ath11k_nss_map_wds_pee return 0; } @@ -183,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); diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 3b118c3fb5093c..3c3e436c75ce41 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -58,7 +58,7 @@ Signed-off-by: Venkateswara Naralasetty 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 -@@ -10114,6 +10114,8 @@ static int __ath11k_mac_register(struct +@@ -10154,6 +10154,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 index 8cd0b134bdf77e..752218e9b8ec26 100644 --- 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 @@ -16,7 +16,7 @@ Signed-off-by: Anilkumar Kolli --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -6197,12 +6197,23 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -5953,12 +5953,23 @@ int ath11k_dp_rx_process_mon_status(stru pmon->mon_ppdu_status = DP_PPDU_STATUS_START; } @@ -43,7 +43,7 @@ Signed-off-by: Anilkumar Kolli rcu_read_lock(); spin_lock_bh(&ab->base_lock); peer = ath11k_peer_find_by_id(ab, ppdu_info->peer_id); -@@ -6524,6 +6535,13 @@ static int ath11k_dp_full_mon_process_rx +@@ -6282,6 +6293,13 @@ static int ath11k_dp_full_mon_process_rx spin_lock_bh(&pmon->mon_lock); @@ -57,7 +57,7 @@ Signed-off-by: Anilkumar Kolli sw_mon_entries = &pmon->sw_mon_entries; rx_mon_stats = &pmon->rx_mon_stats; -@@ -6563,7 +6581,6 @@ static int ath11k_dp_full_mon_process_rx +@@ -6321,7 +6339,6 @@ static int ath11k_dp_full_mon_process_rx } rx_mon_stats->dest_ppdu_done++; @@ -65,7 +65,7 @@ Signed-off-by: Anilkumar Kolli pmon->buf_state = DP_MON_STATUS_LAG; pmon->mon_status_paddr = sw_mon_entries->mon_status_paddr; pmon->hold_mon_dst_ring = true; -@@ -6594,16 +6611,10 @@ reap_status_ring: +@@ -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) { diff --git a/package/kernel/mac80211/patches/nss/ath11k/336-ath11k-skip-status-ring-entry-processing.patch b/package/kernel/mac80211/patches/nss/ath11k/336-ath11k-skip-status-ring-entry-processing.patch index f03b4e2d7e5df6..0adf26c808aec6 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -3464,6 +3464,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) { -@@ -3477,6 +3517,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; -@@ -3496,8 +3537,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; -@@ -3528,18 +3568,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) { diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index af64057faf823f..dbd8dd904c022d 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -1839,6 +1839,11 @@ static int ath11k_core_reconfigure_on_cr +@@ -1838,6 +1838,11 @@ static int ath11k_core_reconfigure_on_cr clear_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags); diff --git a/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch b/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch index e1d407e57d2e6f..f574597dceb969 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch @@ -57,7 +57,7 @@ Signed-off-by: Nagarajan Maran spin_unlock_bh(&rx_ring->idr_lock); if (buf_id <= 0) goto fail_dma_unmap; -@@ -3134,6 +3134,16 @@ try_again: +@@ -3141,6 +3141,16 @@ try_again: while (likely(desc = (struct hal_reo_dest_ring *)ath11k_hal_srng_dst_get_next_entry(ab, srng))) { @@ -74,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, -@@ -3164,8 +3174,6 @@ try_again: +@@ -3171,8 +3181,6 @@ try_again: num_buffs_reaped[mac_id]++; diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 3c765c9c2df46e..15a8afde61ef4f 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -4882,12 +4882,6 @@ static int ath11k_station_disassoc(struc +@@ -4899,12 +4899,6 @@ static int ath11k_station_disassoc(struc return ret; } @@ -30,7 +30,7 @@ Signed-off-by: Karthikeyan Kathirvel return 0; } -@@ -5478,6 +5472,17 @@ static int ath11k_mac_op_sta_state(struc +@@ -5495,6 +5489,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/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch b/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch index ec9d831abded55..f57faaa465ae76 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch @@ -13,7 +13,7 @@ Signed-off-by: Ramya Gnanasekar --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -2515,7 +2515,8 @@ static void ath11k_dp_rx_h_undecap(struc +@@ -2564,7 +2564,8 @@ static void ath11k_dp_rx_h_undecap(struc ehdr = (struct ethhdr *)msdu->data; /* mac80211 allows fast path only for authorized STA */ diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index b4e399144ac1ae..3786bd3de9647d 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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,7 +19,7 @@ Signed-off-by: Raj Kumar Bhagat --- a/drivers/net/wireless/ath/ath11k/nss.c +++ b/drivers/net/wireless/ath/ath11k/nss.c -@@ -2410,13 +2410,14 @@ msg_free: +@@ -3871,13 +3871,14 @@ msg_free: } int ath11k_nss_map_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, @@ -35,7 +35,7 @@ Signed-off-by: Raj Kumar Bhagat int ret = 0; wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); -@@ -2426,7 +2427,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; @@ -46,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; @@ -54,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, @@ -63,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, @@ -75,7 +75,7 @@ Signed-off-by: Raj Kumar Bhagat } --- a/drivers/net/wireless/ath/ath11k/peer.c +++ b/drivers/net/wireless/ath/ath11k/peer.c -@@ -359,8 +359,7 @@ void ath11k_peer_map_ast(struct ath11k * +@@ -373,8 +373,7 @@ void ath11k_peer_map_ast(struct ath11k * if ((ast_entry->type == ATH11K_AST_TYPE_WDS) || (ast_entry->type == ATH11K_AST_TYPE_MEC)) 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 index fd4f0938cdb83b..f909ba4a673f69 100644 --- 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 @@ -14,7 +14,7 @@ Signed-off-by: Ramya Gnanasekar --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h -@@ -1501,6 +1501,7 @@ struct htt_ppdu_stats_usr_cmpltn_cmn { +@@ -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 @@ -24,7 +24,7 @@ Signed-off-by: Ramya Gnanasekar u32 ppdu_id; --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -1323,7 +1323,7 @@ static int ath11k_htt_tlv_ppdu_stats_par +@@ -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; @@ -33,7 +33,7 @@ Signed-off-by: Ramya Gnanasekar ppdu_info = data; -@@ -1404,6 +1404,8 @@ static int ath11k_htt_tlv_ppdu_stats_par +@@ -1369,6 +1369,8 @@ static int ath11k_htt_tlv_ppdu_stats_par return -EINVAL; } @@ -42,7 +42,7 @@ Signed-off-by: Ramya Gnanasekar 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, -@@ -1415,6 +1417,7 @@ static int ath11k_htt_tlv_ppdu_stats_par +@@ -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)); diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 832a7d92b35a0a..8adb5448a1564c 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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,9 +41,9 @@ Signed-off-by: Tamizh Chelvam Raja --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -1176,6 +1176,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 reo_error_drop[HAL_REO_DEST_RING_ERROR_CODE_MAX]; u32 hal_reo_error[DP_REO_DST_RING_MAX]; + u32 hal_reo_cmd_drain; + u32 reo_cmd_cache_error; @@ -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 -@@ -1416,6 +1416,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 -@@ -1185,8 +1185,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); @@ -95,7 +95,7 @@ Signed-off-by: Tamizh Chelvam Raja u32 ba_win_sz; bool active; -@@ -53,6 +54,14 @@ struct dp_reo_cache_flush_elem { +@@ -51,6 +52,14 @@ struct dp_reo_cache_flush_elem { unsigned long ts; }; @@ -110,7 +110,7 @@ Signed-off-by: Tamizh Chelvam Raja struct dp_reo_cmd { struct list_head list; struct dp_rx_tid data; -@@ -298,6 +307,12 @@ struct ath11k_dp { +@@ -295,6 +304,12 @@ struct ath11k_dp { * - reo_cmd_cache_flush_count */ spinlock_t reo_cmd_lock; @@ -122,10 +122,10 @@ Signed-off-by: Tamizh Chelvam Raja + spinlock_t reo_cmd_update_queue_lock; struct ath11k_hp_update_timer reo_cmd_timer; struct ath11k_hp_update_timer tx_ring_timer[DP_TCL_NUM_RING_MAX]; - + }; --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -22,6 +22,9 @@ +@@ -21,6 +21,9 @@ #define ATH11K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ) @@ -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) { -@@ -729,13 +732,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); -@@ -781,14 +821,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) { -@@ -799,11 +843,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); -@@ -811,24 +861,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? */ -@@ -837,6 +884,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; -@@ -854,13 +924,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); -@@ -876,34 +953,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/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch b/package/kernel/mac80211/patches/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch index 144d5a9ca4d36c..020df707b6e6a4 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch @@ -21,11 +21,9 @@ Signed-off-by: Aaradhana Sahu drivers/net/wireless/ath/ath11k/dp_tx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) -diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.c b/drivers/net/wireless/ath/ath11k/dp_tx.c -index 3d8417d..5c034e6 100644 --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -@@ -347,7 +347,8 @@ tcl_ring_sel: +@@ -221,7 +221,8 @@ tcl_ring_sel: switch (ti.encap_type) { case HAL_TCL_ENCAP_TYPE_NATIVE_WIFI: @@ -35,7 +33,7 @@ index 3d8417d..5c034e6 100644 is_diff_encap = true; else ath11k_dp_tx_encap_nwifi(skb); -@@ -375,7 +376,7 @@ tcl_ring_sel: +@@ -247,7 +248,7 @@ tcl_ring_sel: if ((!test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) && !(info->control.flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && !info->control.hw_key && ieee80211_has_protected(hdr->frame_control)) || @@ -44,6 +42,3 @@ index 3d8417d..5c034e6 100644 /* HW requirement is that metadata should always point to a * 8-byte aligned address. So we add alignment pad to start of * buffer. HTT Metadata should be ensured to be multiple of 8-bytes --- -2.17.1 - diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 6b4433aafa4f41..df9fb62bcd17b4 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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; -@@ -333,6 +370,10 @@ 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); +@@ -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/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 index 2b7d9c50c0c776..510fbc2448cee7 100644 --- 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 @@ -11,11 +11,9 @@ Signed-off-by: Yuvasree Sivasankaran drivers/net/wireless/ath/ath11k/mac.c | 1 + 1 file changed, 1 insertion(+) -diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c -index 3e79e07..32ff5c9 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -13034,6 +13034,7 @@ static int __ath11k_mac_register(struct ath11k *ar) +@@ -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); @@ -23,6 +21,3 @@ index 3e79e07..32ff5c9 100644 if (ath11k_frame_mode == ATH11K_HW_TXRX_ETHERNET) { ieee80211_hw_set(ar->hw, SUPPORTS_TX_ENCAP_OFFLOAD); --- -2.34.1 - diff --git a/package/kernel/mac80211/patches/nss/ath11k/457-wifi-ath11k-Avoid-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 index de7f697c7ccb7c..c23b6cb3c858b4 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/457-wifi-ath11k-Avoid-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 -@@ -6292,7 +6292,9 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -6090,7 +6090,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))) { -@@ -6310,7 +6312,6 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -6108,7 +6110,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,14 +67,14 @@ Signed-off-by: Yuvasree Sivasankaran ppdu_info->peer_id = HAL_INVALID_PEERID; hal_status = ath11k_hal_rx_parse_mon_status(ab, ppdu_info, skb); -@@ -6326,6 +6327,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) { +@@ -6136,6 +6137,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 @@ -221,6 +221,7 @@ struct hal_rx_mon_ppdu_info { diff --git a/package/kernel/mac80211/patches/nss/ath11k/458-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 index 04d842e96a107b..6399718268b0b1 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/458-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,7 +18,7 @@ Signed-off-by: Karthikeyan Periyasamy --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -@@ -217,7 +217,8 @@ tcl_ring_sel: +@@ -222,7 +222,8 @@ tcl_ring_sel: switch (ti.encap_type) { case HAL_TCL_ENCAP_TYPE_NATIVE_WIFI: if ((arvif->vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) && 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 index f5301ca9e4890f..b471fb326a5b48 100644 --- 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 @@ -26,7 +26,7 @@ Acked-by: Jeff Johnson --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -8232,7 +8232,6 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -8221,7 +8221,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; @@ -34,7 +34,7 @@ Acked-by: Jeff Johnson mutex_lock(&ar->conf_mutex); -@@ -8255,21 +8254,6 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -8244,21 +8243,6 @@ ath11k_mac_op_assign_vif_chanctx(struct goto out; } 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 index 2490a8139d452a..2fb2cdfd429b11 100644 --- 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 @@ -30,7 +30,7 @@ Acked-by: Jeff Johnson enum nl80211_he_ru_alloc ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc(u16 ru_phy) { -@@ -5323,7 +5323,7 @@ static int ath11k_mac_station_add(struct +@@ -5319,7 +5319,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) { @@ -39,7 +39,7 @@ Acked-by: Jeff Johnson if (ret) { ath11k_warn(ab, "failed to delay vdev start: %d\n", ret); goto free_tx_stats; -@@ -8175,8 +8175,8 @@ unlock: +@@ -8164,8 +8164,8 @@ unlock: mutex_unlock(&ar->conf_mutex); } 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 index 3b6e24ae508bbe..4d83d0f0ed9029 100644 --- 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 @@ -28,7 +28,7 @@ Acked-by: Jeff Johnson enum nl80211_he_ru_alloc ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc(u16 ru_phy) { enum nl80211_he_ru_alloc ret; -@@ -5253,100 +5250,6 @@ static void ath11k_mac_dec_num_stations( +@@ -5249,100 +5246,6 @@ static void ath11k_mac_dec_num_stations( ar->num_stations--; } @@ -129,7 +129,7 @@ Acked-by: Jeff Johnson static u32 ath11k_mac_ieee80211_sta_bw_to_wmi(struct ath11k *ar, struct ieee80211_sta *sta) { -@@ -5402,187 +5305,6 @@ static int ath11k_mac_cfg_dyn_vlan(struc +@@ -5398,187 +5301,6 @@ static int ath11k_mac_cfg_dyn_vlan(struc return ret; } @@ -317,7 +317,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) -@@ -9735,6 +9457,281 @@ ath11k_mac_op_config_mesh_offload_path(s +@@ -9739,6 +9461,281 @@ ath11k_mac_op_config_mesh_offload_path(s } #endif 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 index e8e663431217c5..d1b462519c91e8 100644 --- 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 @@ -52,7 +52,7 @@ Acked-by: Jeff Johnson --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -7937,6 +7937,30 @@ static int ath11k_mac_start_vdev_delay(s +@@ -7933,6 +7933,30 @@ static int ath11k_mac_start_vdev_delay(s return 0; } @@ -83,7 +83,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -@@ -7981,15 +8005,17 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -7977,15 +8001,17 @@ ath11k_mac_op_assign_vif_chanctx(struct goto out; } @@ -109,7 +109,7 @@ Acked-by: Jeff Johnson if (arvif->vdev_type != WMI_VDEV_TYPE_MONITOR && test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags)) { -@@ -8029,8 +8055,6 @@ ath11k_mac_op_unassign_vif_chanctx(struc +@@ -8025,8 +8051,6 @@ ath11k_mac_op_unassign_vif_chanctx(struc "chanctx unassign ptr %p vdev_id %i\n", ctx, arvif->vdev_id); @@ -118,7 +118,7 @@ Acked-by: Jeff Johnson if (ab->hw_params.vdev_start_delay && arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { spin_lock_bh(&ab->base_lock); -@@ -8054,24 +8078,13 @@ ath11k_mac_op_unassign_vif_chanctx(struc +@@ -8050,24 +8074,13 @@ ath11k_mac_op_unassign_vif_chanctx(struc return; } @@ -149,7 +149,7 @@ Acked-by: Jeff Johnson } if (ab->hw_params.vdev_start_delay && -@@ -9551,6 +9564,46 @@ exit: +@@ -9555,6 +9568,46 @@ exit: return ret; } @@ -196,7 +196,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, -@@ -9586,31 +9639,15 @@ static int ath11k_mac_op_sta_state(struc +@@ -9590,31 +9643,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)) { @@ -233,7 +233,7 @@ Acked-by: Jeff Johnson 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); -@@ -9621,12 +9658,6 @@ static int ath11k_mac_op_sta_state(struc +@@ -9625,12 +9662,6 @@ static int ath11k_mac_op_sta_state(struc } spin_unlock_bh(&ar->ab->base_lock); mutex_unlock(&ar->ab->tbl_mtx_lock); @@ -246,9 +246,9 @@ Acked-by: Jeff Johnson } else if (old_state == IEEE80211_STA_AUTH && new_state == IEEE80211_STA_ASSOC && (vif->type == NL80211_IFTYPE_AP || -@@ -10195,6 +10226,8 @@ static int __ath11k_mac_register(struct - wiphy_ext_feature_set(ar->hw->wiphy, - NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); +@@ -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); + 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 index 3bcf93279c5a2f..2362820dc9e838 100644 --- 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 @@ -40,7 +40,7 @@ ath11k-$(CPTCFG_ATH11K_THERMAL) += thermal.o --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c -@@ -1919,7 +1919,9 @@ int ath11k_debugfs_register(struct ath11 +@@ -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); @@ -120,7 +120,7 @@ &fops_peer_ps_state); --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -1664,8 +1664,10 @@ ath11k_update_per_peer_tx_stats(struct a +@@ -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; @@ -131,7 +131,7 @@ } usr_stats->rate_stats_updated = true; -@@ -2105,7 +2107,9 @@ void ath11k_dp_htt_htc_t2h_msg_handler(s +@@ -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: @@ -176,7 +176,7 @@ spin_unlock_bh(&ab->base_lock); --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -9869,7 +9869,7 @@ static const struct ieee80211_ops ath11k +@@ -9812,7 +9812,7 @@ static const struct ieee80211_ops ath11k .set_wakeup = ath11k_wow_op_set_wakeup, #endif diff --git a/package/kernel/mac80211/patches/nss/subsys/007-fix_compilation_issue.patch b/package/kernel/mac80211/patches/nss/subsys/007-fix_compilation_issue.patch index 3b9f555b3bce51..d89cfbe51cb8ab 100644 --- a/package/kernel/mac80211/patches/nss/subsys/007-fix_compilation_issue.patch +++ b/package/kernel/mac80211/patches/nss/subsys/007-fix_compilation_issue.patch @@ -1,6 +1,6 @@ --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -9224,7 +9224,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 */ @@ -9,7 +9,7 @@ enum nl80211_commands cmd, u8 count, u64 color_bitmap); -@@ -9234,9 +9234,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, @@ -21,7 +21,7 @@ 0, color_bitmap); } -@@ -9250,7 +9250,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) { @@ -30,7 +30,7 @@ count, 0); } -@@ -9262,7 +9262,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) { @@ -39,7 +39,7 @@ 0, 0); } -@@ -9274,7 +9274,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) { @@ -50,7 +50,7 @@ } --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -4771,7 +4771,7 @@ void ieee80211_color_collision_detection +@@ -4780,7 +4780,7 @@ void ieee80211_color_collision_detection struct ieee80211_sub_if_data *sdata = link->sdata; sdata_lock(sdata); @@ -72,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 +@@ -1410,18 +1410,6 @@ static void __sta_info_destroy_part2(str WARN_ON_ONCE(ret); } @@ -93,7 +93,7 @@ --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -19406,7 +19406,7 @@ void cfg80211_ch_switch_started_notify(s +@@ -19472,7 +19472,7 @@ void cfg80211_ch_switch_started_notify(s } EXPORT_SYMBOL(cfg80211_ch_switch_started_notify); @@ -102,7 +102,7 @@ enum nl80211_commands cmd, u8 count, u64 color_bitmap) { -@@ -19420,7 +19420,7 @@ int cfg80211_bss_color_notify(struct net +@@ -19486,7 +19486,7 @@ int cfg80211_bss_color_notify(struct net trace_cfg80211_bss_color_notify(dev, cmd, count, color_bitmap); @@ -111,7 +111,7 @@ if (!msg) return -ENOMEM; -@@ -19443,7 +19443,7 @@ int cfg80211_bss_color_notify(struct net +@@ -19509,7 +19509,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/nss/subsys/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 index 82d8c4e05bb11f..a5da9e91eae835 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 +@@ -4688,8 +4688,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/nss/subsys/199-001-mac80211-add-nss-support.patch b/package/kernel/mac80211/patches/nss/subsys/199-001-mac80211-add-nss-support.patch index 1c508dc8884c96..2943f6b04bad5c 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 +@@ -1408,7 +1424,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 +@@ -1416,7 +1432,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 +@@ -1989,6 +2005,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 { +@@ -2680,6 +2706,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 { +@@ -2737,6 +2765,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 { +@@ -3749,6 +3778,10 @@ struct ieee80211_prep_tx_info { * non-MLO connections. * The callback can sleep. * @@ -116,7 +116,7 @@ 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 { +@@ -4300,7 +4333,9 @@ struct ieee80211_ops { struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, u64 changed); @@ -127,7 +127,7 @@ Signed-off-by: Sriram R 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 { +@@ -4605,7 +4640,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 -@@ -2368,6 +2368,9 @@ sta_get_last_rx_stats(struct sta_info *s +@@ -2370,6 +2370,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 +@@ -4641,13 +4655,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 +@@ -2679,7 +2679,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 +@@ -2729,6 +2729,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 +@@ -2757,6 +2759,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); diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index 87c2a52b676f21..fffe171334c9a4 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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: +@@ -6215,7 +6215,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 index db6550ab79c2cc..bd9c1c024b1e5d 100644 --- 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 @@ -31,7 +31,7 @@ Signed-off-by: Muna Sinada --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -9229,4 +9229,15 @@ bool cfg80211_valid_disable_subchannel_b +@@ -9327,4 +9327,15 @@ bool cfg80211_valid_disable_subchannel_b */ void cfg80211_links_removed(struct net_device *dev, u16 link_mask); @@ -49,7 +49,7 @@ Signed-off-by: Muna Sinada #endif /* __NET_CFG80211_H */ --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -7353,6 +7353,20 @@ u32 ieee80211_calc_rx_airtime(struct iee +@@ -7361,6 +7361,20 @@ u32 ieee80211_calc_rx_airtime(struct iee int len); /** @@ -91,18 +91,18 @@ Signed-off-by: Muna Sinada /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ -@@ -2818,6 +2823,8 @@ enum nl80211_commands { - * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce - * transmit power to stay within regulatory limits. u32, dBi. +@@ -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 -@@ -3358,6 +3365,8 @@ enum nl80211_attrs { +@@ -3353,6 +3360,8 @@ enum nl80211_attrs { - NL80211_ATTR_WIPHY_ANTENNA_GAIN, + NL80211_ATTR_MLO_LINK_DISABLED, + NL80211_ATTR_HE_MUEDCA_PARAMS, + @@ -111,7 +111,7 @@ Signed-off-by: Muna Sinada __NL80211_ATTR_AFTER_LAST, --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c -@@ -7910,3 +7910,15 @@ void ieee80211_disable_rssi_reports(stru +@@ -7954,3 +7954,15 @@ void ieee80211_disable_rssi_reports(stru _ieee80211_enable_rssi_reports(sdata, 0, 0); } EXPORT_SYMBOL(ieee80211_disable_rssi_reports); @@ -129,7 +129,7 @@ Signed-off-by: Muna Sinada +EXPORT_SYMBOL(ieee80211_update_muedca_params); --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h -@@ -3085,6 +3085,26 @@ TRACE_EVENT(stop_queue, +@@ -3092,6 +3092,26 @@ TRACE_EVENT(stop_queue, ) ); @@ -158,7 +158,7 @@ Signed-off-by: Muna Sinada #undef TRACE_INCLUDE_PATH --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -20170,6 +20170,42 @@ nla_put_failure: +@@ -20199,6 +20199,42 @@ nla_put_failure: } EXPORT_SYMBOL(cfg80211_update_owe_info_event); diff --git a/package/kernel/mac80211/patches/nss/subsys/207-ath11k-Add-support-for-dynamic-vlan.patch b/package/kernel/mac80211/patches/nss/subsys/207-ath11k-Add-support-for-dynamic-vlan.patch index af46c8f0bfa05e..15d796071fa077 100644 --- a/package/kernel/mac80211/patches/nss/subsys/207-ath11k-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 +@@ -4270,6 +4273,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 +@@ -4291,6 +4296,19 @@ void __ieee80211_subif_start_xmit(struct if (IS_ERR(sta)) sta = NULL; diff --git a/package/kernel/mac80211/patches/nss/subsys/207-mac80211-add-nss-redirect-support.patch b/package/kernel/mac80211/patches/nss/subsys/207-mac80211-add-nss-redirect-support.patch index c9a12d5f127cbe..a4895803b38ba0 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 +@@ -4503,6 +4503,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 +@@ -4516,6 +4545,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 +@@ -4702,6 +4735,9 @@ netdev_tx_t ieee80211_subif_start_xmit_8 struct ieee80211_key *key; struct sta_info *sta; diff --git a/package/kernel/mac80211/patches/nss/subsys/235-001-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 index cf3784afa29b2a..55e2fff1560fb8 100644 --- a/package/kernel/mac80211/patches/nss/subsys/235-001-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 -@@ -5095,6 +5095,17 @@ void ieee80211_sta_pspoll(struct ieee802 +@@ -5098,6 +5098,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 -@@ -2176,7 +2176,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); @@ -137,8 +137,8 @@ Signed-off-by: Sathishkumar Muruganandam { --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4298,8 +4298,13 @@ void __ieee80211_subif_start_xmit(struct - atomic_inc(&sta->tx_netif_pkts); +@@ -4297,8 +4297,13 @@ void __ieee80211_subif_start_xmit(struct + sta = NULL; if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { - ap_sdata = container_of(sdata->bss, @@ -153,7 +153,7 @@ Signed-off-by: Sathishkumar Muruganandam if (ap_sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED && !is_multicast_ether_addr(skb->data)) { if (sta) -@@ -4692,7 +4692,8 @@ static void ieee80211_8023_xmit(struct i +@@ -4688,7 +4693,8 @@ static void ieee80211_8023_xmit(struct i info->hw_queue = sdata->vif.hw_queue[queue]; @@ -197,7 +197,7 @@ Signed-off-by: Sathishkumar Muruganandam drv_remove_interface(local, sdata); --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c -@@ -5218,7 +5218,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/nss/subsys/236-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 index 453f516497a5b5..803ee900bfdcc1 100644 --- a/package/kernel/mac80211/patches/nss/subsys/236-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 -@@ -2084,6 +2084,8 @@ enum ieee80211_key_flags { +@@ -2086,6 +2086,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) -@@ -2103,6 +2105,7 @@ struct ieee80211_key_conf { +@@ -2105,6 +2107,7 @@ struct ieee80211_key_conf { u8 hw_key_idx; s8 keyidx; u16 flags; @@ -102,7 +102,7 @@ Signed-off-by: Sathishkumar Muruganandam key->conf.cipher = cipher; --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4654,16 +4654,25 @@ static void ieee80211_8023_xmit(struct i +@@ -4649,16 +4649,25 @@ static void ieee80211_8023_xmit(struct i struct ieee80211_key *key, struct sk_buff *skb) { struct ieee80211_tx_info *info; diff --git a/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch b/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch index 2503fa030c946c..310256f78d42fb 100644 --- a/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch +++ b/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch @@ -30,7 +30,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran struct ieee80211_local *local; --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4676,19 +4676,21 @@ static void ieee80211_8023_xmit(struct i +@@ -4678,19 +4678,21 @@ static void ieee80211_8023_xmit(struct i ieee80211_aggr_check(sdata, sta, skb); @@ -64,7 +64,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran } skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); -@@ -4745,7 +4747,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4747,7 +4749,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; @@ -73,7 +73,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran struct sta_info *sta; #ifdef CPTCFG_MAC80211_NSS_SUPPORT -@@ -4763,9 +4765,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4765,9 +4767,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 goto out; } @@ -90,7 +90,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran goto skip_offload; key = rcu_dereference(sta->ptk[sta->ptk_idx]); -@@ -4776,6 +4782,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4778,6 +4784,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); @@ -98,7 +98,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran ieee80211_8023_xmit(sdata, dev, sta, key, skb); goto out; -@@ -6282,13 +6289,7 @@ start_xmit: +@@ -6284,13 +6291,7 @@ start_xmit: mutex_lock(&local->mtx); local_bh_disable(); diff --git a/package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch b/package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch index 5e0a156312fe4e..55ad36baf69aa4 100644 --- a/package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch +++ b/package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch @@ -66,7 +66,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran }; /* -@@ -792,6 +801,11 @@ struct ieee80211_bss_conf { +@@ -790,6 +799,11 @@ struct ieee80211_bss_conf { bool he_full_ul_mumimo; bool eht_su_beamformer; bool eht_su_beamformee; @@ -112,7 +112,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran }; -@@ -2768,6 +2788,7 @@ enum ieee80211_hw_flags { +@@ -2769,6 +2789,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 -@@ -4268,6 +4289,8 @@ struct ieee80211_prep_tx_info { +@@ -4269,6 +4290,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. -@@ -4651,6 +4674,12 @@ struct ieee80211_ops { +@@ -4652,6 +4675,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); -@@ -7509,4 +7538,100 @@ int ieee80211_set_active_links(struct ie +@@ -7510,4 +7539,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 -@@ -2521,6 +2521,7 @@ static int ieee80211_update_mesh_config( +@@ -2523,6 +2523,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; -@@ -2537,8 +2538,11 @@ static int ieee80211_update_mesh_config( +@@ -2539,8 +2540,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)) { -@@ -2552,8 +2556,12 @@ static int ieee80211_update_mesh_config( +@@ -2554,8 +2558,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)) -@@ -2588,8 +2596,12 @@ static int ieee80211_update_mesh_config( +@@ -2590,8 +2598,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. -@@ -2631,6 +2643,7 @@ static int ieee80211_update_mesh_config( +@@ -2633,6 +2645,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 -@@ -572,3 +572,23 @@ int drv_change_sta_links(struct ieee8021 +@@ -579,3 +579,23 @@ int drv_change_sta_links(struct ieee8021 return 0; } @@ -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 +@@ -315,6 +315,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 +@@ -356,6 +360,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,7 @@ 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 -@@ -2609,7 +2609,7 @@ 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; @@ -1182,7 +1182,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran int ret; u8 link_id = u32_get_bits(ctrl_flags, IEEE80211_TX_CTRL_MLO_LINK); -@@ -2621,6 +2621,9 @@ static struct sk_buff *ieee80211_build_h +@@ -2622,6 +2622,9 @@ static struct sk_buff *ieee80211_build_h info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; #endif @@ -1192,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]; -@@ -2691,6 +2694,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: @@ -1206,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; -@@ -2954,10 +2964,10 @@ static struct sk_buff *ieee80211_build_h +@@ -2955,10 +2965,10 @@ static struct sk_buff *ieee80211_build_h skb_reset_mac_header(skb); @@ -1221,7 +1221,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran info->ack_frame_id = info_id; info->band = band; -@@ -4272,6 +4282,7 @@ void __ieee80211_subif_start_xmit(struct +@@ -4274,6 +4284,7 @@ void __ieee80211_subif_start_xmit(struct struct sk_buff *next; int len = skb->len; struct ieee80211_key *key = NULL; @@ -1229,7 +1229,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran struct ieee80211_sub_if_data *ap_sdata; if (unlikely(!ieee80211_sdata_running(sdata) || skb->len < ETH_HLEN)) { -@@ -4348,9 +4359,15 @@ void __ieee80211_subif_start_xmit(struct +@@ -4350,9 +4361,15 @@ void __ieee80211_subif_start_xmit(struct goto out; } diff --git a/package/kernel/mac80211/patches/nss/subsys/335-0003-ath11k-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 index b488e431c6cd3c..f78d7ce6e09304 100644 --- a/package/kernel/mac80211/patches/nss/subsys/335-0003-ath11k-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 -@@ -2728,6 +2728,8 @@ struct ieee80211_txq { +@@ -2731,6 +2731,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 { -@@ -2787,6 +2789,7 @@ enum ieee80211_hw_flags { +@@ -2790,6 +2792,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/nss/subsys/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 index 0a3e71bee9716f..63373b7751f9eb 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -4759,6 +4759,67 @@ out_free: +@@ -4761,6 +4761,67 @@ out_free: kfree_skb(skb); } @@ -82,7 +82,7 @@ Signed-off-by: Aloka Dixit netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, struct net_device *dev) { -@@ -4798,6 +4859,11 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4800,6 +4861,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/nss/subsys/336-mac80211-Mesh-Fast-rx-support.patch b/package/kernel/mac80211/patches/nss/subsys/336-mac80211-Mesh-Fast-rx-support.patch index eb6c51c8ba0cad..0b89a11957bec4 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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); @@ -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; -@@ -4876,6 +4881,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 -@@ -4925,6 +4934,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))) -@@ -4962,9 +5002,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/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch b/package/kernel/mac80211/patches/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch index 0be0c6106bf788..0cb2a1e95244e3 100644 --- a/package/kernel/mac80211/patches/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch +++ b/package/kernel/mac80211/patches/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch @@ -33,7 +33,7 @@ Signed-off-by: Tamizh Chelvam --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4711,7 +4711,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4695,7 +4695,7 @@ static void ieee80211_8023_xmit(struct i ieee80211_aggr_check(sdata, sta, skb); @@ -42,7 +42,7 @@ Signed-off-by: Tamizh Chelvam tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); if (tid_tx) { -@@ -4762,7 +4762,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4746,7 +4746,7 @@ static void ieee80211_8023_xmit(struct i &info->flags, NULL); dev_sw_netstats_tx_add(dev, skbs, len); 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 index 5fd21ba6a4d42b..808f69e644ed61 100644 --- 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 @@ -10,11 +10,9 @@ Signed-off-by: Hari Chandrakanthan net/mac80211/spectmgmt.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) -diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c -index 76747bf..7ddfb96 100644 --- a/net/mac80211/spectmgmt.c +++ b/net/mac80211/spectmgmt.c -@@ -33,7 +33,10 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, +@@ -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; @@ -25,7 +23,7 @@ index 76747bf..7ddfb96 100644 memset(csa_ie, 0, sizeof(*csa_ie)); -@@ -133,20 +136,13 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, +@@ -133,20 +136,13 @@ int ieee80211_parse_ch_switch_ie(struct } if (wide_bw_chansw_ie) { @@ -52,6 +50,3 @@ index 76747bf..7ddfb96 100644 /* default, for the case of IEEE80211_VHT_CHANWIDTH_USE_HT, * to the previously parsed chandef --- -2.7.4 - 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 index 82e44b83600984..df2b3a9257b115 100644 --- 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 @@ -19,11 +19,9 @@ Signed-off-by: Hari Chandrakanthan net/mac80211/spectmgmt.c | 4 ++++ 1 file changed, 4 insertions(+) -diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c -index 7ddfb96..15c7ac3 100644 --- a/net/mac80211/spectmgmt.c +++ b/net/mac80211/spectmgmt.c -@@ -136,6 +136,10 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, +@@ -136,6 +136,10 @@ int ieee80211_parse_ch_switch_ie(struct } if (wide_bw_chansw_ie) { @@ -34,6 +32,3 @@ index 7ddfb96..15c7ac3 100644 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; --- -2.7.4 - diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index eaec491461b6cc..2cb2ebe6f58f76 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -1427,8 +1427,6 @@ ieee80211_tx_info_clear_status(struct ie +@@ -1405,8 +1405,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 -@@ -1500,22 +1498,21 @@ enum mac80211_rx_flags { +@@ -1478,22 +1476,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 -@@ -517,18 +517,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/nss/subsys/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 index e0415032bb8ae7..a947728fc661f1 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -2061,6 +2061,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); @@ -44,7 +44,7 @@ Signed-off-by: Aaradhana Sahu /* misc utils */ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, -@@ -4320,7 +4321,7 @@ void __ieee80211_subif_start_xmit(struct +@@ -4319,7 +4320,7 @@ void __ieee80211_subif_start_xmit(struct !is_multicast_ether_addr(skb->data)) { if (sta) key = rcu_dereference(sta->ptk[sta->ptk_idx]); @@ -53,7 +53,7 @@ Signed-off-by: Aaradhana Sahu rcu_read_unlock(); return; } -@@ -4366,7 +4367,7 @@ void __ieee80211_subif_start_xmit(struct +@@ -4365,7 +4366,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]); @@ -62,7 +62,7 @@ Signed-off-by: Aaradhana Sahu } else { dev_sw_netstats_tx_add(dev, 1, skb->len); ieee80211_xmit(sdata, sta, skb); -@@ -4667,7 +4668,8 @@ static bool ieee80211_tx_8023(struct iee +@@ -4663,7 +4664,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, @@ -72,7 +72,7 @@ Signed-off-by: Aaradhana Sahu { struct ieee80211_tx_info *info; struct ethhdr *ehdr = (struct ethhdr *)skb->data; -@@ -4723,6 +4725,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4719,6 +4721,7 @@ static void ieee80211_8023_xmit(struct i info = IEEE80211_SKB_CB(skb); memset(info, 0, sizeof(*info)); @@ -80,7 +80,7 @@ Signed-off-by: Aaradhana Sahu info->hw_queue = sdata->vif.hw_queue[queue]; if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && -@@ -4743,11 +4746,12 @@ static void ieee80211_8023_xmit(struct i +@@ -4739,11 +4742,12 @@ static void ieee80211_8023_xmit(struct i memcpy(IEEE80211_SKB_CB(seg), info, sizeof(*info)); } @@ -96,7 +96,7 @@ Signed-off-by: Aaradhana Sahu dev_sw_netstats_tx_add(dev, skbs, len); if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD) && sta) { -@@ -4770,7 +4774,8 @@ out_free: +@@ -4763,7 +4767,8 @@ out_free: void ieee80211_8023_xmit_ap(struct ieee80211_sub_if_data *sdata, struct net_device *dev, struct sta_info *sta, @@ -106,7 +106,7 @@ Signed-off-by: Aaradhana Sahu { struct ieee80211_tx_info *info; struct ieee80211_local *local = sdata->local; -@@ -4779,6 +4784,9 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4772,6 +4777,9 @@ void ieee80211_8023_xmit_ap(struct ieee8 unsigned long flags; int q; u16 q_map; @@ -116,7 +116,7 @@ Signed-off-by: Aaradhana Sahu /* * If the skb is shared we need to obtain our own copy. -@@ -4790,11 +4798,13 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4783,11 +4791,13 @@ void ieee80211_8023_xmit_ap(struct ieee8 info = IEEE80211_SKB_CB(skb); memset(info, 0, sizeof(*info)); @@ -133,9 +133,9 @@ Signed-off-by: Aaradhana Sahu info->flags |= IEEE80211_TX_CTL_HW_80211_ENCAP; info->control.vif = &sdata->vif; -@@ -4831,14 +4841,23 @@ void ieee80211_8023_xmit_ap(struct ieee8 - if (sta) - atomic_inc(&sta->tx_drv_pkts); +@@ -4821,14 +4831,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, @@ -158,7 +158,7 @@ Signed-off-by: Aaradhana Sahu #ifdef CPTCFG_MAC80211_NSS_SUPPORT ieee80211_xmit_nss_fixup(skb, dev); -@@ -4854,14 +4873,15 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4844,14 +4863,15 @@ netdev_tx_t ieee80211_subif_start_xmit_8 kfree_skb(skb); goto out; } @@ -176,7 +176,7 @@ Signed-off-by: Aaradhana Sahu goto skip_offload; key = rcu_dereference(sta->ptk[sta->ptk_idx]); -@@ -4872,13 +4892,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4862,13 +4882,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 goto skip_offload; if (sdata->vif.type == NL80211_IFTYPE_AP) { @@ -192,7 +192,7 @@ Signed-off-by: Aaradhana Sahu goto out; skip_offload: -@@ -6384,7 +6404,10 @@ start_xmit: +@@ -6374,7 +6394,10 @@ start_xmit: mutex_lock(&local->mtx); local_bh_disable(); diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index 61421d7d766950..7ffaf99158b90e 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -2373,7 +2373,7 @@ static void mpath_set_pinfo(struct mesh_ +@@ -2350,7 +2350,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,7 +94,7 @@ 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 -@@ -510,7 +510,7 @@ 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) { @@ -103,7 +103,7 @@ Signed-off-by: P Praneesh flush_mpath = true; } mesh_path_assign_nexthop(mpath, sta); -@@ -571,7 +571,7 @@ 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) { diff --git a/package/kernel/mac80211/patches/nss/subsys/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch b/package/kernel/mac80211/patches/nss/subsys/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch index e3c2db4cc8a713..8d8c3c68d58c91 100644 --- a/package/kernel/mac80211/patches/nss/subsys/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch +++ b/package/kernel/mac80211/patches/nss/subsys/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch @@ -19,7 +19,7 @@ Signed-off-by: Ramanathan Choodamani --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4572,6 +4572,7 @@ netdev_tx_t ieee80211_subif_start_xmit(s +@@ -4571,6 +4571,7 @@ netdev_tx_t ieee80211_subif_start_xmit(s #ifdef CPTCFG_MAC80211_NSS_SUPPORT ieee80211_xmit_nss_fixup(skb, dev); #endif @@ -27,7 +27,7 @@ Signed-off-by: Ramanathan Choodamani if (likely(!is_multicast_ether_addr(eth->h_dest))) goto normal; -@@ -4844,7 +4845,43 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4834,7 +4835,43 @@ void ieee80211_8023_xmit_ap(struct ieee8 netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, struct net_device *dev) { diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index a2a9879f25285b..6b5cf7f3e24660 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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, -@@ -3631,7 +3633,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; -@@ -3649,7 +3651,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) -@@ -3795,7 +3797,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; -@@ -4344,7 +4346,7 @@ void __ieee80211_subif_start_xmit(struct +@@ -4343,7 +4345,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,7 +67,7 @@ Signed-off-by: Tamizh Chelvam Raja if (!skb) { len = 0; goto out; -@@ -4572,7 +4574,6 @@ netdev_tx_t ieee80211_subif_start_xmit(s +@@ -4571,7 +4573,6 @@ netdev_tx_t ieee80211_subif_start_xmit(s #ifdef CPTCFG_MAC80211_NSS_SUPPORT ieee80211_xmit_nss_fixup(skb, dev); #endif @@ -75,7 +75,7 @@ Signed-off-by: Tamizh Chelvam Raja if (likely(!is_multicast_ether_addr(eth->h_dest))) goto normal; -@@ -4719,7 +4720,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4715,7 +4716,7 @@ static void ieee80211_8023_xmit(struct i } } @@ -84,7 +84,7 @@ Signed-off-by: Tamizh Chelvam Raja if (!skb) return; -@@ -4845,6 +4846,7 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4835,6 +4836,7 @@ void ieee80211_8023_xmit_ap(struct ieee8 netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, struct net_device *dev) { @@ -92,7 +92,7 @@ Signed-off-by: Tamizh Chelvam Raja 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 = {}; -@@ -4879,9 +4881,10 @@ out: +@@ -4869,9 +4871,10 @@ out: } return NETDEV_TX_OK; 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 index e25220a1b01c99..b76692a6f9500c 100644 --- 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 @@ -23,7 +23,7 @@ Signed-off-by: Yuvasree Sivasankaran --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -2727,6 +2727,9 @@ struct ieee80211_txq { +@@ -2730,6 +2730,9 @@ struct ieee80211_txq { * * @IEEE80211_HW_SUPPORTS_TID_CLASS_OFFLOAD: Hardware suports tid calssification offload. * @@ -33,7 +33,7 @@ Signed-off-by: Yuvasree Sivasankaran * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays */ enum ieee80211_hw_flags { -@@ -2787,6 +2790,7 @@ enum ieee80211_hw_flags { +@@ -2790,6 +2793,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_SUPPORTS_NSS_OFFLOAD, IEEE80211_HW_SUPPORTS_MESH_NSS_OFFLOAD, IEEE80211_HW_SUPPORTS_TID_CLASS_OFFLOAD, @@ -43,7 +43,7 @@ Signed-off-by: Yuvasree Sivasankaran NUM_IEEE80211_HW_FLAGS --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c -@@ -499,6 +499,7 @@ static const char *hw_flag_names[] = { +@@ -508,6 +508,7 @@ static const char *hw_flag_names[] = { FLAG(SUPPORTS_NSS_OFFLOAD), FLAG(SUPPORTS_MESH_NSS_OFFLOAD), FLAG(SUPPORTS_TID_CLASS_OFFLOAD), @@ -53,7 +53,7 @@ Signed-off-by: Yuvasree Sivasankaran --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -1602,6 +1602,9 @@ int ieee80211_txq_setup_flows(struct iee +@@ -1603,6 +1603,9 @@ int ieee80211_txq_setup_flows(struct iee bool supp_vht = false; enum nl80211_band band; @@ -63,7 +63,7 @@ Signed-off-by: Yuvasree Sivasankaran ret = fq_init(fq, 4096); if (ret) return ret; -@@ -1649,6 +1652,9 @@ void ieee80211_txq_teardown_flows(struct +@@ -1650,6 +1653,9 @@ void ieee80211_txq_teardown_flows(struct { struct fq *fq = &local->fq; @@ -73,7 +73,7 @@ Signed-off-by: Yuvasree Sivasankaran kfree(local->cvars); local->cvars = NULL; -@@ -1665,7 +1671,8 @@ static bool ieee80211_queue_skb(struct i +@@ -1666,7 +1672,8 @@ static bool ieee80211_queue_skb(struct i struct ieee80211_vif *vif; struct txq_info *txqi; @@ -83,7 +83,7 @@ Signed-off-by: Yuvasree Sivasankaran return false; if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) -@@ -4326,7 +4333,8 @@ void __ieee80211_subif_start_xmit(struct +@@ -4328,7 +4335,8 @@ void __ieee80211_subif_start_xmit(struct } } @@ -93,7 +93,7 @@ Signed-off-by: Yuvasree Sivasankaran ieee80211_aggr_check(sdata, sta, skb); if (sta) { -@@ -4678,8 +4686,10 @@ static void ieee80211_8023_xmit(struct i +@@ -4680,8 +4688,10 @@ static void ieee80211_8023_xmit(struct i bool multicast; u8 tid; @@ -106,7 +106,7 @@ Signed-off-by: Yuvasree Sivasankaran multicast = is_multicast_ether_addr(ra); -@@ -6414,9 +6424,12 @@ int ieee80211_tx_control_port(struct wip +@@ -6416,9 +6426,12 @@ int ieee80211_tx_control_port(struct wip } if (!IS_ERR(sta)) { @@ -123,7 +123,7 @@ Signed-off-by: Yuvasree Sivasankaran * for MLO STA, the SA should be the AP MLD address, but --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -4516,6 +4516,9 @@ static int ieee80211_get_txq_stats(struc +@@ -4525,6 +4525,9 @@ static int ieee80211_get_txq_stats(struc struct ieee80211_sub_if_data *sdata; int ret = 0; @@ -135,7 +135,7 @@ Signed-off-by: Yuvasree Sivasankaran --- a/net/mac80211/main.c +++ b/net/mac80211/main.c -@@ -841,7 +841,10 @@ struct ieee80211_hw *ieee80211_alloc_hw_ +@@ -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); @@ -185,7 +185,7 @@ Signed-off-by: Yuvasree Sivasankaran } for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { -@@ -427,7 +429,9 @@ void sta_info_free(struct ieee80211_loca +@@ -430,7 +432,9 @@ void sta_info_free(struct ieee80211_loca sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr); @@ -196,7 +196,7 @@ Signed-off-by: Yuvasree Sivasankaran kfree(rcu_dereference_raw(sta->sta.rates)); #ifdef CPTCFG_MAC80211_MESH kfree(sta->mesh); -@@ -529,8 +533,6 @@ __sta_info_alloc(struct ieee80211_sub_if +@@ -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; @@ -205,7 +205,7 @@ Signed-off-by: Yuvasree Sivasankaran int i; sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp); -@@ -604,18 +606,22 @@ __sta_info_alloc(struct ieee80211_sub_if +@@ -607,18 +609,22 @@ __sta_info_alloc(struct ieee80211_sub_if sta->last_connected = ktime_get_seconds(); @@ -237,7 +237,7 @@ Signed-off-by: Yuvasree Sivasankaran } if (sta_prepare_rate_control(local, sta, gfp)) -@@ -689,7 +695,8 @@ __sta_info_alloc(struct ieee80211_sub_if +@@ -692,7 +698,8 @@ __sta_info_alloc(struct ieee80211_sub_if return sta; free_txq: @@ -247,7 +247,7 @@ Signed-off-by: Yuvasree Sivasankaran free: sta_info_free_link(&sta->deflink); #ifdef CPTCFG_MAC80211_MESH -@@ -1684,11 +1691,13 @@ void ieee80211_sta_ps_deliver_wakeup(str +@@ -1687,11 +1694,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); @@ -265,7 +265,7 @@ Signed-off-by: Yuvasree Sivasankaran } skb_queue_head_init(&pending); -@@ -2103,6 +2112,9 @@ ieee80211_sta_ps_deliver_response(struct +@@ -2106,6 +2115,9 @@ ieee80211_sta_ps_deliver_response(struct * TIM recalculation. */ @@ -275,7 +275,7 @@ Signed-off-by: Yuvasree Sivasankaran for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) { if (!sta->sta.txq[tid] || !(driver_release_tids & BIT(tid)) || -@@ -2519,7 +2531,7 @@ static void sta_set_tidstats(struct sta_ +@@ -2521,7 +2533,7 @@ static void sta_set_tidstats(struct sta_ tidstats->tx_msdu_failed = sta->deflink.status_stats.msdu_failed[tid]; } @@ -284,7 +284,7 @@ Signed-off-by: Yuvasree Sivasankaran spin_lock_bh(&local->fq.lock); rcu_read_lock(); -@@ -2847,6 +2859,9 @@ unsigned long ieee80211_sta_last_active( +@@ -2849,6 +2861,9 @@ unsigned long ieee80211_sta_last_active( static void sta_update_codel_params(struct sta_info *sta, u32 thr) { diff --git a/package/kernel/mac80211/patches/nss/subsys/829-mac80211-fix-mesh-ping-issue.patch b/package/kernel/mac80211/patches/nss/subsys/829-mac80211-fix-mesh-ping-issue.patch index c19d97a818ba17..642901bed17459 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -4649,16 +4649,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; } -@@ -4881,10 +4879,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 -@@ -4934,37 +4929,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))) -@@ -5002,30 +4966,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/nss/subsys/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 index db714cd568b203..0f8289a892d4a4 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 @@ -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; From bd7e1a5b52ae7a7bb02c64611a07a37c583585bf Mon Sep 17 00:00:00 2001 From: Qosmio Date: Tue, 27 Feb 2024 11:10:36 -0500 Subject: [PATCH 125/225] ath11k_nss: Experimental build for IPQ6018 This will require setting the correct `ATH11K_MEM_PROFILE_XXX` for your platform. Setting it to value lower/higher than physically available will cause NULL virtual address kernel panics. I believe this setting was not originally meant to reduce memory footprint of 1G+ platforms, but to account for platforms that were 512M or less. Will require tweaking to allow for the old behvaior on 1G+ IPQ807x, while still saving memory for platforms <= 512M. --- ...207-ath11k-Enable-256_512MB-profiles.patch | 32 +- ...11k-Disable-rx_header-tlv-for-2K-SKB.patch | 1016 +++++++++++++++++ ...pport-for-WDS-offload-in-NSS-offload.patch | 24 +- ...-dynamic-VLAN-support-in-NSS-offload.patch | 16 +- ...ow-fast-rx-by-bypassing-stats-update.patch | 4 +- ...ow-fast-rx-by-bypassing-stats-update.patch | 46 +- .../nss/ath11k/244-ath11k-dp-tx-perf.patch | 27 +- .../300-ath11k-nss-mesh-offload-support.patch | 20 +- ...lookup-failure-in-mgmt-tx-completion.patch | 2 +- ...e-free-of-peer-rx_tid-during-reo-cmd.patch | 2 +- ...TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch | 2 +- ...ing-rx-stats-with-monitor-vif-enable.patch | 8 +- ...1k-skip-status-ring-entry-processing.patch | 8 +- ...356-ath11k-invalid-desc-sanity-check.patch | 6 +- ...-fix-tkip-encryption-traffic-failure.patch | 2 +- ...Fix-ppdu_id-from-firmware-PPDU-stats.patch | 8 +- ...Add-retry-mechanism-for-update_rx_qu.patch | 18 +- ...th11k-Advertise-TX_QUEUE-mac-hw-flag.patch | 2 +- ...oid-memset-of-ppdu-info-for-next-skb.patch | 6 +- ...11k-remove-invalid-peer-create-logic.patch | 4 +- ...th11k-rename-ath11k_start_vdev_delay.patch | 2 +- ...ation-of-ath11k_mac_start_vdev_delay.patch | 2 +- ...ailure-due-to-unexpected-peer-delete.patch | 16 +- ...k-make-debugfs-sta-htt-stats-modular.patch | 8 +- 24 files changed, 1169 insertions(+), 112 deletions(-) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch diff --git a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch index d89b500015fc33..ce5bcf84f1f7c1 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch @@ -254,7 +254,15 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = false, -@@ -259,7 +262,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -210,6 +213,7 @@ 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, + }, + { + .name = "qca6390 hw2.0", +@@ -259,7 +263,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -263,7 +271,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -426,7 +429,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -426,7 +430,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -272,7 +280,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -462,6 +465,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -462,6 +466,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, @@ -280,7 +288,7 @@ Signed-off-by: Ramya Gnanasekar }, { .name = "wcn6855 hw2.1", -@@ -509,7 +513,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -509,7 +514,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -289,7 +297,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -545,6 +549,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -545,6 +550,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, @@ -297,7 +305,7 @@ Signed-off-by: Ramya Gnanasekar }, { .name = "wcn6750 hw1.0", -@@ -593,7 +598,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -593,7 +599,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = true, .coldboot_cal_ftm = true, .cbcal_restart_fw = false, @@ -306,7 +314,15 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = false, -@@ -672,7 +677,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -626,6 +632,7 @@ static struct ath11k_hw_params ath11k_hw + .tx_ring_size = DP_TCL_DATA_RING_SIZE_WCN6750, + .smp2p_wow_exit = true, + .support_fw_mac_sequence = true, ++ .num_vdevs_peers = ath11k_vdevs_peers, + }, + { + .hw_rev = ATH11K_HW_IPQ5018_HW10, +@@ -672,7 +679,7 @@ static struct ath11k_hw_params ath11k_hw .supports_monitor = false, .supports_sta_ps = false, .supports_shadow_regs = false, @@ -315,7 +331,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_regdb = false, -@@ -707,6 +712,22 @@ static struct ath11k_hw_params ath11k_hw +@@ -707,6 +714,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, diff --git a/package/kernel/mac80211/patches/nss/ath11k/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch b/package/kernel/mac80211/patches/nss/ath11k/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch new file mode 100644 index 00000000000000..7b7673953bd4fe --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch @@ -0,0 +1,1016 @@ +From 30f54666ae15128f26fbad787a35253885a10513 Mon Sep 17 00:00:00 2001 +From: Ramya Gnanasekar +Date: Fri, 25 Dec 2020 16:11:06 +0530 +Subject: [PATCH] ath11k: Disable rx_header tlv for 2K SKB + +On low memory platform hdr_status in hal_rx_desc is not subscribed to +get a savings of 128bytes in skb. This is required to reduce the skb +size from 4K to 2K. Use HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG message +to unsubscribe rx_pkt_header tlv for rxdma ring. + +Signed-off-by: Ramya Gnanasekar + +--- a/drivers/net/wireless/ath/ath11k/debugfs.c ++++ b/drivers/net/wireless/ath/ath11k/debugfs.c +@@ -668,6 +668,7 @@ static ssize_t ath11k_write_extd_rx_stat + } + + ar->debug.rx_filter = tlv_filter.rx_filter; ++ tlv_filter.offset_valid = false; + + 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; +@@ -1129,6 +1130,7 @@ static ssize_t ath11k_write_pktlog_filte + } + + /* Clear rx filter set for monitor mode and rx status */ ++ tlv_filter.offset_valid = false; + 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, 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 { + #define DP_REO_CMD_RING_SIZE 256 + #define DP_REO_STATUS_RING_SIZE 2048 + #define DP_RXDMA_BUF_RING_SIZE 4096 +-#define DP_RXDMA_REFILL_RING_SIZE 2048 ++#define DP_RXDMA_REFILL_RING_SIZE ATH11K_DP_RXDMA_REFILL_RING_SIZE ++#define DP_RXDMA_NSS_REFILL_RING_SIZE ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE + #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 +@@ -648,7 +649,7 @@ enum htt_stats_internal_ppdu_frametype { + * + * |31 26|25|24|23 16|15 8|7 0| + * |-----------------+----------------+----------------+---------------| +- * | rsvd1 |PS|SS| ring_id | pdev_id | msg_type | ++ * | rsvd1|OV|PS|SS| ring_id | pdev_id | msg_type | + * |-------------------------------------------------------------------| + * | rsvd2 | ring_buffer_size | + * |-------------------------------------------------------------------| +@@ -662,6 +663,14 @@ enum htt_stats_internal_ppdu_frametype { + * |-------------------------------------------------------------------| + * | tlv_filter_in_flags | + * |-------------------------------------------------------------------| ++ * | rx_header_offset | rx_packet_offset | ++ * |-------------------------------------------------------------------| ++ * | rx_mpdu_start_offset | rx_mpdu_end_offset | ++ * |-------------------------------------------------------------------| ++ * | rx_msdu_start_offset | rx_msdu_end_offset | ++ * |-------------------------------------------------------------------| ++ * | rsvd3 | rx_attention_offset | ++ * |-------------------------------------------------------------------| + * Where: + * PS = pkt_swap + * SS = status_swap +@@ -675,7 +684,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'27:31 - rsvd1: reserved for future use + * dword1 - b'0:16 - ring_buffer_size: size of buffers referenced by rx ring, + * in byte units. + * Valid only for HW_TO_SW_RING and SW_TO_HW_RING +@@ -704,6 +716,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 ++ * dword7 - b'0:15 - rx_packet_offset: rx_packet_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_1 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * - b'16:31 - rx_header_offset: rx_header_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_1 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * dword8 - b'0:15 - rx_mpdu_end_offset: rx_mpdu_end_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_2 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * - b'16:31 - rx_mpdu_start_offset: rx_mpdu_start_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_2 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * dword9 - b'0:15 - rx_msdu_end_offset: rx_msdu_end_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_3 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * - b'16:31 - rx_msdu_start_offset: rx_msdu_start_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_3 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * dword10- b'0:15 - rx_attention_offset: rx_attention_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_4 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * - b'16:31 - rsvd3 for future use + */ + + #define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) +@@ -711,8 +759,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) ++#define HTT_RX_RING_SELECTION_CFG_CMD_OFFSET_VALID BIT(26) + + #define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE GENMASK(15, 0) ++#define HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET GENMASK(15, 0) ++#define HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET GENMASK(31, 16) ++#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET GENMASK(15, 0) ++#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET GENMASK(31, 16) ++#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET GENMASK(15, 0) ++#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET GENMASK(31, 16) ++#define HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET GENMASK(15, 0) + + enum htt_rx_filter_tlv_flags { + HTT_RX_FILTER_TLV_FLAGS_MPDU_START = BIT(0), +@@ -1016,6 +1072,14 @@ enum htt_rx_data_pkt_filter_tlv_flasg3 { + HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER | \ + HTT_RX_FILTER_TLV_FLAGS_ATTENTION) + ++#define HTT_RX_RXDMA_FILTER_TLV_FLAGS_BUF_RING \ ++ (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ ++ HTT_RX_FILTER_TLV_FLAGS_MSDU_START | \ ++ HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \ ++ HTT_RX_FILTER_TLV_FLAGS_MSDU_END | \ ++ HTT_RX_FILTER_TLV_FLAGS_MPDU_END | \ ++ HTT_RX_FILTER_TLV_FLAGS_ATTENTION) ++ + struct htt_rx_ring_selection_cfg_cmd { + u32 info0; + u32 info1; +@@ -1024,6 +1088,10 @@ struct htt_rx_ring_selection_cfg_cmd { + u32 pkt_type_en_flags2; + u32 pkt_type_en_flags3; + u32 rx_filter_tlv; ++ u32 rx_packet_offset; ++ u32 rx_mpdu_offset; ++ u32 rx_msdu_offset; ++ u32 rx_attn_offset; + } __packed; + + struct htt_rx_ring_tlv_filter { +@@ -1032,6 +1100,14 @@ struct htt_rx_ring_tlv_filter { + u32 pkt_filter_flags1; /* MGMT */ + u32 pkt_filter_flags2; /* CTRL */ + u32 pkt_filter_flags3; /* DATA */ ++ bool offset_valid; ++ u16 rx_packet_offset; ++ u16 rx_header_offset; ++ u16 rx_mpdu_end_offset; ++ u16 rx_mpdu_start_offset; ++ u16 rx_msdu_end_offset; ++ u16 rx_msdu_start_offset; ++ u16 rx_attn_offset; + }; + + #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 + return ab->hw_params.hw_ops->rx_desc_get_mpdu_fc_valid(desc); + } + ++static u16 ath11k_dp_rxdesc_get_mpdu_frame_ctrl(struct ath11k_base *ab, ++ struct hal_rx_desc *desc) ++{ ++ return ab->hw_params.hw_ops->rx_desc_get_mpdu_frame_ctl(desc); ++} ++ + 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 + return ab->hw_params.hw_ops->rx_desc_mpdu_start_addr2(desc); + } + ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M ++static void ath11k_dp_get_rx_header_offset(struct ath11k_base *ab, ++ struct htt_rx_ring_tlv_filter *tlv_filter) ++{ ++ ab->hw_params.hw_ops->rx_desc_get_offset(tlv_filter); ++} ++#endif ++ ++static bool ath11k_dp_rx_desc_dot11_hdr_fields_valid(struct ath11k_base *ab, ++ struct hal_rx_desc *desc) ++{ ++ return ab->hw_params.hw_ops->rx_desc_dot11_hdr_fields_valid(desc); ++} ++ ++static void ath11k_dp_rx_desc_get_dot11_hdr(struct ath11k_base *ab, ++ struct hal_rx_desc *desc, ++ struct ieee80211_hdr *hdr) ++{ ++ ab->hw_params.hw_ops->rx_desc_get_dot11_hdr(desc, hdr); ++} ++ ++static void ath11k_dp_rx_desc_get_crypto_header(struct ath11k_base *ab, ++ struct hal_rx_desc *desc, ++ u8 *crypto_hdr, ++ enum hal_encrypt_type enctype) ++{ ++ ab->hw_params.hw_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); ++} ++ + static void ath11k_dp_service_mon_ring(struct timer_list *t) + { + struct ath11k_base *ab = from_timer(ab, t, mon_reap_timer); +@@ -2134,6 +2169,49 @@ int ath11k_dp_rx_crypto_icv_len(struct a + return 0; + } + ++static void ath11k_get_dot11_hdr_from_rx_desc(struct ath11k *ar, ++ struct sk_buff *msdu, ++ struct ath11k_skb_rxcb *rxcb, ++ struct ieee80211_rx_status *status, ++ enum hal_encrypt_type enctype) ++{ ++ struct hal_rx_desc *rx_desc = rxcb->rx_desc; ++ struct ath11k_base *ab = ar->ab; ++ size_t hdr_len, crypto_len; ++ struct ieee80211_hdr *hdr; ++ u16 fc, qos_ctl = 0; ++ u8 *crypto_hdr; ++ ++ if (!(status->flag & RX_FLAG_IV_STRIPPED)) { ++ crypto_len = ath11k_dp_rx_crypto_param_len(ar, enctype); ++ crypto_hdr = skb_push(msdu, crypto_len); ++ ath11k_dp_rx_desc_get_crypto_header(ab, rx_desc, crypto_hdr, enctype); ++ } ++ ++ fc = ath11k_dp_rxdesc_get_mpdu_frame_ctrl(ab, rx_desc); ++ hdr_len = ieee80211_hdrlen(fc); ++ skb_push(msdu, hdr_len); ++ hdr = (struct ieee80211_hdr *)msdu->data; ++ hdr->frame_control = fc; ++ ++ /* Get wifi header from rx_desc */ ++ ath11k_dp_rx_desc_get_dot11_hdr(ab, rx_desc, hdr); ++ ++ if (rxcb->is_mcbc) ++ status->flag &= ~RX_FLAG_PN_VALIDATED; ++ ++ /* Add QOS header */ ++ if (ieee80211_is_data_qos(hdr->frame_control)) { ++ qos_ctl = rxcb->tid; ++ if (ath11k_dp_rx_h_msdu_start_mesh_ctl_present(ab, rx_desc)) ++ qos_ctl |= IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT; ++ ++ /* TODO Add other QoS ctl fields when required */ ++ memcpy(msdu->data + (hdr_len - IEEE80211_QOS_CTL_LEN), ++ &qos_ctl, IEEE80211_QOS_CTL_LEN); ++ } ++} ++ + static void ath11k_dp_rx_h_undecap_nwifi(struct ath11k *ar, + struct sk_buff *msdu, + u8 *first_hdr, +@@ -2147,7 +2225,8 @@ static void ath11k_dp_rx_h_undecap_nwifi + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + u16 qos_ctl = 0; +- u8 *qos; ++ u8 *qos, *crypto_hdr; ++ bool add_qos_ctrl = false; + + /* copy SA & DA and pull decapped header */ + hdr = (struct ieee80211_hdr *)msdu->data; +@@ -2156,7 +2235,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)); + +- if (rxcb->is_first_msdu) { ++ if (rxcb->is_first_msdu && first_hdr) { + /* original 802.11 header is valid for the first msdu + * hence we can reuse the same header + */ +@@ -2186,16 +2265,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); ++ add_qos_ctrl = true; + } + + 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)); ++ if (first_hdr) { ++ memcpy(skb_push(msdu, ++ ath11k_dp_rx_crypto_param_len(ar, enctype)), ++ (void *)hdr + hdr_len, ++ ath11k_dp_rx_crypto_param_len(ar, enctype)); ++ } else { ++ crypto_hdr = skb_push(msdu, ath11k_dp_rx_crypto_param_len(ar, enctype)); ++ ath11k_dp_rx_desc_get_crypto_header(ar->ab, ++ rxcb->rx_desc, crypto_hdr, enctype); ++ } + } + +- if (!rxcb->is_first_msdu) { ++ if (!rxcb->is_first_msdu || add_qos_ctrl) { + memcpy(skb_push(msdu, + IEEE80211_QOS_CTL_LEN), &qos_ctl, + IEEE80211_QOS_CTL_LEN); +@@ -2311,6 +2397,20 @@ static void ath11k_dp_rx_h_undecap_eth(s + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + void *rfc1042; ++ struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); ++ struct ath11k_dp_rfc1042_hdr rfc = {0xaa, 0xaa, 0x03, {0x00, 0x00, 0x00}}; ++ ++ if (!first_hdr) { ++ eth = (struct ethhdr *)msdu->data; ++ ether_addr_copy(da, eth->h_dest); ++ ether_addr_copy(sa, eth->h_source); ++ rfc.snap_type = eth->h_proto; ++ skb_pull(msdu, sizeof(struct ethhdr)); ++ 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); ++ goto exit; ++ } + + rfc1042 = ath11k_dp_rx_h_find_rfc1042(ar, msdu, enctype); + if (WARN_ON_ONCE(!rfc1042)) +@@ -2339,6 +2439,7 @@ static void ath11k_dp_rx_h_undecap_eth(s + + memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); + ++exit: + /* original 802.11 header has a different DA and in + * case of 4addr it may also have different SA + */ +@@ -2357,6 +2458,7 @@ static void ath11k_dp_rx_h_undecap_snap( + size_t hdr_len; + u8 l3_pad_bytes; + struct hal_rx_desc *rx_desc; ++ struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); + + /* Delivered decapped frame: + * [amsdu header] <-- replaced with 802.11 hdr +@@ -2370,6 +2472,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); + ++ if (!first_hdr) { ++ ath11k_get_dot11_hdr_from_rx_desc(ar, msdu, rxcb, status, enctype); ++ return; ++ } ++ + hdr = (struct ieee80211_hdr *)first_hdr; + hdr_len = ieee80211_hdrlen(hdr->frame_control); + +@@ -2766,6 +2873,20 @@ static int ath11k_dp_rx_process_msdu(str + goto free_out; + } + ++ hdr_status = ath11k_dp_rx_h_80211_hdr(ab, rx_desc); ++ /* wifi hdr fields validation for 512M:: ++ * Mcast packets in ethernet frame mode ++ * will need wifi hdr in msdu to validate PN. ++ * Header will be added in undecap routine. ++ * Validation on wifi hdr fields from rx_desc. ++ */ ++ if (!hdr_status && ath11k_dp_rx_h_attn_is_mcbc(ab, rx_desc) && ++ !ath11k_dp_rx_desc_dot11_hdr_fields_valid(ab, rx_desc)) { ++ ath11k_warn(ab, "One or more invalid dot11 header fields\n"); ++ ret = -EIO; ++ goto free_out; ++ } ++ + rxcb = ATH11K_SKB_RXCB(msdu); + rxcb->rx_desc = rx_desc; + msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(ab, rx_desc); +@@ -2778,8 +2899,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); +- ath11k_dbg_dump(ab, ATH11K_DBG_DATA, NULL, "", hdr_status, +- sizeof(struct ieee80211_hdr)); ++ if (hdr_status) ++ ath11k_dbg_dump(ab, ATH11K_DBG_DATA, NULL, "", hdr_status, ++ sizeof(struct ieee80211_hdr)); + ath11k_dbg_dump(ab, ATH11K_DBG_DATA, NULL, "", rx_desc, + sizeof(struct hal_rx_desc)); + goto free_out; +@@ -3649,6 +3771,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); ++ + head_len = hdr_len + hal_rx_desc_sz + IEEE80211_TKIP_IV_LEN; + tail_len = IEEE80211_CCMP_MIC_LEN + IEEE80211_TKIP_ICV_LEN + FCS_LEN; + +@@ -3929,8 +4052,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) + { +- struct ieee80211_hdr *hdr; + u64 pn = 0; ++ struct ieee80211_hdr *hdr; + u8 *ehdr; + u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; + +@@ -4160,8 +4283,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); +- ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", hdr_status, +- sizeof(struct ieee80211_hdr)); ++ if (hdr_status) ++ ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", hdr_status, ++ sizeof(struct ieee80211_hdr)); + ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", rx_desc, + sizeof(struct hal_rx_desc)); + dev_kfree_skb_any(msdu); +@@ -4784,6 +4908,47 @@ void ath11k_dp_rx_pdev_free(struct ath11 + ath11k_dp_rxdma_pdev_buf_free(ar); + } + ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M ++static int ath11k_dp_rxdma_ring_sel_config(struct ath11k *ar) ++{ ++ struct ath11k_pdev_dp *dp = &ar->dp; ++ struct htt_rx_ring_tlv_filter tlv_filter = {0}; ++ u32 ring_id; ++ int ret; ++ u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; ++ ++ ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id; ++ ++ tlv_filter.rx_filter = HTT_RX_RXDMA_FILTER_TLV_FLAGS_BUF_RING; ++ tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR; ++ tlv_filter.pkt_filter_flags3 = HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST | ++ HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST; ++ tlv_filter.offset_valid = true; ++ tlv_filter.rx_packet_offset = hal_rx_desc_sz; ++ tlv_filter.rx_header_offset = 0; ++ ++ ath11k_dp_get_rx_header_offset(ar->ab, &tlv_filter); ++ ++ if (!ar->ab->nss.enabled) ++ ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, dp->mac_id, ++ HAL_RXDMA_BUF, ++ DP_RXDMA_REFILL_RING_SIZE, ++ &tlv_filter); ++ else ++ ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, dp->mac_id, ++ HAL_RXDMA_BUF, ++ DP_RXDMA_NSS_REFILL_RING_SIZE, ++ &tlv_filter); ++ ++ return ret; ++} ++#else ++static int ath11k_dp_rxdma_ring_sel_config(struct ath11k *ar) ++{ ++ return 0; ++} ++#endif ++ + int ath11k_dp_rx_pdev_alloc(struct ath11k_base *ab, int mac_id) + { + struct ath11k *ar = ab->pdevs[mac_id].ar; +@@ -4877,6 +5042,12 @@ config_refill_ring: + } + } + ++ ret = ath11k_dp_rxdma_ring_sel_config(ar); ++ if (ret) { ++ ath11k_warn(ab, "failed to setup rxdma ring selection config\n"); ++ return ret; ++ } ++ + return 0; + } + +--- a/drivers/net/wireless/ath/ath11k/dp_tx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_tx.c +@@ -1183,6 +1183,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)); ++ cmd->info0 |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_OFFSET_VALID, ++ tlv_filter->offset_valid); + + cmd->info1 = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE, + rx_buf_size); +@@ -1192,6 +1194,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; + ++ if (tlv_filter->offset_valid) { ++ cmd->rx_packet_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET, ++ tlv_filter->rx_packet_offset); ++ cmd->rx_packet_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET, ++ tlv_filter->rx_header_offset); ++ ++ cmd->rx_mpdu_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET, ++ tlv_filter->rx_mpdu_end_offset); ++ cmd->rx_mpdu_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET, ++ tlv_filter->rx_mpdu_start_offset); ++ ++ cmd->rx_msdu_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET, ++ tlv_filter->rx_msdu_end_offset); ++ cmd->rx_msdu_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET, ++ tlv_filter->rx_msdu_start_offset); ++ ++ cmd->rx_attn_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET, ++ tlv_filter->rx_attn_offset); ++ } ++ + ret = ath11k_htc_send(&ab->htc, ab->dp.eid, skb); + if (ret) + goto err_free; +@@ -1270,6 +1292,7 @@ int ath11k_dp_tx_htt_monitor_mode_ring_c + } + + ring_id = dp->rxdma_mon_buf_ring.refill_buf_ring.ring_id; ++ tlv_filter.offset_valid = false; + + if (!reset) { + tlv_filter.rx_filter = HTT_RX_MON_FILTER_TLV_FLAGS_MON_BUF_RING; +--- a/drivers/net/wireless/ath/ath11k/hw.c ++++ b/drivers/net/wireless/ath/ath11k/hw.c +@@ -260,7 +260,11 @@ static u8 ath11k_hw_ipq8074_rx_desc_get_ + + static u8 *ath11k_hw_ipq8074_rx_desc_get_hdr_status(struct hal_rx_desc *desc) + { ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + return desc->u.ipq8074.hdr_status; ++#else ++ return NULL; ++#endif + } + + 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 + desc->u.ipq8074.msdu_start.info1 = __cpu_to_le32(info); + } + ++static ++struct rx_attention *ath11k_hw_ipq8074_rx_desc_get_attention(struct hal_rx_desc *desc) ++{ ++ return &desc->u.ipq8074.attention; ++} ++ ++static u8 *ath11k_hw_ipq8074_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) ++{ ++ return &desc->u.ipq8074.msdu_payload[0]; ++} ++ ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M ++static void ath11k_hw_ipq8074_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_ipq8074, mpdu_end_tag)); ++ tlv_filter->rx_mpdu_start_offset = __le16_to_cpu(offsetof ++ (struct hal_rx_desc_ipq8074, mpdu_start_tag)); ++ tlv_filter->rx_msdu_end_offset = __le16_to_cpu(offsetof ++ (struct hal_rx_desc_ipq8074, msdu_end_tag)); ++ tlv_filter->rx_msdu_start_offset = __le16_to_cpu(offsetof ++ (struct hal_rx_desc_ipq8074, msdu_start_tag)); ++ tlv_filter->rx_attn_offset = __le16_to_cpu(offsetof ++ (struct hal_rx_desc_ipq8074, rx_attn_tag)); ++} ++#endif ++ ++static u16 ath11k_hw_ipq8074_rx_desc_get_mpdu_frame_ctl(struct hal_rx_desc *desc) ++{ ++ return __le16_to_cpu(desc->u.ipq8074.mpdu_start.frame_ctrl); ++} ++ + static bool ath11k_hw_ipq8074_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) + { + return __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & + RX_MPDU_START_INFO1_MAC_ADDR2_VALID; + } + +-static u8 *ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) ++static u8* ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) + { + return desc->u.ipq8074.mpdu_start.addr2; + } + +-static +-struct rx_attention *ath11k_hw_ipq8074_rx_desc_get_attention(struct hal_rx_desc *desc) ++static bool ath11k_hw_ipq8074_rx_desc_dot11_hdr_fields_valid(struct hal_rx_desc *desc) + { +- return &desc->u.ipq8074.attention; ++ if ((ath11k_hw_ipq8074_rx_desc_get_mpdu_seq_ctl_vld(desc) && ++ ath11k_hw_ipq8074_rx_desc_get_mpdu_fc_valid(desc) && ++ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & ++ RX_MPDU_START_INFO1_MAC_ADDR1_VALID && ++ ath11k_hw_ipq8074_rx_desc_mac_addr2_valid(desc) && ++ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & ++ RX_MPDU_START_INFO1_MAC_ADDR3_VALID && ++ FIELD_GET((RX_MPDU_START_INFO1_MPDU_DUR_VALID), ++ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1)))) { ++ return true; ++ } ++ return false; ++} ++ ++static void ath11k_hw_ipq8074_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, ++ struct ieee80211_hdr *hdr) ++{ ++ hdr->frame_control = __le16_to_cpu(desc->u.ipq8074.mpdu_start.frame_ctrl); ++ hdr->duration_id = __le16_to_cpu(desc->u.ipq8074.mpdu_start.duration); ++ ether_addr_copy(hdr->addr1, desc->u.ipq8074.mpdu_start.addr1); ++ ether_addr_copy(hdr->addr2, desc->u.ipq8074.mpdu_start.addr2); ++ ether_addr_copy(hdr->addr3, desc->u.ipq8074.mpdu_start.addr3); ++ if (__le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & ++ RX_MPDU_START_INFO1_MAC_ADDR4_VALID) { ++ ether_addr_copy(hdr->addr4, desc->u.ipq8074.mpdu_start.addr4); ++ } ++ hdr->seq_ctrl = __le16_to_cpu(desc->u.ipq8074.mpdu_start.seq_ctrl); ++} ++ ++static void ath11k_hw_ipq8074_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.ipq8074.mpdu_start.pn[0]); ++ crypto_hdr[1] = 0; ++ crypto_hdr[2] = ++ HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.ipq8074.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.ipq8074.mpdu_start.pn[0]); ++ crypto_hdr[1] = ++ HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.ipq8074.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_INFO5_KEY_ID, ++ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info5)); ++ crypto_hdr[3] = 0x20 | (key_id << 6); ++ crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.ipq8074.mpdu_start.pn[0]); ++ crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.ipq8074.mpdu_start.pn[0]); ++ crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.ipq8074.mpdu_start.pn[1]); ++ crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.ipq8074.mpdu_start.pn[1]); + } + +-static u8 *ath11k_hw_ipq8074_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) ++static bool ath11k_hw_qcn9074_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) + { +- return &desc->u.ipq8074.msdu_payload[0]; ++ return __le32_to_cpu(desc->u.qcn9074.mpdu_start.info11) & ++ RX_MPDU_START_INFO11_MAC_ADDR2_VALID; ++} ++ ++static u8* ath11k_hw_qcn9074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) ++{ ++ return desc->u.qcn9074.mpdu_start.addr2; + } + + 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_ + + static u8 *ath11k_hw_qcn9074_rx_desc_get_hdr_status(struct hal_rx_desc *desc) + { ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + return desc->u.qcn9074.hdr_status; ++#else ++ return NULL; ++#endif + } + + 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_ + + static u8 *ath11k_hw_wcn6855_rx_desc_get_hdr_status(struct hal_rx_desc *desc) + { ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + return desc->u.wcn6855.hdr_status; ++#else ++ return NULL; ++#endif + } + + static bool ath11k_hw_wcn6855_rx_desc_encrypt_valid(struct hal_rx_desc *desc) +@@ -929,6 +1047,98 @@ static u32 ath11k_hw_qcn9074_rx_desc_get + return FIELD_GET(HAL_RX_MPDU_INFO_INFO1_MPDU_LEN, + __le32_to_cpu(mpdu_info->u.qcn9074.info1)); + } ++ ++#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]); ++} ++ + 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, +@@ -1009,6 +1219,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 = { +@@ -1050,6 +1267,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 = { +@@ -1132,6 +1356,13 @@ 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, ++#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 wcn6750_ops = { +@@ -1180,6 +1411,8 @@ const struct ath11k_hw_ops ipq5018_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, +@@ -1214,6 +1447,13 @@ const struct ath11k_hw_ops ipq5018_ops = + .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, ++#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, + }; + + #define ATH11K_TX_RING_MASK_0 BIT(0) +--- a/drivers/net/wireless/ath/ath11k/hw.h ++++ b/drivers/net/wireless/ath/ath11k/hw.h +@@ -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 + #else + /* Num VDEVS per radio */ + #define TARGET_NUM_VDEVS(ab) (ab->hw_params.num_vdevs_peers[ab->qmi.target_mem_mode].num_vdevs) +@@ -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 ++#define ATH11K_DP_RXDMA_REFILL_RING_SIZE 2048 ++#define ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE 2048 + #endif + + /* Num of peers for Single Radio mode */ +@@ -128,6 +135,8 @@ 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]; +@@ -285,7 +294,17 @@ 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); ++ 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 ++ u16 (*rx_desc_get_mpdu_frame_ctl)(struct hal_rx_desc *desc); ++ bool (*rx_desc_dot11_hdr_fields_valid)(struct hal_rx_desc *desc); ++ void (*rx_desc_get_dot11_hdr)(struct hal_rx_desc *desc, ++ struct ieee80211_hdr *hdr); ++ void (*rx_desc_get_crypto_header)(struct hal_rx_desc *desc, ++ u8 *crypto_hdr, ++ enum hal_encrypt_type enctype); + }; + + extern const struct ath11k_hw_ops ipq8074_ops; +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -6343,6 +6343,7 @@ static int ath11k_mac_config_mon_status_ + tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar); + } + ++ tlv_filter.offset_valid = false; + 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, +--- 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 { + __le32 mpdu_end_tag; + struct rx_mpdu_end mpdu_end; + u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES]; ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + __le32 hdr_status_tag; + __le32 phy_ppdu_id; + u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN]; ++#endif + u8 msdu_payload[]; + } __packed; + +@@ -1461,9 +1463,11 @@ struct hal_rx_desc_qcn9074 { + __le32 mpdu_end_tag; + struct rx_mpdu_end mpdu_end; + u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES]; ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + __le32 hdr_status_tag; + __le32 phy_ppdu_id; + u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN]; ++#endif + u8 msdu_payload[]; + } __packed; + +@@ -1480,9 +1484,11 @@ struct hal_rx_desc_wcn6855 { + __le32 mpdu_end_tag; + struct rx_mpdu_end mpdu_end; + u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES]; ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + __le32 hdr_status_tag; + __le32 phy_ppdu_id; + u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN]; ++#endif + u8 msdu_payload[]; + } __packed; + +@@ -1507,4 +1513,17 @@ struct hal_rx_desc { + #define RU_484 18 + #define RU_996 37 + ++#define HAL_RX_MPDU_INFO_PN_GET_BYTE1(__val) \ ++ FIELD_GET(GENMASK(7, 0), __le32_to_cpu(__val)) ++ ++#define HAL_RX_MPDU_INFO_PN_GET_BYTE2(__val) \ ++ FIELD_GET(GENMASK(15, 8), __le32_to_cpu(__val)) ++ ++#define HAL_RX_MPDU_INFO_PN_GET_BYTE3(__val) \ ++ FIELD_GET(GENMASK(23, 16), __le32_to_cpu(__val)) ++ ++#define HAL_RX_MPDU_INFO_PN_GET_BYTE4(__val) \ ++ FIELD_GET(GENMASK(31, 24), __le32_to_cpu(__val)) ++ ++ + #endif /* ATH11K_RX_DESC_H */ +--- a/drivers/net/wireless/ath/ath11k/nss.c ++++ b/drivers/net/wireless/ath/ath11k/nss.c +@@ -2230,7 +2230,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; +- wim->wrip.rx_buf_len = DP_RX_BUFFER_SIZE; ++ wim->wrip.rx_buf_len = DP_RXDMA_NSS_REFILL_RING_SIZE; + + /* fill hal srng message */ + wim->hssm.dev_base_addr = (u32)ab->mem_pa; diff --git a/package/kernel/mac80211/patches/nss/ath11k/235-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 index 729ee80199b9a2..10e65157232edb 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/235-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 @@ -214,7 +214,7 @@ Signed-off-by: Sathishkumar Muruganandam ieee80211_queue_work(ar->hw, &arsta->set_4addr_wk); arsta->use_4addr_set = true; } -@@ -6646,6 +6770,9 @@ static int ath11k_mac_op_update_vif_offl +@@ -6647,6 +6771,9 @@ static int ath11k_mac_op_update_vif_offl u32 param_id, param_value; int ret; @@ -224,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 && -@@ -6866,7 +6993,8 @@ static int ath11k_mac_op_add_interface(s +@@ -6867,7 +6994,8 @@ static int ath11k_mac_op_add_interface(s goto err; } @@ -234,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; -@@ -6886,6 +7014,28 @@ static int ath11k_mac_op_add_interface(s +@@ -6887,6 +7015,28 @@ static int ath11k_mac_op_add_interface(s arvif->vif = vif; INIT_LIST_HEAD(&arvif->list); @@ -263,7 +263,7 @@ Signed-off-by: Sathishkumar Muruganandam INIT_DELAYED_WORK(&arvif->connection_loss_work, ath11k_mac_vif_sta_connection_loss_work); -@@ -6915,6 +7065,7 @@ static int ath11k_mac_op_add_interface(s +@@ -6916,6 +7066,7 @@ static int ath11k_mac_op_add_interface(s fallthrough; case NL80211_IFTYPE_AP: arvif->vdev_type = WMI_VDEV_TYPE_AP; @@ -271,7 +271,7 @@ Signed-off-by: Sathishkumar Muruganandam break; case NL80211_IFTYPE_MONITOR: arvif->vdev_type = WMI_VDEV_TYPE_MONITOR; -@@ -7137,13 +7288,30 @@ static void ath11k_mac_op_remove_interfa +@@ -7138,13 +7289,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; @@ -304,7 +304,7 @@ Signed-off-by: Sathishkumar Muruganandam ath11k_dbg(ab, ATH11K_DBG_MAC, "remove interface (vdev %d)\n", arvif->vdev_id); -@@ -7160,6 +7328,14 @@ static void ath11k_mac_op_remove_interfa +@@ -7161,6 +7329,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); @@ -319,7 +319,7 @@ Signed-off-by: Sathishkumar Muruganandam } ret = ath11k_mac_vdev_delete(ar, arvif); -@@ -7203,8 +7379,7 @@ err_vdev_del: +@@ -7204,8 +7380,7 @@ err_vdev_del: ath11k_debugfs_remove_interface(arvif); @@ -329,7 +329,7 @@ Signed-off-by: Sathishkumar Muruganandam mutex_unlock(&ar->conf_mutex); } -@@ -7264,16 +7439,17 @@ static int ath11k_mac_op_ampdu_action(st +@@ -7265,16 +7440,17 @@ static int ath11k_mac_op_ampdu_action(st struct ieee80211_ampdu_params *params) { struct ath11k *ar = hw->priv; @@ -349,7 +349,7 @@ Signed-off-by: Sathishkumar Muruganandam break; case IEEE80211_AMPDU_TX_START: case IEEE80211_AMPDU_TX_STOP_CONT: -@@ -8796,6 +8972,7 @@ static void ath11k_mac_op_sta_statistics +@@ -8797,6 +8973,7 @@ static void ath11k_mac_op_sta_statistics { struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); struct ath11k *ar = arsta->arvif->ar; @@ -357,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); -@@ -8852,7 +9029,8 @@ static void ath11k_mac_op_sta_statistics +@@ -8853,7 +9030,8 @@ static void ath11k_mac_op_sta_statistics ATH11K_DEFAULT_NOISE_FLOOR; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); @@ -380,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 -@@ -1121,12 +1121,13 @@ err_mem_free: +@@ -1156,12 +1156,13 @@ err_mem_free: return ret; } @@ -396,7 +396,7 @@ Signed-off-by: Sathishkumar Muruganandam int ret; ret = ath11k_peer_rx_tid_setup(ar, params->sta->addr, vdev_id, -@@ -1138,13 +1139,13 @@ int ath11k_dp_rx_ampdu_start(struct ath1 +@@ -1173,13 +1174,13 @@ int ath11k_dp_rx_ampdu_start(struct ath1 return ret; } diff --git a/package/kernel/mac80211/patches/nss/ath11k/236-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 index 80b8a5fc67d7ea..e7817f953ace6e 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/236-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 @@ -423,7 +423,7 @@ Signed-off-by: Sathishkumar Muruganandam } } else if (old_state == IEEE80211_STA_AUTHORIZED && new_state == IEEE80211_STA_ASSOC) { -@@ -7018,7 +7247,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7019,7 +7248,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; -@@ -7031,6 +7260,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7032,6 +7261,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; } -@@ -7055,6 +7285,20 @@ static int ath11k_mac_op_add_interface(s +@@ -7056,6 +7286,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: -@@ -7095,7 +7339,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7096,7 +7340,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++; -@@ -7254,7 +7498,7 @@ err_peer_del: +@@ -7255,7 +7499,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 } } -@@ -7265,6 +7509,8 @@ err_vdev_del: +@@ -7266,6 +7510,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); -@@ -7362,6 +7608,7 @@ err_vdev_del: +@@ -7363,6 +7609,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, -@@ -9960,8 +10207,11 @@ static int __ath11k_mac_register(struct +@@ -9961,8 +10208,11 @@ static int __ath11k_mac_register(struct ab->hw_params.bios_sar_capa) ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa; 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 index bbf4f20ac2326c..493ed32105629e 100644 --- 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 @@ -10,7 +10,7 @@ }; --- 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 +@@ -974,6 +974,79 @@ static const struct file_operations fops .llseek = default_llseek, }; @@ -90,7 +90,7 @@ 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 +@@ -1023,6 +1096,8 @@ int ath11k_debugfs_soc_create(struct ath ret = PTR_ERR(ab->debugfs_soc); goto out; } diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 61077309338ffb..c5cd8f20874996 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -33,7 +33,7 @@ Signed-off-by: P Praneesh enum ath11k_hw_rev { --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -340,6 +340,12 @@ static int ath11k_dp_purge_mon_ring(stru +@@ -375,6 +375,12 @@ static int ath11k_dp_purge_mon_ring(stru return -ETIMEDOUT; } @@ -46,7 +46,7 @@ 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, -@@ -1664,7 +1670,7 @@ int ath11k_dp_htt_tlv_iter(struct ath11k +@@ -1699,7 +1705,7 @@ int ath11k_dp_htt_tlv_iter(struct ath11k len -= sizeof(*tlv); if (tlv_len > len) { @@ -55,7 +55,7 @@ Signed-off-by: P Praneesh tlv_tag, ptr - begin, len, tlv_len); return -EINVAL; } -@@ -2454,10 +2460,60 @@ ath11k_dp_rx_h_find_peer(struct ath11k_b +@@ -2561,10 +2567,60 @@ ath11k_dp_rx_h_find_peer(struct ath11k_b return peer; } @@ -117,7 +117,7 @@ Signed-off-by: P Praneesh { bool fill_crypto_hdr; enum hal_encrypt_type enctype; -@@ -2468,9 +2524,13 @@ static void ath11k_dp_rx_h_mpdu(struct a +@@ -2575,9 +2631,13 @@ static void ath11k_dp_rx_h_mpdu(struct a struct rx_attention *rx_attention; u32 err_bitmap; @@ -132,7 +132,7 @@ Signed-off-by: P Praneesh rxcb->is_mcbc = fill_crypto_hdr; if (rxcb->is_mcbc) { -@@ -2481,6 +2541,26 @@ static void ath11k_dp_rx_h_mpdu(struct a +@@ -2588,6 +2648,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) { @@ -159,7 +159,7 @@ Signed-off-by: P Praneesh if (rxcb->is_mcbc) enctype = peer->sec_type_grp; else -@@ -2490,6 +2570,8 @@ static void ath11k_dp_rx_h_mpdu(struct a +@@ -2597,6 +2677,8 @@ static void ath11k_dp_rx_h_mpdu(struct a } spin_unlock_bh(&ar->ab->base_lock); @@ -168,7 +168,7 @@ Signed-off-by: P Praneesh 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 +@@ -2838,7 +2920,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, @@ -178,7 +178,7 @@ Signed-off-by: P Praneesh { struct ath11k_base *ab = ar->ab; struct hal_rx_desc *rx_desc, *lrx_desc; -@@ -2798,8 +2881,13 @@ static int ath11k_dp_rx_process_msdu(str +@@ -2920,8 +3003,13 @@ static int ath11k_dp_rx_process_msdu(str } } @@ -193,7 +193,7 @@ Signed-off-by: P Praneesh rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; -@@ -2814,10 +2902,12 @@ static void ath11k_dp_rx_process_receive +@@ -2936,10 +3024,12 @@ static void ath11k_dp_rx_process_receive struct sk_buff_head *msdu_list, int mac_id) { @@ -206,7 +206,7 @@ Signed-off-by: P Praneesh if (skb_queue_empty(msdu_list)) return; -@@ -2834,7 +2924,12 @@ static void ath11k_dp_rx_process_receive +@@ -2956,7 +3046,12 @@ static void ath11k_dp_rx_process_receive } while ((msdu = __skb_dequeue(msdu_list))) { @@ -220,7 +220,7 @@ Signed-off-by: P Praneesh if (unlikely(ret)) { ath11k_dbg(ab, ATH11K_DBG_DATA, "Unable to process msdu %d", ret); -@@ -2842,7 +2937,10 @@ static void ath11k_dp_rx_process_receive +@@ -2964,7 +3059,10 @@ static void ath11k_dp_rx_process_receive continue; } @@ -232,7 +232,7 @@ Signed-off-by: P Praneesh } } -@@ -2851,11 +2949,12 @@ void ath11k_dp_rx_from_nss(struct ath11k +@@ -2973,11 +3071,12 @@ void ath11k_dp_rx_from_nss(struct ath11k { struct ieee80211_rx_status rx_status = {0}; struct ath11k_skb_rxcb *rxcb; @@ -246,7 +246,7 @@ Signed-off-by: P Praneesh 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 +@@ -4446,6 +4545,7 @@ static int ath11k_dp_rx_h_null_q_desc(st struct ieee80211_rx_status *status, struct sk_buff_head *msdu_list) { @@ -254,7 +254,7 @@ Signed-off-by: P Praneesh 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 +@@ -4495,7 +4595,8 @@ static int ath11k_dp_rx_h_null_q_desc(st } ath11k_dp_rx_h_ppdu(ar, desc, status); @@ -266,7 +266,7 @@ Signed-off-by: P Praneesh --- a/drivers/net/wireless/ath/ath11k/hw.c +++ b/drivers/net/wireless/ath/ath11k/hw.c -@@ -293,6 +293,16 @@ static bool ath11k_hw_ipq8074_rx_desc_ge +@@ -297,6 +297,16 @@ static bool ath11k_hw_ipq8074_rx_desc_ge __le32_to_cpu(desc->u.ipq8074.msdu_start.info2)); } @@ -283,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, -@@ -470,6 +480,16 @@ static bool ath11k_hw_qcn9074_rx_desc_ge +@@ -584,6 +594,16 @@ static bool ath11k_hw_qcn9074_rx_desc_ge __le32_to_cpu(desc->u.qcn9074.msdu_start.info2)); } @@ -300,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, -@@ -1025,6 +1045,7 @@ const struct ath11k_hw_ops qca6390_ops = +@@ -1194,6 +1214,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, @@ -308,7 +308,15 @@ 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, -@@ -1189,6 +1210,7 @@ const struct ath11k_hw_ops ipq5018_ops = +@@ -1242,6 +1263,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, ++ .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, +@@ -1379,6 +1401,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, @@ -318,7 +326,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 -@@ -260,6 +260,7 @@ struct ath11k_hw_ops { +@@ -269,6 +269,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); diff --git a/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch b/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch index 7535883c4763d0..aa7d70c0345c8c 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch @@ -454,7 +454,7 @@ Signed-off-by: P Praneesh ieee80211_free_txskb(ar->hw, skb); return; } -@@ -7622,7 +7632,7 @@ err_vdev_del: +@@ -7623,7 +7633,7 @@ err_vdev_del: idr_for_each(&ar->txmgmt_idr, ath11k_mac_vif_txmgmt_idr_remove, vif); @@ -465,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 -@@ -832,10 +832,22 @@ static ssize_t ath11k_debugfs_dump_soc_d +@@ -833,10 +833,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]); @@ -490,6 +490,15 @@ Signed-off-by: P Praneesh if (len > size) --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -105,7 +105,7 @@ static struct ath11k_hw_params ath11k_hw + .supports_regdb = false, + .fix_l1ss = true, + .credit_flow = false, +- .max_tx_ring = DP_TCL_NUM_RING_MAX, ++ .max_tx_ring = DP_TCL_NUM_RING_MAX + 1, + .hal_params = &ath11k_hw_hal_params_ipq8074, + .supports_dynamic_smps_6ghz = false, + .alloc_cacheable_memory = true, @@ -188,7 +188,6 @@ static struct ath11k_hw_params ath11k_hw .supports_regdb = false, .fix_l1ss = true, @@ -504,10 +513,18 @@ Signed-off-by: P Praneesh .support_fw_mac_sequence = 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, }, { - .name = "qca6390 hw2.0", -@@ -380,6 +381,8 @@ static struct ath11k_hw_params ath11k_hw +@@ -356,7 +357,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, +@@ -381,6 +381,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, @@ -516,7 +533,7 @@ Signed-off-by: P Praneesh }, { .name = "wcn6855 hw2.0", -@@ -2143,6 +2146,9 @@ int ath11k_core_pre_init(struct ath11k_b +@@ -2145,6 +2147,9 @@ int ath11k_core_pre_init(struct ath11k_b if (nss_offload) ab->nss.stats_enabled = 1; 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 index b31809f689548b..1fa2d32aaa33cb 100644 --- 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 @@ -1014,7 +1014,7 @@ Signed-off-by: Vasanthakumar Thiagarajan +#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 { +@@ -1529,15 +1529,29 @@ struct htt_ppdu_stats_usr_cmn_array { struct htt_tx_ppdu_stats_info tx_ppdu_info[]; } __packed; @@ -1046,7 +1046,7 @@ Signed-off-by: Vasanthakumar Thiagarajan #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 +@@ -1444,6 +1444,71 @@ static int ath11k_htt_tlv_ppdu_stats_par return 0; } @@ -1118,7 +1118,7 @@ Signed-off-by: Vasanthakumar Thiagarajan 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 +@@ -1467,6 +1532,9 @@ ath11k_update_per_peer_tx_stats(struct a if (!(usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_RATE))) return; @@ -1128,7 +1128,7 @@ Signed-off-by: Vasanthakumar Thiagarajan 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 +@@ -1600,6 +1668,8 @@ ath11k_update_per_peer_tx_stats(struct a ath11k_debugfs_sta_add_tx_stats(arsta, peer_stats, rate_idx); } @@ -1137,7 +1137,7 @@ Signed-off-by: Vasanthakumar Thiagarajan spin_unlock_bh(&ab->base_lock); rcu_read_unlock(); } -@@ -1685,6 +1755,69 @@ int ath11k_dp_htt_tlv_iter(struct ath11k +@@ -1720,6 +1790,69 @@ int ath11k_dp_htt_tlv_iter(struct ath11k return 0; } @@ -1207,7 +1207,7 @@ Signed-off-by: Vasanthakumar Thiagarajan 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 +@@ -1738,6 +1871,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; @@ -1223,7 +1223,7 @@ Signed-off-by: Vasanthakumar Thiagarajan 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 +@@ -1805,6 +1947,12 @@ static int ath11k_htt_pull_ppdu_stats(st } } @@ -1257,7 +1257,7 @@ Signed-off-by: Vasanthakumar Thiagarajan mutex_unlock(&ar->conf_mutex); } -@@ -9714,6 +9726,28 @@ err_fallback: +@@ -9715,6 +9727,28 @@ err_fallback: return 0; } @@ -1286,7 +1286,7 @@ Signed-off-by: Vasanthakumar Thiagarajan static const struct ieee80211_ops ath11k_ops = { .tx = ath11k_mac_op_tx, .wake_tx_queue = ieee80211_handle_wake_tx_queue, -@@ -9771,6 +9805,9 @@ static const struct ieee80211_ops ath11k +@@ -9772,6 +9806,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, @@ -1296,7 +1296,7 @@ Signed-off-by: Vasanthakumar Thiagarajan }; static void ath11k_mac_update_ch_list(struct ath11k *ar, -@@ -10231,6 +10268,8 @@ static int __ath11k_mac_register(struct +@@ -10232,6 +10269,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); 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 index cb4fba0a2ffdcd..1d7cf5b0e7c585 100644 --- 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 @@ -23,7 +23,7 @@ Signed-off-by: Rameshkumar Sundaram --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -7643,8 +7643,10 @@ err_vdev_del: +@@ -7644,8 +7644,10 @@ err_vdev_del: kfree(arvif->vlan_keyid_map); ath11k_peer_cleanup(ar, arvif->vdev_id); diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index d733219b38aa7f..798ec1973c3fe3 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -1332,6 +1332,7 @@ const struct ath11k_hw_ring_mask ath11k_ +@@ -1573,6 +1573,7 @@ const struct ath11k_hw_ring_mask ath11k_ ATH11K_RX_WBM_REL_RING_MASK_0, }, .reo_status = { diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 3c3e436c75ce41..67781ea0ad2b6b 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -58,7 +58,7 @@ Signed-off-by: Venkateswara Naralasetty 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 -@@ -10154,6 +10154,8 @@ static int __ath11k_mac_register(struct +@@ -10155,6 +10155,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 index 752218e9b8ec26..90adde1baf67db 100644 --- 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 @@ -16,7 +16,7 @@ Signed-off-by: Anilkumar Kolli --- 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 +@@ -6124,12 +6124,23 @@ int ath11k_dp_rx_process_mon_status(stru pmon->mon_ppdu_status = DP_PPDU_STATUS_START; } @@ -43,7 +43,7 @@ Signed-off-by: Anilkumar Kolli 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 +@@ -6453,6 +6464,13 @@ static int ath11k_dp_full_mon_process_rx spin_lock_bh(&pmon->mon_lock); @@ -57,7 +57,7 @@ Signed-off-by: Anilkumar Kolli 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 +@@ -6492,7 +6510,6 @@ static int ath11k_dp_full_mon_process_rx } rx_mon_stats->dest_ppdu_done++; @@ -65,7 +65,7 @@ Signed-off-by: Anilkumar Kolli 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: +@@ -6523,16 +6540,10 @@ reap_status_ring: int ath11k_dp_rx_process_mon_rings(struct ath11k_base *ab, int mac_id, struct napi_struct *napi, int budget) { diff --git a/package/kernel/mac80211/patches/nss/ath11k/336-ath11k-skip-status-ring-entry-processing.patch b/package/kernel/mac80211/patches/nss/ath11k/336-ath11k-skip-status-ring-entry-processing.patch index 0adf26c808aec6..8950e960467e67 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -3660,6 +3660,46 @@ ath11k_dp_rx_mon_update_status_buf_state +@@ -3782,6 +3782,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) { -@@ -3673,6 +3713,7 @@ static int ath11k_dp_rx_reap_mon_status_ +@@ -3795,6 +3835,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; -@@ -3692,8 +3733,7 @@ static int ath11k_dp_rx_reap_mon_status_ +@@ -3814,8 +3855,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; -@@ -3724,18 +3764,43 @@ static int ath11k_dp_rx_reap_mon_status_ +@@ -3846,18 +3886,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) { diff --git a/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch b/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch index f574597dceb969..8e23cd99e747c6 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch @@ -46,7 +46,7 @@ Signed-off-by: Nagarajan Maran --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -396,8 +396,8 @@ int ath11k_dp_rxbufs_replenish(struct at +@@ -431,8 +431,8 @@ int ath11k_dp_rxbufs_replenish(struct at goto fail_free_skb; spin_lock_bh(&rx_ring->idr_lock); @@ -57,7 +57,7 @@ Signed-off-by: Nagarajan Maran spin_unlock_bh(&rx_ring->idr_lock); if (buf_id <= 0) goto fail_dma_unmap; -@@ -3141,6 +3141,16 @@ try_again: +@@ -3263,6 +3263,16 @@ try_again: while (likely(desc = (struct hal_reo_dest_ring *)ath11k_hal_srng_dst_get_next_entry(ab, srng))) { @@ -74,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, -@@ -3171,8 +3181,6 @@ try_again: +@@ -3293,8 +3303,6 @@ try_again: num_buffs_reaped[mac_id]++; diff --git a/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch b/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch index f57faaa465ae76..fe231db61355ea 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch @@ -13,7 +13,7 @@ Signed-off-by: Ramya Gnanasekar --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -2564,7 +2564,8 @@ static void ath11k_dp_rx_h_undecap(struc +@@ -2671,7 +2671,8 @@ static void ath11k_dp_rx_h_undecap(struc ehdr = (struct ethhdr *)msdu->data; /* mac80211 allows fast path only for authorized STA */ 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 index f909ba4a673f69..fd4f0938cdb83b 100644 --- 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 @@ -14,7 +14,7 @@ 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 { +@@ -1501,6 +1501,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 @@ -24,7 +24,7 @@ Signed-off-by: Ramya Gnanasekar 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 +@@ -1323,7 +1323,7 @@ static int ath11k_htt_tlv_ppdu_stats_par struct htt_ppdu_user_stats *user_stats = NULL; int cur_user; u16 peer_id; @@ -33,7 +33,7 @@ Signed-off-by: Ramya Gnanasekar ppdu_info = data; -@@ -1369,6 +1369,8 @@ static int ath11k_htt_tlv_ppdu_stats_par +@@ -1404,6 +1404,8 @@ static int ath11k_htt_tlv_ppdu_stats_par return -EINVAL; } @@ -42,7 +42,7 @@ Signed-off-by: Ramya Gnanasekar 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 +@@ -1415,6 +1417,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)); diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 8adb5448a1564c..fd78090aebc0f0 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -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 -@@ -848,6 +848,18 @@ static ssize_t ath11k_debugfs_dump_soc_d +@@ -849,6 +849,18 @@ static ssize_t ath11k_debugfs_dump_soc_d "\nNSS Transmit Failures: %d\n", atomic_read(&soc_stats->tx_err.nss_tx_fail)); @@ -110,7 +110,7 @@ Signed-off-by: Tamizh Chelvam Raja struct dp_reo_cmd { struct list_head list; struct dp_rx_tid data; -@@ -295,6 +304,12 @@ struct ath11k_dp { +@@ -296,6 +305,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) { -@@ -672,13 +675,50 @@ static int ath11k_dp_rx_pdev_srng_alloc( +@@ -707,13 +710,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); -@@ -724,14 +764,18 @@ static void ath11k_dp_reo_cmd_free(struc +@@ -759,14 +799,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) { -@@ -742,11 +786,17 @@ static void ath11k_dp_reo_cache_flush(st +@@ -777,11 +821,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); -@@ -754,24 +804,21 @@ static void ath11k_dp_reo_cache_flush(st +@@ -789,24 +839,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? */ -@@ -780,6 +827,29 @@ static void ath11k_dp_rx_tid_del_func(st +@@ -815,6 +862,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; -@@ -797,13 +867,20 @@ static void ath11k_dp_rx_tid_del_func(st +@@ -832,13 +902,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); -@@ -819,34 +896,48 @@ free_desc: +@@ -854,34 +931,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/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 index 510fbc2448cee7..1f81a8ef722598 100644 --- 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 @@ -13,7 +13,7 @@ Signed-off-by: Yuvasree Sivasankaran --- 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 +@@ -10142,6 +10142,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); diff --git a/package/kernel/mac80211/patches/nss/ath11k/457-wifi-ath11k-Avoid-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 index c23b6cb3c858b4..55d8063a2403ca 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/457-wifi-ath11k-Avoid-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 -@@ -6090,7 +6090,9 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -6261,7 +6261,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))) { -@@ -6108,7 +6110,6 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -6279,7 +6281,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,7 +67,7 @@ Signed-off-by: Yuvasree Sivasankaran ppdu_info->peer_id = HAL_INVALID_PEERID; hal_status = ath11k_hal_rx_parse_mon_status(ab, ppdu_info, skb); -@@ -6136,6 +6137,7 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -6307,6 +6308,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); 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 index b471fb326a5b48..b2912777fad5d0 100644 --- 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 @@ -26,7 +26,7 @@ Acked-by: Jeff Johnson --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -8221,7 +8221,6 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -8222,7 +8222,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; @@ -34,7 +34,7 @@ Acked-by: Jeff Johnson mutex_lock(&ar->conf_mutex); -@@ -8244,21 +8243,6 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -8245,21 +8244,6 @@ ath11k_mac_op_assign_vif_chanctx(struct goto out; } 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 index 2fb2cdfd429b11..ea08ea8818155d 100644 --- 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 @@ -39,7 +39,7 @@ Acked-by: Jeff Johnson if (ret) { ath11k_warn(ab, "failed to delay vdev start: %d\n", ret); goto free_tx_stats; -@@ -8164,8 +8164,8 @@ unlock: +@@ -8165,8 +8165,8 @@ unlock: mutex_unlock(&ar->conf_mutex); } 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 index 4d83d0f0ed9029..a2ff42ad9d194d 100644 --- 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 @@ -317,7 +317,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) -@@ -9739,6 +9461,281 @@ ath11k_mac_op_config_mesh_offload_path(s +@@ -9740,6 +9462,281 @@ ath11k_mac_op_config_mesh_offload_path(s } #endif 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 index d1b462519c91e8..aeaf65aaa0e73b 100644 --- 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 @@ -52,7 +52,7 @@ Acked-by: Jeff Johnson --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -7933,6 +7933,30 @@ static int ath11k_mac_start_vdev_delay(s +@@ -7934,6 +7934,30 @@ static int ath11k_mac_start_vdev_delay(s return 0; } @@ -83,7 +83,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -@@ -7977,15 +8001,17 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -7978,15 +8002,17 @@ ath11k_mac_op_assign_vif_chanctx(struct goto out; } @@ -109,7 +109,7 @@ Acked-by: Jeff Johnson if (arvif->vdev_type != WMI_VDEV_TYPE_MONITOR && test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags)) { -@@ -8025,8 +8051,6 @@ ath11k_mac_op_unassign_vif_chanctx(struc +@@ -8026,8 +8052,6 @@ ath11k_mac_op_unassign_vif_chanctx(struc "chanctx unassign ptr %p vdev_id %i\n", ctx, arvif->vdev_id); @@ -118,7 +118,7 @@ Acked-by: Jeff Johnson if (ab->hw_params.vdev_start_delay && arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { spin_lock_bh(&ab->base_lock); -@@ -8050,24 +8074,13 @@ ath11k_mac_op_unassign_vif_chanctx(struc +@@ -8051,24 +8075,13 @@ ath11k_mac_op_unassign_vif_chanctx(struc return; } @@ -149,7 +149,7 @@ Acked-by: Jeff Johnson } if (ab->hw_params.vdev_start_delay && -@@ -9555,6 +9568,46 @@ exit: +@@ -9556,6 +9569,46 @@ exit: return ret; } @@ -196,7 +196,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, -@@ -9590,31 +9643,15 @@ static int ath11k_mac_op_sta_state(struc +@@ -9591,31 +9644,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)) { @@ -233,7 +233,7 @@ Acked-by: Jeff Johnson 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); -@@ -9625,12 +9662,6 @@ static int ath11k_mac_op_sta_state(struc +@@ -9626,12 +9663,6 @@ static int ath11k_mac_op_sta_state(struc } spin_unlock_bh(&ar->ab->base_lock); mutex_unlock(&ar->ab->tbl_mtx_lock); @@ -246,7 +246,7 @@ Acked-by: Jeff Johnson } 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 +@@ -10203,6 +10234,8 @@ static int __ath11k_mac_register(struct wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); 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 index 2362820dc9e838..06f5e62c7b103c 100644 --- 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 @@ -40,7 +40,7 @@ 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 +@@ -1877,7 +1877,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); @@ -120,7 +120,7 @@ &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 +@@ -1758,8 +1758,10 @@ ath11k_update_per_peer_tx_stats(struct a peer_stats->mu_pos = mu_pos; peer_stats->ru_tones = arsta->txrate.he_ru_alloc; @@ -131,7 +131,7 @@ } usr_stats->rate_stats_updated = true; -@@ -2170,7 +2172,9 @@ void ath11k_dp_htt_htc_t2h_msg_handler(s +@@ -2205,7 +2207,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: @@ -176,7 +176,7 @@ spin_unlock_bh(&ab->base_lock); --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -9812,7 +9812,7 @@ static const struct ieee80211_ops ath11k +@@ -9813,7 +9813,7 @@ static const struct ieee80211_ops ath11k .set_wakeup = ath11k_wow_op_set_wakeup, #endif From 10a14c09e84a06aeacc7d3742be701f44bcd7b55 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 9 Mar 2024 11:15:21 -0500 Subject: [PATCH 126/225] ath11k_nss: Set correct pbufs for 1GB profile --- package/kernel/mac80211/files/qca-nss-pbuf.init | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/kernel/mac80211/files/qca-nss-pbuf.init b/package/kernel/mac80211/files/qca-nss-pbuf.init index f4f45b9a4a4c60..c6d6b8b2238074 100755 --- a/package/kernel/mac80211/files/qca-nss-pbuf.init +++ b/package/kernel/mac80211/files/qca-nss-pbuf.init @@ -105,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 | \ @@ -115,12 +115,12 @@ 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 } From 102e65c43128691a488a29b864635d631d8630cc Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 9 Mar 2024 11:17:51 -0500 Subject: [PATCH 127/225] qualcommax: remove uneeded macsec/btcoex dts not needed for NSS offload and helps save some memory --- .../patches-6.1/9999-add-btcoex-dts.patch | 30 ------------------- .../patches-6.1/9999-add-nss-macsec.patch | 13 -------- 2 files changed, 43 deletions(-) delete mode 100644 target/linux/qualcommax/patches-6.1/9999-add-btcoex-dts.patch delete mode 100644 target/linux/qualcommax/patches-6.1/9999-add-nss-macsec.patch diff --git a/target/linux/qualcommax/patches-6.1/9999-add-btcoex-dts.patch b/target/linux/qualcommax/patches-6.1/9999-add-btcoex-dts.patch deleted file mode 100644 index 83825b782c1b7f..00000000000000 --- a/target/linux/qualcommax/patches-6.1/9999-add-btcoex-dts.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- linux-6.1.71/arch/arm64/boot/dts/qcom/ipq8074.dtsi 2024-01-07 01:44:56.908138962 -0500 -+++ linux-6.1.71/arch/arm64/boot/dts/qcom/ipq8074.dtsi 2024-01-07 01:44:58.908138962 -0500 -@@ -1170,7 +1170,14 @@ - wifi: wifi@c0000000 { - compatible = "qcom,ipq8074-wifi"; - reg = <0xc000000 0x2000000>; -- -+ qcom,hw-mode-id = <1>; -+ #ifdef __IPQ_MEM_PROFILE_256_MB__ -+ qcom,tgt-mem-mode = <2>; -+ #elif __IPQ_MEM_PROFILE_512_MB__ -+ qcom,tgt-mem-mode = <1>; -+ #else -+ qcom,tgt-mem-mode = <0>; -+ #endif - interrupts = , - , - , -@@ -1276,6 +1283,12 @@ - "tcl2host-status-ring"; - qcom,rproc = <&q6v5_wcss>; - status = "disabled"; -+ qcom,pta-num = <0>; -+ qcom,coex-mode = <0x2>; -+ qcom,bt-active-time = <0x12>; -+ qcom,bt-priority-time = <0x0c>; -+ qcom,coex-algo = <0x2>; -+ qcom,pta-priority = <0x80800505>; - }; - }; diff --git a/target/linux/qualcommax/patches-6.1/9999-add-nss-macsec.patch b/target/linux/qualcommax/patches-6.1/9999-add-nss-macsec.patch deleted file mode 100644 index 1be086be21789f..00000000000000 --- a/target/linux/qualcommax/patches-6.1/9999-add-nss-macsec.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi 2024-01-08 16:04:51.957322224 -0500 -+++ b/arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi 2024-01-08 16:09:29.079630738 -0500 -@@ -268,4 +268,10 @@ - }; - }; - }; -+ nss-macsec1 { -+ compatible = "qcom,nss-macsec"; -+ phy_addr = <0x1c>; -+ phy_access_mode = <0x00>; -+ mdiobus = <&mdio>; -+ }; - }; From 32859e658adcbfc4dd7fcd3340ad70abd7ebf086 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 9 Mar 2024 11:31:54 -0500 Subject: [PATCH 128/225] ath11k_nss: Revert setting fw_mem_mode for IPQ807x Leave it set to '0', as it will kernel panic with 2K skb patch. This flag was incorrectly assumed to save memory on 1G platforms. --- .../ath11k/207-ath11k-Enable-256_512MB-profiles.patch | 9 --------- 1 file changed, 9 deletions(-) diff --git a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch index d89b500015fc33..4d9c1537a8bb4b 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch @@ -228,15 +228,6 @@ Signed-off-by: Ramya Gnanasekar static struct ath11k_hw_params ath11k_hw_params[] = { { .hw_rev = ATH11K_HW_IPQ8074, -@@ -95,7 +97,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, @@ -127,6 +129,7 @@ static struct ath11k_hw_params ath11k_hw .tcl_ring_retry = true, .tx_ring_size = DP_TCL_DATA_RING_SIZE, From 4633f58db60867e5a678aa4cdc825da1be14583c Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 9 Mar 2024 11:39:37 -0500 Subject: [PATCH 129/225] ath11k_nss: remove leftover max_tx_ring it was not removed when applying patch to replace it with 'max_tx_ring = DP_TCL_NUM_RING_MAX +1' --- .../patches/nss/ath11k/244-ath11k-dp-tx-perf.patch | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch b/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch index 7535883c4763d0..1c9a6ebd1d41ac 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch @@ -507,7 +507,15 @@ Signed-off-by: P Praneesh }, { .name = "qca6390 hw2.0", -@@ -380,6 +381,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, @@ -516,7 +524,7 @@ Signed-off-by: P Praneesh }, { .name = "wcn6855 hw2.0", -@@ -2143,6 +2146,9 @@ int ath11k_core_pre_init(struct ath11k_b +@@ -2143,6 +2145,9 @@ int ath11k_core_pre_init(struct ath11k_b if (nss_offload) ab->nss.stats_enabled = 1; From 94b220a0bab9a12617ad98f058eea78dee5a726e Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 9 Mar 2024 11:45:32 -0500 Subject: [PATCH 130/225] ath11k_nss: Import bugfix patches --- ...ix-mutex-dead-lock-and-q6-dump-crash.patch | 59 ++++ ...agement-frames-to-firmware-before-wa.patch | 43 +++ ...a_map_single-to-virt_to_phys-in-rx-r.patch | 66 +++++ .../999-336-0002-ath11k-Use-idr_replace.patch | 264 ++++++++++++++++++ 4 files changed, 432 insertions(+) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/401-ath11k-Fix-mutex-dead-lock-and-q6-dump-crash.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/453-ath11k-flush-management-frames-to-firmware-before-wa.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/669-ath11k-change-dma_map_single-to-virt_to_phys-in-rx-r.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/999-336-0002-ath11k-Use-idr_replace.patch 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 00000000000000..1f66f72a4a4851 --- /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 +@@ -8001,7 +8001,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 +@@ -2960,6 +2960,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 00000000000000..7d413afec97b3d --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/453-ath11k-flush-management-frames-to-firmware-before-wa.patch @@ -0,0 +1,43 @@ +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(+) + +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index 28c9908ef816..dbdb7aa5c498 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -10266,6 +10266,8 @@ static int ath11k_mac_flush_tx_complete(struct ath11k *ar) + 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); +-- +2.7.4 + 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 00000000000000..fe767b6a33de2a --- /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 +@@ -427,9 +427,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; + +@@ -465,8 +465,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/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 00000000000000..c2cc4f2f89f43e --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/999-336-0002-ath11k-Use-idr_replace.patch @@ -0,0 +1,264 @@ +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; + } + +@@ -3346,11 +3365,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]; + +@@ -3383,8 +3405,16 @@ 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_find(&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", + buf_id); +@@ -3464,9 +3494,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; + } + +@@ -4831,7 +4864,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; +@@ -5047,14 +5080,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]; + +@@ -5129,7 +5165,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(); +@@ -5151,6 +5187,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; + } + +@@ -5238,7 +5276,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; + } +@@ -6184,12 +6222,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); + } + } + +@@ -6701,7 +6739,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), From 497a91689994e0ea8af5d0b52b033517ac6be94e Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 9 Mar 2024 11:59:20 -0500 Subject: [PATCH 131/225] ath11k_nss: Introduce skbuff_recycle for performance QSDK NSS builds utilize skbuff recycling for better handling of memory. On a Dynalink DL-WRX36 (pbuf script should be set to 'auto') a significant drop in memory usage was observed as well consistent sustained RX/TX speeds. BEFORE: echo 3 >! /proc/sys/vm/drop_caches free -m total used free shared buff/cache available Mem: 867 338 547 90 101 528 Swap: 0 0 0 AFTER: total used free shared buff/cache available Mem: 867 242 594 1 81 624 Swap: 0 0 0 NOTE: For 512MB platforms, users need to test with the following scenarios, as the patch `999-233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch` is really only testable on platforms with 512M or less RAM. 1.) Explicitly setting 'ATH11K_MEM_PROFILE_512M' on and see if system crashes on boot. 2.) Explicitly setting 'ATH11K_MEM_PROFILE_1G' 3.) Remove patches 999-233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch 999-311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch And re-test with #1 and #2 It was incorrectly assumed that setting a 512M for 1G platforms would save memory, instead it needs to be explicitly set to know proper memory regions, otherwise it would cause fw crash. --- package/kernel/mac80211/Makefile | 2 +- package/kernel/mac80211/ath.mk | 1 - ...207-ath11k-Enable-256_512MB-profiles.patch | 32 +- ...pport-for-WDS-offload-in-NSS-offload.patch | 24 +- ...-dynamic-VLAN-support-in-NSS-offload.patch | 16 +- ...ow-fast-rx-by-bypassing-stats-update.patch | 6 +- ...ow-fast-rx-by-bypassing-stats-update.patch | 46 +- .../nss/ath11k/244-ath11k-dp-tx-perf.patch | 14 +- .../300-ath11k-nss-mesh-offload-support.patch | 20 +- ...lookup-failure-in-mgmt-tx-completion.patch | 2 +- ...e-free-of-peer-rx_tid-during-reo-cmd.patch | 2 +- ...TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch | 2 +- ...ing-rx-stats-with-monitor-vif-enable.patch | 8 +- ...1k-skip-status-ring-entry-processing.patch | 8 +- ...356-ath11k-invalid-desc-sanity-check.patch | 6 +- ...-fix-tkip-encryption-traffic-failure.patch | 2 +- ...Fix-ppdu_id-from-firmware-PPDU-stats.patch | 8 +- ...Add-retry-mechanism-for-update_rx_qu.patch | 18 +- ...th11k-Advertise-TX_QUEUE-mac-hw-flag.patch | 2 +- ...oid-memset-of-ppdu-info-for-next-skb.patch | 6 +- ...11k-remove-invalid-peer-create-logic.patch | 4 +- ...th11k-rename-ath11k_start_vdev_delay.patch | 2 +- ...ation-of-ath11k_mac_start_vdev_delay.patch | 2 +- ...ailure-due-to-unexpected-peer-delete.patch | 16 +- ...k-make-debugfs-sta-htt-stats-modular.patch | 8 +- ...1k-Disable-rx_header-tlv-for-2K-SKB.patch} | 154 ++-- ...-nss-thread-priority-during-pdev_ini.patch | 109 +++ target/linux/qualcommax/config-6.1 | 5 + .../qualcommax/files/net/core/skbuff_debug.c | 332 ++++++++ .../qualcommax/files/net/core/skbuff_debug.h | 53 ++ .../files/net/core/skbuff_notifier.c | 42 + .../files/net/core/skbuff_notifier.h | 52 ++ .../files/net/core/skbuff_recycle.c | 729 ++++++++++++++++++ .../files/net/core/skbuff_recycle.h | 178 +++++ ...f-cache-for-skb-data-for-LM-profiles.patch | 69 ++ ...-Cache-for-skb-data-for-all-profiles.patch | 91 +++ ...0-0367-Generic-rx-to-rx-skb-recycler.patch | 207 +++++ ...debug-track-functions-that-free-SKBs.patch | 51 ++ ...ebug-objects-to-track-skb-allocation.patch | 126 +++ ...debug-move-activate-deactivate-sites.patch | 75 ++ ...track-alloc-and-free-complete-stacks.patch | 28 + ...ug-track-sum-of-skb-while-not-in-use.patch | 29 + .../9990-0376-Add-notifier-interface.patch | 116 +++ ...sk_buff-head-is-valid-in-consume_skb.patch | 51 ++ ...-page-frag-allocations-for-SKB-for-2.patch | 69 ++ ...ption-check-to-enable-skb-recycler-c.patch | 54 ++ ...ompile-error-when-recycler-is-disabl.patch | 32 + ...kb-while-dequeuing-from-backlog-list.patch | 31 + ...kb-allocation-to-allocate-the-skbs-f.patch | 158 ++++ ...he-crash-in-skbuff.c-for-debug-build.patch | 26 + ...h-due-to-missing-skb-debug-deactivat.patch | 57 ++ 51 files changed, 2945 insertions(+), 236 deletions(-) rename package/kernel/mac80211/patches/nss/ath11k/{233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch => 999-233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch} (88%) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/999-311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch create mode 100644 target/linux/qualcommax/files/net/core/skbuff_debug.c create mode 100644 target/linux/qualcommax/files/net/core/skbuff_debug.h create mode 100644 target/linux/qualcommax/files/net/core/skbuff_notifier.c create mode 100644 target/linux/qualcommax/files/net/core/skbuff_notifier.h create mode 100644 target/linux/qualcommax/files/net/core/skbuff_recycle.c create mode 100644 target/linux/qualcommax/files/net/core/skbuff_recycle.h create mode 100644 target/linux/qualcommax/patches-6.1/9990-0272-net-skbuff-cache-for-skb-data-for-LM-profiles.patch create mode 100644 target/linux/qualcommax/patches-6.1/9990-0273-net-skbuff-Cache-for-skb-data-for-all-profiles.patch create mode 100644 target/linux/qualcommax/patches-6.1/9990-0367-Generic-rx-to-rx-skb-recycler.patch create mode 100644 target/linux/qualcommax/patches-6.1/9990-0368-skbuff_debug-track-functions-that-free-SKBs.patch create mode 100644 target/linux/qualcommax/patches-6.1/9990-0369-net-skbuff-use-debug-objects-to-track-skb-allocation.patch create mode 100644 target/linux/qualcommax/patches-6.1/9990-0373-skbuff_debug-move-activate-deactivate-sites.patch create mode 100644 target/linux/qualcommax/patches-6.1/9990-0374-skbuff_debug-track-alloc-and-free-complete-stacks.patch create mode 100644 target/linux/qualcommax/patches-6.1/9990-0375-skbuff_debug-track-sum-of-skb-while-not-in-use.patch create mode 100644 target/linux/qualcommax/patches-6.1/9990-0376-Add-notifier-interface.patch create mode 100644 target/linux/qualcommax/patches-6.1/9990-0377-net-Check-if-sk_buff-head-is-valid-in-consume_skb.patch create mode 100644 target/linux/qualcommax/patches-6.1/9990-0378-net-core-Disable-page-frag-allocations-for-SKB-for-2.patch create mode 100644 target/linux/qualcommax/patches-6.1/9990-0422-net-Fix-kernel-option-check-to-enable-skb-recycler-c.patch create mode 100644 target/linux/qualcommax/patches-6.1/9990-0429-net-skbuff-Fix-compile-error-when-recycler-is-disabl.patch create mode 100644 target/linux/qualcommax/patches-6.1/9990-0444-net-prefetch-skb-while-dequeuing-from-backlog-list.patch create mode 100644 target/linux/qualcommax/patches-6.1/9990-0498-skbuff-Fix-the-skb-allocation-to-allocate-the-skbs-f.patch create mode 100644 target/linux/qualcommax/patches-6.1/9990-0527-net-Fix-the-crash-in-skbuff.c-for-debug-build.patch create mode 100644 target/linux/qualcommax/patches-6.1/9990-0558-net-Fix-the-crash-due-to-missing-skb-debug-deactivat.patch diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 7fbcfdb841a199..a9a984adbc36ad 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 PKG_VERSION:=6.6.15 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/ PKG_HASH:=3bbc461121134fda9089c084a5eed577d05e7837a157edf9a3797937172a3ece diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk index 574a3e2424dc90..ba76c0125a910b 100644 --- a/package/kernel/mac80211/ath.mk +++ b/package/kernel/mac80211/ath.mk @@ -70,7 +70,6 @@ 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-$(CONFIG_ATH11K_NSS_MESH_SUPPORT) += ATH11K_NSS_MESH_SUPPORT config-$(call config_package,ath9k-htc) += ATH9K_HTC config-$(call config_package,ath10k,regular) += ATH10K ATH10K_PCI diff --git a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch index 75e0bf1b79b844..4d9c1537a8bb4b 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch @@ -245,15 +245,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = false, -@@ -210,6 +213,7 @@ 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, - }, - { - .name = "qca6390 hw2.0", -@@ -259,7 +263,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, @@ -262,7 +254,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -426,7 +430,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, @@ -271,7 +263,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -462,6 +466,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, @@ -279,7 +271,7 @@ Signed-off-by: Ramya Gnanasekar }, { .name = "wcn6855 hw2.1", -@@ -509,7 +514,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -509,7 +513,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -288,7 +280,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -545,6 +550,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, @@ -296,7 +288,7 @@ Signed-off-by: Ramya Gnanasekar }, { .name = "wcn6750 hw1.0", -@@ -593,7 +599,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -593,7 +598,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = true, .coldboot_cal_ftm = true, .cbcal_restart_fw = false, @@ -305,15 +297,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = false, -@@ -626,6 +632,7 @@ static struct ath11k_hw_params ath11k_hw - .tx_ring_size = DP_TCL_DATA_RING_SIZE_WCN6750, - .smp2p_wow_exit = true, - .support_fw_mac_sequence = true, -+ .num_vdevs_peers = ath11k_vdevs_peers, - }, - { - .hw_rev = ATH11K_HW_IPQ5018_HW10, -@@ -672,7 +679,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, @@ -322,7 +306,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_regdb = false, -@@ -707,6 +714,22 @@ static struct ath11k_hw_params ath11k_hw +@@ -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, diff --git a/package/kernel/mac80211/patches/nss/ath11k/235-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 index 10e65157232edb..729ee80199b9a2 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/235-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 @@ -214,7 +214,7 @@ Signed-off-by: Sathishkumar Muruganandam ieee80211_queue_work(ar->hw, &arsta->set_4addr_wk); arsta->use_4addr_set = true; } -@@ -6647,6 +6771,9 @@ static int ath11k_mac_op_update_vif_offl +@@ -6646,6 +6770,9 @@ static int ath11k_mac_op_update_vif_offl u32 param_id, param_value; int ret; @@ -224,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 && -@@ -6867,7 +6994,8 @@ static int ath11k_mac_op_add_interface(s +@@ -6866,7 +6993,8 @@ static int ath11k_mac_op_add_interface(s goto err; } @@ -234,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; -@@ -6887,6 +7015,28 @@ static int ath11k_mac_op_add_interface(s +@@ -6886,6 +7014,28 @@ static int ath11k_mac_op_add_interface(s arvif->vif = vif; INIT_LIST_HEAD(&arvif->list); @@ -263,7 +263,7 @@ Signed-off-by: Sathishkumar Muruganandam INIT_DELAYED_WORK(&arvif->connection_loss_work, ath11k_mac_vif_sta_connection_loss_work); -@@ -6916,6 +7066,7 @@ static int ath11k_mac_op_add_interface(s +@@ -6915,6 +7065,7 @@ static int ath11k_mac_op_add_interface(s fallthrough; case NL80211_IFTYPE_AP: arvif->vdev_type = WMI_VDEV_TYPE_AP; @@ -271,7 +271,7 @@ Signed-off-by: Sathishkumar Muruganandam break; case NL80211_IFTYPE_MONITOR: arvif->vdev_type = WMI_VDEV_TYPE_MONITOR; -@@ -7138,13 +7289,30 @@ static void ath11k_mac_op_remove_interfa +@@ -7137,13 +7288,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; @@ -304,7 +304,7 @@ Signed-off-by: Sathishkumar Muruganandam ath11k_dbg(ab, ATH11K_DBG_MAC, "remove interface (vdev %d)\n", arvif->vdev_id); -@@ -7161,6 +7329,14 @@ static void ath11k_mac_op_remove_interfa +@@ -7160,6 +7328,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); @@ -319,7 +319,7 @@ Signed-off-by: Sathishkumar Muruganandam } ret = ath11k_mac_vdev_delete(ar, arvif); -@@ -7204,8 +7380,7 @@ err_vdev_del: +@@ -7203,8 +7379,7 @@ err_vdev_del: ath11k_debugfs_remove_interface(arvif); @@ -329,7 +329,7 @@ Signed-off-by: Sathishkumar Muruganandam mutex_unlock(&ar->conf_mutex); } -@@ -7265,16 +7440,17 @@ static int ath11k_mac_op_ampdu_action(st +@@ -7264,16 +7439,17 @@ static int ath11k_mac_op_ampdu_action(st struct ieee80211_ampdu_params *params) { struct ath11k *ar = hw->priv; @@ -349,7 +349,7 @@ Signed-off-by: Sathishkumar Muruganandam break; case IEEE80211_AMPDU_TX_START: case IEEE80211_AMPDU_TX_STOP_CONT: -@@ -8797,6 +8973,7 @@ static void ath11k_mac_op_sta_statistics +@@ -8796,6 +8972,7 @@ static void ath11k_mac_op_sta_statistics { struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); struct ath11k *ar = arsta->arvif->ar; @@ -357,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); -@@ -8853,7 +9030,8 @@ static void ath11k_mac_op_sta_statistics +@@ -8852,7 +9029,8 @@ static void ath11k_mac_op_sta_statistics ATH11K_DEFAULT_NOISE_FLOOR; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); @@ -380,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 -@@ -1156,12 +1156,13 @@ err_mem_free: +@@ -1121,12 +1121,13 @@ err_mem_free: return ret; } @@ -396,7 +396,7 @@ Signed-off-by: Sathishkumar Muruganandam int ret; ret = ath11k_peer_rx_tid_setup(ar, params->sta->addr, vdev_id, -@@ -1173,13 +1174,13 @@ int ath11k_dp_rx_ampdu_start(struct ath1 +@@ -1138,13 +1139,13 @@ int ath11k_dp_rx_ampdu_start(struct ath1 return ret; } diff --git a/package/kernel/mac80211/patches/nss/ath11k/236-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 index e7817f953ace6e..80b8a5fc67d7ea 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/236-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 @@ -423,7 +423,7 @@ Signed-off-by: Sathishkumar Muruganandam } } else if (old_state == IEEE80211_STA_AUTHORIZED && new_state == IEEE80211_STA_ASSOC) { -@@ -7019,7 +7248,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7018,7 +7247,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; -@@ -7032,6 +7261,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7031,6 +7260,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; } -@@ -7056,6 +7286,20 @@ static int ath11k_mac_op_add_interface(s +@@ -7055,6 +7285,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: -@@ -7096,7 +7340,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7095,7 +7339,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++; -@@ -7255,7 +7499,7 @@ err_peer_del: +@@ -7254,7 +7498,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 } } -@@ -7266,6 +7510,8 @@ err_vdev_del: +@@ -7265,6 +7509,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); -@@ -7363,6 +7609,7 @@ err_vdev_del: +@@ -7362,6 +7608,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, -@@ -9961,8 +10208,11 @@ static int __ath11k_mac_register(struct +@@ -9960,8 +10207,11 @@ static int __ath11k_mac_register(struct ab->hw_params.bios_sar_capa) ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa; 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 index 493ed32105629e..0362ff8caa5d0e 100644 --- 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 @@ -4,13 +4,13 @@ u32 max_ast_index; u32 num_ast_entries; -+ bool stats_disable; ++ 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 -@@ -974,6 +974,79 @@ static const struct file_operations fops +@@ -973,6 +973,79 @@ static const struct file_operations fops .llseek = default_llseek, }; @@ -90,7 +90,7 @@ int ath11k_debugfs_pdev_create(struct ath11k_base *ab) { if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) -@@ -1023,6 +1096,8 @@ int ath11k_debugfs_soc_create(struct ath +@@ -1022,6 +1095,8 @@ int ath11k_debugfs_soc_create(struct ath ret = PTR_ERR(ab->debugfs_soc); goto out; } diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index c5cd8f20874996..61077309338ffb 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -33,7 +33,7 @@ Signed-off-by: P Praneesh enum ath11k_hw_rev { --- 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; } @@ -46,7 +46,7 @@ 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, -@@ -1699,7 +1705,7 @@ int ath11k_dp_htt_tlv_iter(struct ath11k +@@ -1664,7 +1670,7 @@ int ath11k_dp_htt_tlv_iter(struct ath11k len -= sizeof(*tlv); if (tlv_len > len) { @@ -55,7 +55,7 @@ Signed-off-by: P Praneesh tlv_tag, ptr - begin, len, tlv_len); return -EINVAL; } -@@ -2561,10 +2567,60 @@ ath11k_dp_rx_h_find_peer(struct ath11k_b +@@ -2454,10 +2460,60 @@ ath11k_dp_rx_h_find_peer(struct ath11k_b return peer; } @@ -117,7 +117,7 @@ Signed-off-by: P Praneesh { bool fill_crypto_hdr; enum hal_encrypt_type enctype; -@@ -2575,9 +2631,13 @@ 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; @@ -132,7 +132,7 @@ Signed-off-by: P Praneesh rxcb->is_mcbc = fill_crypto_hdr; if (rxcb->is_mcbc) { -@@ -2588,6 +2648,26 @@ static void ath11k_dp_rx_h_mpdu(struct a +@@ -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) { @@ -159,7 +159,7 @@ Signed-off-by: P Praneesh if (rxcb->is_mcbc) enctype = peer->sec_type_grp; else -@@ -2597,6 +2677,8 @@ static void ath11k_dp_rx_h_mpdu(struct a +@@ -2490,6 +2570,8 @@ static void ath11k_dp_rx_h_mpdu(struct a } spin_unlock_bh(&ar->ab->base_lock); @@ -168,7 +168,7 @@ Signed-off-by: P Praneesh 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) -@@ -2838,7 +2920,8 @@ static void ath11k_dp_rx_deliver_msdu(st +@@ -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, @@ -178,7 +178,7 @@ Signed-off-by: P Praneesh { struct ath11k_base *ab = ar->ab; struct hal_rx_desc *rx_desc, *lrx_desc; -@@ -2920,8 +3003,13 @@ static int ath11k_dp_rx_process_msdu(str +@@ -2798,8 +2881,13 @@ static int ath11k_dp_rx_process_msdu(str } } @@ -193,7 +193,7 @@ Signed-off-by: P Praneesh rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; -@@ -2936,10 +3024,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) { @@ -206,7 +206,7 @@ Signed-off-by: P Praneesh if (skb_queue_empty(msdu_list)) return; -@@ -2956,7 +3046,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))) { @@ -220,7 +220,7 @@ Signed-off-by: P Praneesh if (unlikely(ret)) { ath11k_dbg(ab, ATH11K_DBG_DATA, "Unable to process msdu %d", ret); -@@ -2964,7 +3059,10 @@ static void ath11k_dp_rx_process_receive +@@ -2842,7 +2937,10 @@ static void ath11k_dp_rx_process_receive continue; } @@ -232,7 +232,7 @@ Signed-off-by: P Praneesh } } -@@ -2973,11 +3071,12 @@ void ath11k_dp_rx_from_nss(struct ath11k +@@ -2851,11 +2949,12 @@ void ath11k_dp_rx_from_nss(struct ath11k { struct ieee80211_rx_status rx_status = {0}; struct ath11k_skb_rxcb *rxcb; @@ -246,7 +246,7 @@ Signed-off-by: P Praneesh rx_status.flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; -@@ -4446,6 +4545,7 @@ static int ath11k_dp_rx_h_null_q_desc(st +@@ -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) { @@ -254,7 +254,7 @@ Signed-off-by: P Praneesh u16 msdu_len; struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; struct rx_attention *rx_attention; -@@ -4495,7 +4595,8 @@ static int ath11k_dp_rx_h_null_q_desc(st +@@ -4371,7 +4471,8 @@ static int ath11k_dp_rx_h_null_q_desc(st } ath11k_dp_rx_h_ppdu(ar, desc, status); @@ -266,7 +266,7 @@ Signed-off-by: P Praneesh --- a/drivers/net/wireless/ath/ath11k/hw.c +++ b/drivers/net/wireless/ath/ath11k/hw.c -@@ -297,6 +297,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)); } @@ -283,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, -@@ -584,6 +594,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)); } @@ -300,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, -@@ -1194,6 +1214,7 @@ const struct ath11k_hw_ops ipq6018_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, @@ -308,15 +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, -@@ -1242,6 +1263,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, -+ .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, -@@ -1379,6 +1401,7 @@ const struct ath11k_hw_ops wcn6750_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, @@ -326,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 -@@ -269,6 +269,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); diff --git a/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch b/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch index f514843b447f1a..1c9a6ebd1d41ac 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch @@ -454,7 +454,7 @@ Signed-off-by: P Praneesh ieee80211_free_txskb(ar->hw, skb); return; } -@@ -7623,7 +7633,7 @@ err_vdev_del: +@@ -7622,7 +7632,7 @@ err_vdev_del: idr_for_each(&ar->txmgmt_idr, ath11k_mac_vif_txmgmt_idr_remove, vif); @@ -465,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]); @@ -490,15 +490,6 @@ Signed-off-by: P Praneesh if (len > size) --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c -@@ -105,7 +105,7 @@ static struct ath11k_hw_params ath11k_hw - .supports_regdb = false, - .fix_l1ss = true, - .credit_flow = false, -- .max_tx_ring = DP_TCL_NUM_RING_MAX, -+ .max_tx_ring = DP_TCL_NUM_RING_MAX + 1, - .hal_params = &ath11k_hw_hal_params_ipq8074, - .supports_dynamic_smps_6ghz = false, - .alloc_cacheable_memory = true, @@ -188,7 +188,6 @@ static struct ath11k_hw_params ath11k_hw .supports_regdb = false, .fix_l1ss = true, @@ -513,7 +504,6 @@ Signed-off-by: P Praneesh .support_fw_mac_sequence = 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, }, { .name = "qca6390 hw2.0", 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 index 1fa2d32aaa33cb..b31809f689548b 100644 --- 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 @@ -1014,7 +1014,7 @@ Signed-off-by: Vasanthakumar Thiagarajan +#endif --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h -@@ -1529,15 +1529,29 @@ struct htt_ppdu_stats_usr_cmn_array { +@@ -1453,15 +1453,29 @@ struct htt_ppdu_stats_usr_cmn_array { struct htt_tx_ppdu_stats_info tx_ppdu_info[]; } __packed; @@ -1046,7 +1046,7 @@ Signed-off-by: Vasanthakumar Thiagarajan #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 -@@ -1444,6 +1444,71 @@ static int ath11k_htt_tlv_ppdu_stats_par +@@ -1409,6 +1409,71 @@ static int ath11k_htt_tlv_ppdu_stats_par return 0; } @@ -1118,7 +1118,7 @@ Signed-off-by: Vasanthakumar Thiagarajan static void ath11k_update_per_peer_tx_stats(struct ath11k *ar, struct htt_ppdu_stats *ppdu_stats, u8 user) -@@ -1467,6 +1532,9 @@ ath11k_update_per_peer_tx_stats(struct a +@@ -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; @@ -1128,7 +1128,7 @@ Signed-off-by: Vasanthakumar Thiagarajan 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); -@@ -1600,6 +1668,8 @@ ath11k_update_per_peer_tx_stats(struct a +@@ -1565,6 +1633,8 @@ ath11k_update_per_peer_tx_stats(struct a ath11k_debugfs_sta_add_tx_stats(arsta, peer_stats, rate_idx); } @@ -1137,7 +1137,7 @@ Signed-off-by: Vasanthakumar Thiagarajan spin_unlock_bh(&ab->base_lock); rcu_read_unlock(); } -@@ -1720,6 +1790,69 @@ int ath11k_dp_htt_tlv_iter(struct ath11k +@@ -1685,6 +1755,69 @@ int ath11k_dp_htt_tlv_iter(struct ath11k return 0; } @@ -1207,7 +1207,7 @@ Signed-off-by: Vasanthakumar Thiagarajan static int ath11k_htt_pull_ppdu_stats(struct ath11k_base *ab, struct sk_buff *skb) { -@@ -1738,6 +1871,15 @@ static int ath11k_htt_pull_ppdu_stats(st +@@ -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; @@ -1223,7 +1223,7 @@ Signed-off-by: Vasanthakumar Thiagarajan rcu_read_lock(); ar = ath11k_mac_get_ar_by_pdev_id(ab, pdev_id); if (!ar) { -@@ -1805,6 +1947,12 @@ static int ath11k_htt_pull_ppdu_stats(st +@@ -1770,6 +1912,12 @@ static int ath11k_htt_pull_ppdu_stats(st } } @@ -1257,7 +1257,7 @@ Signed-off-by: Vasanthakumar Thiagarajan mutex_unlock(&ar->conf_mutex); } -@@ -9715,6 +9727,28 @@ err_fallback: +@@ -9714,6 +9726,28 @@ err_fallback: return 0; } @@ -1286,7 +1286,7 @@ Signed-off-by: Vasanthakumar Thiagarajan static const struct ieee80211_ops ath11k_ops = { .tx = ath11k_mac_op_tx, .wake_tx_queue = ieee80211_handle_wake_tx_queue, -@@ -9772,6 +9806,9 @@ static const struct ieee80211_ops ath11k +@@ -9771,6 +9805,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, @@ -1296,7 +1296,7 @@ Signed-off-by: Vasanthakumar Thiagarajan }; static void ath11k_mac_update_ch_list(struct ath11k *ar, -@@ -10232,6 +10269,8 @@ static int __ath11k_mac_register(struct +@@ -10231,6 +10268,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); 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 index 1d7cf5b0e7c585..cb4fba0a2ffdcd 100644 --- 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 @@ -23,7 +23,7 @@ Signed-off-by: Rameshkumar Sundaram --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -7644,8 +7644,10 @@ err_vdev_del: +@@ -7643,8 +7643,10 @@ err_vdev_del: kfree(arvif->vlan_keyid_map); ath11k_peer_cleanup(ar, arvif->vdev_id); diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 798ec1973c3fe3..d733219b38aa7f 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -1573,6 +1573,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/nss/ath11k/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 index 67781ea0ad2b6b..3c3e436c75ce41 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -58,7 +58,7 @@ Signed-off-by: Venkateswara Naralasetty 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 -@@ -10155,6 +10155,8 @@ static int __ath11k_mac_register(struct +@@ -10154,6 +10154,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 index 90adde1baf67db..752218e9b8ec26 100644 --- 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 @@ -16,7 +16,7 @@ Signed-off-by: Anilkumar Kolli --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -6124,12 +6124,23 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -5953,12 +5953,23 @@ int ath11k_dp_rx_process_mon_status(stru pmon->mon_ppdu_status = DP_PPDU_STATUS_START; } @@ -43,7 +43,7 @@ Signed-off-by: Anilkumar Kolli rcu_read_lock(); spin_lock_bh(&ab->base_lock); peer = ath11k_peer_find_by_id(ab, ppdu_info->peer_id); -@@ -6453,6 +6464,13 @@ static int ath11k_dp_full_mon_process_rx +@@ -6282,6 +6293,13 @@ static int ath11k_dp_full_mon_process_rx spin_lock_bh(&pmon->mon_lock); @@ -57,7 +57,7 @@ Signed-off-by: Anilkumar Kolli sw_mon_entries = &pmon->sw_mon_entries; rx_mon_stats = &pmon->rx_mon_stats; -@@ -6492,7 +6510,6 @@ static int ath11k_dp_full_mon_process_rx +@@ -6321,7 +6339,6 @@ static int ath11k_dp_full_mon_process_rx } rx_mon_stats->dest_ppdu_done++; @@ -65,7 +65,7 @@ Signed-off-by: Anilkumar Kolli pmon->buf_state = DP_MON_STATUS_LAG; pmon->mon_status_paddr = sw_mon_entries->mon_status_paddr; pmon->hold_mon_dst_ring = true; -@@ -6523,16 +6540,10 @@ reap_status_ring: +@@ -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) { diff --git a/package/kernel/mac80211/patches/nss/ath11k/336-ath11k-skip-status-ring-entry-processing.patch b/package/kernel/mac80211/patches/nss/ath11k/336-ath11k-skip-status-ring-entry-processing.patch index 8950e960467e67..0adf26c808aec6 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -3782,6 +3782,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) { -@@ -3795,6 +3835,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; -@@ -3814,8 +3855,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; -@@ -3846,18 +3886,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) { diff --git a/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch b/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch index 8e23cd99e747c6..f574597dceb969 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch @@ -46,7 +46,7 @@ Signed-off-by: Nagarajan Maran --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -431,8 +431,8 @@ int ath11k_dp_rxbufs_replenish(struct at +@@ -396,8 +396,8 @@ int ath11k_dp_rxbufs_replenish(struct at goto fail_free_skb; spin_lock_bh(&rx_ring->idr_lock); @@ -57,7 +57,7 @@ Signed-off-by: Nagarajan Maran spin_unlock_bh(&rx_ring->idr_lock); if (buf_id <= 0) goto fail_dma_unmap; -@@ -3263,6 +3263,16 @@ try_again: +@@ -3141,6 +3141,16 @@ try_again: while (likely(desc = (struct hal_reo_dest_ring *)ath11k_hal_srng_dst_get_next_entry(ab, srng))) { @@ -74,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, -@@ -3293,8 +3303,6 @@ try_again: +@@ -3171,8 +3181,6 @@ try_again: num_buffs_reaped[mac_id]++; diff --git a/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch b/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch index fe231db61355ea..f57faaa465ae76 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch @@ -13,7 +13,7 @@ Signed-off-by: Ramya Gnanasekar --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -2671,7 +2671,8 @@ static void ath11k_dp_rx_h_undecap(struc +@@ -2564,7 +2564,8 @@ static void ath11k_dp_rx_h_undecap(struc ehdr = (struct ethhdr *)msdu->data; /* mac80211 allows fast path only for authorized STA */ 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 index fd4f0938cdb83b..f909ba4a673f69 100644 --- 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 @@ -14,7 +14,7 @@ Signed-off-by: Ramya Gnanasekar --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h -@@ -1501,6 +1501,7 @@ struct htt_ppdu_stats_usr_cmpltn_cmn { +@@ -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 @@ -24,7 +24,7 @@ Signed-off-by: Ramya Gnanasekar u32 ppdu_id; --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -1323,7 +1323,7 @@ static int ath11k_htt_tlv_ppdu_stats_par +@@ -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; @@ -33,7 +33,7 @@ Signed-off-by: Ramya Gnanasekar ppdu_info = data; -@@ -1404,6 +1404,8 @@ static int ath11k_htt_tlv_ppdu_stats_par +@@ -1369,6 +1369,8 @@ static int ath11k_htt_tlv_ppdu_stats_par return -EINVAL; } @@ -42,7 +42,7 @@ Signed-off-by: Ramya Gnanasekar 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, -@@ -1415,6 +1417,7 @@ static int ath11k_htt_tlv_ppdu_stats_par +@@ -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)); diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index fd78090aebc0f0..8adb5448a1564c 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -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 -@@ -849,6 +849,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)); @@ -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/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 index 1f81a8ef722598..510fbc2448cee7 100644 --- 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 @@ -13,7 +13,7 @@ Signed-off-by: Yuvasree Sivasankaran --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -10142,6 +10142,7 @@ static int __ath11k_mac_register(struct +@@ -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); diff --git a/package/kernel/mac80211/patches/nss/ath11k/457-wifi-ath11k-Avoid-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 index 55d8063a2403ca..c23b6cb3c858b4 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/457-wifi-ath11k-Avoid-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 -@@ -6261,7 +6261,9 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -6090,7 +6090,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))) { -@@ -6279,7 +6281,6 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -6108,7 +6110,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,7 +67,7 @@ Signed-off-by: Yuvasree Sivasankaran ppdu_info->peer_id = HAL_INVALID_PEERID; hal_status = ath11k_hal_rx_parse_mon_status(ab, ppdu_info, skb); -@@ -6307,6 +6308,7 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -6136,6 +6137,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); 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 index b2912777fad5d0..b471fb326a5b48 100644 --- 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 @@ -26,7 +26,7 @@ Acked-by: Jeff Johnson --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -8222,7 +8222,6 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -8221,7 +8221,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; @@ -34,7 +34,7 @@ Acked-by: Jeff Johnson mutex_lock(&ar->conf_mutex); -@@ -8245,21 +8244,6 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -8244,21 +8243,6 @@ ath11k_mac_op_assign_vif_chanctx(struct goto out; } 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 index ea08ea8818155d..2fb2cdfd429b11 100644 --- 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 @@ -39,7 +39,7 @@ Acked-by: Jeff Johnson if (ret) { ath11k_warn(ab, "failed to delay vdev start: %d\n", ret); goto free_tx_stats; -@@ -8165,8 +8165,8 @@ unlock: +@@ -8164,8 +8164,8 @@ unlock: mutex_unlock(&ar->conf_mutex); } 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 index a2ff42ad9d194d..4d83d0f0ed9029 100644 --- 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 @@ -317,7 +317,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) -@@ -9740,6 +9462,281 @@ ath11k_mac_op_config_mesh_offload_path(s +@@ -9739,6 +9461,281 @@ ath11k_mac_op_config_mesh_offload_path(s } #endif 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 index aeaf65aaa0e73b..d1b462519c91e8 100644 --- 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 @@ -52,7 +52,7 @@ Acked-by: Jeff Johnson --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -7934,6 +7934,30 @@ static int ath11k_mac_start_vdev_delay(s +@@ -7933,6 +7933,30 @@ static int ath11k_mac_start_vdev_delay(s return 0; } @@ -83,7 +83,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -@@ -7978,15 +8002,17 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -7977,15 +8001,17 @@ ath11k_mac_op_assign_vif_chanctx(struct goto out; } @@ -109,7 +109,7 @@ Acked-by: Jeff Johnson if (arvif->vdev_type != WMI_VDEV_TYPE_MONITOR && test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags)) { -@@ -8026,8 +8052,6 @@ ath11k_mac_op_unassign_vif_chanctx(struc +@@ -8025,8 +8051,6 @@ ath11k_mac_op_unassign_vif_chanctx(struc "chanctx unassign ptr %p vdev_id %i\n", ctx, arvif->vdev_id); @@ -118,7 +118,7 @@ Acked-by: Jeff Johnson if (ab->hw_params.vdev_start_delay && arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { spin_lock_bh(&ab->base_lock); -@@ -8051,24 +8075,13 @@ ath11k_mac_op_unassign_vif_chanctx(struc +@@ -8050,24 +8074,13 @@ ath11k_mac_op_unassign_vif_chanctx(struc return; } @@ -149,7 +149,7 @@ Acked-by: Jeff Johnson } if (ab->hw_params.vdev_start_delay && -@@ -9556,6 +9569,46 @@ exit: +@@ -9555,6 +9568,46 @@ exit: return ret; } @@ -196,7 +196,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, -@@ -9591,31 +9644,15 @@ static int ath11k_mac_op_sta_state(struc +@@ -9590,31 +9643,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)) { @@ -233,7 +233,7 @@ Acked-by: Jeff Johnson 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); -@@ -9626,12 +9663,6 @@ static int ath11k_mac_op_sta_state(struc +@@ -9625,12 +9662,6 @@ static int ath11k_mac_op_sta_state(struc } spin_unlock_bh(&ar->ab->base_lock); mutex_unlock(&ar->ab->tbl_mtx_lock); @@ -246,7 +246,7 @@ Acked-by: Jeff Johnson } else if (old_state == IEEE80211_STA_AUTH && new_state == IEEE80211_STA_ASSOC && (vif->type == NL80211_IFTYPE_AP || -@@ -10203,6 +10234,8 @@ static int __ath11k_mac_register(struct +@@ -10202,6 +10233,8 @@ static int __ath11k_mac_register(struct wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); 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 index 06f5e62c7b103c..2362820dc9e838 100644 --- 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 @@ -40,7 +40,7 @@ ath11k-$(CPTCFG_ATH11K_THERMAL) += thermal.o --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c -@@ -1877,7 +1877,9 @@ int ath11k_debugfs_register(struct ath11 +@@ -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); @@ -120,7 +120,7 @@ &fops_peer_ps_state); --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -1758,8 +1758,10 @@ ath11k_update_per_peer_tx_stats(struct a +@@ -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; @@ -131,7 +131,7 @@ } usr_stats->rate_stats_updated = true; -@@ -2205,7 +2207,9 @@ void ath11k_dp_htt_htc_t2h_msg_handler(s +@@ -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: @@ -176,7 +176,7 @@ spin_unlock_bh(&ab->base_lock); --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -9813,7 +9813,7 @@ static const struct ieee80211_ops ath11k +@@ -9812,7 +9812,7 @@ static const struct ieee80211_ops ath11k .set_wakeup = ath11k_wow_op_set_wakeup, #endif diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 88% rename from package/kernel/mac80211/patches/nss/ath11k/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 7b7673953bd4fe..155f383efc8dd0 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -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; -@@ -1129,6 +1130,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,17 +30,19 @@ 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 { - #define DP_REO_CMD_RING_SIZE 256 +@@ -238,6 +238,11 @@ struct ath11k_pdev_dp { #define DP_REO_STATUS_RING_SIZE 2048 #define DP_RXDMA_BUF_RING_SIZE 4096 --#define DP_RXDMA_REFILL_RING_SIZE 2048 -+#define DP_RXDMA_REFILL_RING_SIZE ATH11K_DP_RXDMA_REFILL_RING_SIZE -+#define DP_RXDMA_NSS_REFILL_RING_SIZE ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE + #define DP_RXDMA_REFILL_RING_SIZE 2048 ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512MB ++#define DP_RXDMA_NSS_REFILL_RING_SIZE 1816 ++#else ++#define DP_RXDMA_NSS_REFILL_RING_SIZE 2048 ++#endif #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 -@@ -648,7 +649,7 @@ enum htt_stats_internal_ppdu_frametype { +@@ -672,7 +677,7 @@ enum htt_stats_internal_ppdu_frametype { * * |31 26|25|24|23 16|15 8|7 0| * |-----------------+----------------+----------------+---------------| @@ -49,7 +51,7 @@ Signed-off-by: Ramya Gnanasekar * |-------------------------------------------------------------------| * | rsvd2 | ring_buffer_size | * |-------------------------------------------------------------------| -@@ -662,6 +663,14 @@ enum htt_stats_internal_ppdu_frametype { +@@ -686,6 +691,14 @@ enum htt_stats_internal_ppdu_frametype { * |-------------------------------------------------------------------| * | tlv_filter_in_flags | * |-------------------------------------------------------------------| @@ -64,7 +66,7 @@ Signed-off-by: Ramya Gnanasekar * Where: * PS = pkt_swap * SS = status_swap -@@ -675,7 +684,10 @@ enum htt_stats_internal_ppdu_frametype { +@@ -699,7 +712,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 @@ -76,7 +78,7 @@ Signed-off-by: Ramya Gnanasekar * dword1 - b'0:16 - ring_buffer_size: size of buffers referenced by rx ring, * in byte units. * Valid only for HW_TO_SW_RING and SW_TO_HW_RING -@@ -704,6 +716,42 @@ enum htt_stats_internal_ppdu_frametype { +@@ -728,6 +744,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 @@ -119,7 +121,7 @@ Signed-off-by: Ramya Gnanasekar */ #define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) -@@ -711,8 +759,16 @@ enum htt_stats_internal_ppdu_frametype { +@@ -735,8 +787,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) @@ -136,7 +138,7 @@ Signed-off-by: Ramya Gnanasekar enum htt_rx_filter_tlv_flags { HTT_RX_FILTER_TLV_FLAGS_MPDU_START = BIT(0), -@@ -1016,6 +1072,14 @@ enum htt_rx_data_pkt_filter_tlv_flasg3 { +@@ -1040,6 +1100,14 @@ enum htt_rx_data_pkt_filter_tlv_flasg3 { HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER | \ HTT_RX_FILTER_TLV_FLAGS_ATTENTION) @@ -151,7 +153,7 @@ Signed-off-by: Ramya Gnanasekar struct htt_rx_ring_selection_cfg_cmd { u32 info0; u32 info1; -@@ -1024,6 +1088,10 @@ struct htt_rx_ring_selection_cfg_cmd { +@@ -1048,6 +1116,10 @@ struct htt_rx_ring_selection_cfg_cmd { u32 pkt_type_en_flags2; u32 pkt_type_en_flags3; u32 rx_filter_tlv; @@ -162,7 +164,7 @@ Signed-off-by: Ramya Gnanasekar } __packed; struct htt_rx_ring_tlv_filter { -@@ -1032,6 +1100,14 @@ struct htt_rx_ring_tlv_filter { +@@ -1056,6 +1128,14 @@ struct htt_rx_ring_tlv_filter { u32 pkt_filter_flags1; /* MGMT */ u32 pkt_filter_flags2; /* CTRL */ u32 pkt_filter_flags3; /* DATA */ @@ -179,7 +181,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); } @@ -192,7 +194,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); } @@ -228,7 +230,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); -@@ -2134,6 +2169,49 @@ int ath11k_dp_rx_crypto_icv_len(struct a +@@ -2387,6 +2422,49 @@ int ath11k_dp_rx_crypto_icv_len(struct a return 0; } @@ -278,7 +280,7 @@ Signed-off-by: Ramya Gnanasekar static void ath11k_dp_rx_h_undecap_nwifi(struct ath11k *ar, struct sk_buff *msdu, u8 *first_hdr, -@@ -2147,7 +2225,8 @@ static void ath11k_dp_rx_h_undecap_nwifi +@@ -2400,7 +2478,8 @@ static void ath11k_dp_rx_h_undecap_nwifi u8 da[ETH_ALEN]; u8 sa[ETH_ALEN]; u16 qos_ctl = 0; @@ -288,7 +290,7 @@ Signed-off-by: Ramya Gnanasekar /* copy SA & DA and pull decapped header */ hdr = (struct ieee80211_hdr *)msdu->data; -@@ -2156,7 +2235,7 @@ static void ath11k_dp_rx_h_undecap_nwifi +@@ -2409,7 +2488,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)); @@ -297,7 +299,7 @@ Signed-off-by: Ramya Gnanasekar /* original 802.11 header is valid for the first msdu * hence we can reuse the same header */ -@@ -2186,16 +2265,23 @@ static void ath11k_dp_rx_h_undecap_nwifi +@@ -2439,16 +2518,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); @@ -326,7 +328,7 @@ Signed-off-by: Ramya Gnanasekar memcpy(skb_push(msdu, IEEE80211_QOS_CTL_LEN), &qos_ctl, IEEE80211_QOS_CTL_LEN); -@@ -2311,6 +2397,20 @@ static void ath11k_dp_rx_h_undecap_eth(s +@@ -2564,6 +2650,20 @@ static void ath11k_dp_rx_h_undecap_eth(s u8 da[ETH_ALEN]; u8 sa[ETH_ALEN]; void *rfc1042; @@ -347,7 +349,7 @@ Signed-off-by: Ramya Gnanasekar rfc1042 = ath11k_dp_rx_h_find_rfc1042(ar, msdu, enctype); if (WARN_ON_ONCE(!rfc1042)) -@@ -2339,6 +2439,7 @@ static void ath11k_dp_rx_h_undecap_eth(s +@@ -2592,6 +2692,7 @@ static void ath11k_dp_rx_h_undecap_eth(s memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); @@ -355,7 +357,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 */ -@@ -2357,6 +2458,7 @@ static void ath11k_dp_rx_h_undecap_snap( +@@ -2610,6 +2711,7 @@ static void ath11k_dp_rx_h_undecap_snap( size_t hdr_len; u8 l3_pad_bytes; struct hal_rx_desc *rx_desc; @@ -363,7 +365,7 @@ Signed-off-by: Ramya Gnanasekar /* Delivered decapped frame: * [amsdu header] <-- replaced with 802.11 hdr -@@ -2370,6 +2472,11 @@ static void ath11k_dp_rx_h_undecap_snap( +@@ -2623,6 +2725,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); @@ -375,7 +377,7 @@ Signed-off-by: Ramya Gnanasekar hdr = (struct ieee80211_hdr *)first_hdr; hdr_len = ieee80211_hdrlen(hdr->frame_control); -@@ -2766,6 +2873,20 @@ static int ath11k_dp_rx_process_msdu(str +@@ -3097,6 +3204,20 @@ static int ath11k_dp_rx_process_msdu(str goto free_out; } @@ -396,7 +398,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); -@@ -2778,8 +2899,9 @@ static int ath11k_dp_rx_process_msdu(str +@@ -3109,8 +3230,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); @@ -408,7 +410,7 @@ Signed-off-by: Ramya Gnanasekar ath11k_dbg_dump(ab, ATH11K_DBG_DATA, NULL, "", rx_desc, sizeof(struct hal_rx_desc)); goto free_out; -@@ -3649,6 +3771,7 @@ static int ath11k_dp_rx_h_verify_tkip_mi +@@ -4069,6 +4191,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); @@ -416,7 +418,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; -@@ -3929,8 +4052,8 @@ static void ath11k_dp_rx_h_sort_frags(st +@@ -4349,8 +4472,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) { @@ -426,7 +428,7 @@ Signed-off-by: Ramya Gnanasekar u8 *ehdr; u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; -@@ -4160,8 +4283,9 @@ ath11k_dp_process_rx_err_buf(struct ath1 +@@ -4580,8 +4703,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); @@ -438,7 +440,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); -@@ -4784,6 +4908,47 @@ void ath11k_dp_rx_pdev_free(struct ath11 +@@ -5206,6 +5330,47 @@ void ath11k_dp_rx_pdev_free(struct ath11 ath11k_dp_rxdma_pdev_buf_free(ar); } @@ -486,7 +488,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; -@@ -4877,6 +5042,12 @@ config_refill_ring: +@@ -5299,6 +5464,12 @@ config_refill_ring: } } @@ -501,7 +503,7 @@ Signed-off-by: Ramya Gnanasekar --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -@@ -1183,6 +1183,8 @@ int ath11k_dp_tx_htt_rx_filter_setup(str +@@ -1264,6 +1264,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)); @@ -510,7 +512,7 @@ Signed-off-by: Ramya Gnanasekar cmd->info1 = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE, rx_buf_size); -@@ -1192,6 +1194,26 @@ int ath11k_dp_tx_htt_rx_filter_setup(str +@@ -1273,6 +1275,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; @@ -537,7 +539,7 @@ Signed-off-by: Ramya Gnanasekar ret = ath11k_htc_send(&ab->htc, ab->dp.eid, skb); if (ret) goto err_free; -@@ -1270,6 +1292,7 @@ int ath11k_dp_tx_htt_monitor_mode_ring_c +@@ -1351,6 +1373,7 @@ int ath11k_dp_tx_htt_monitor_mode_ring_c } ring_id = dp->rxdma_mon_buf_ring.refill_buf_ring.ring_id; @@ -559,7 +561,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); } @@ -698,7 +700,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) { @@ -710,7 +712,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) { @@ -722,11 +724,10 @@ Signed-off-by: Ramya Gnanasekar } static bool ath11k_hw_wcn6855_rx_desc_encrypt_valid(struct hal_rx_desc *desc) -@@ -929,6 +1047,98 @@ static u32 ath11k_hw_qcn9074_rx_desc_get - return FIELD_GET(HAL_RX_MPDU_INFO_INFO1_MPDU_LEN, - __le32_to_cpu(mpdu_info->u.qcn9074.info1)); +@@ -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) +{ @@ -817,11 +818,10 @@ Signed-off-by: Ramya Gnanasekar + 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]); +} -+ - 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, -@@ -1009,6 +1219,13 @@ const struct ath11k_hw_ops ipq6018_ops = + + 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, @@ -834,8 +834,8 @@ Signed-off-by: Ramya Gnanasekar + .rx_desc_get_crypto_header = ath11k_hw_ipq8074_rx_desc_get_crypto_hdr, }; - const struct ath11k_hw_ops qca6390_ops = { -@@ -1050,6 +1267,13 @@ const struct ath11k_hw_ops qca6390_ops = + const struct ath11k_hw_ops ipq6018_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, @@ -848,9 +848,9 @@ Signed-off-by: Ramya Gnanasekar + .rx_desc_get_crypto_header = ath11k_hw_ipq8074_rx_desc_get_crypto_hdr, }; - const struct ath11k_hw_ops qcn9074_ops = { -@@ -1132,6 +1356,13 @@ const struct ath11k_hw_ops wcn6855_ops = - .rx_desc_mpdu_start_addr2 = ath11k_hw_wcn6855_rx_desc_mpdu_start_addr2, + 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 @@ -862,18 +862,15 @@ Signed-off-by: Ramya Gnanasekar + .rx_desc_get_crypto_header = ath11k_hw_ipq8074_rx_desc_get_crypto_hdr, }; - const struct ath11k_hw_ops wcn6750_ops = { -@@ -1180,6 +1411,8 @@ const struct ath11k_hw_ops ipq5018_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, + 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, - .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, -@@ -1214,6 +1447,13 @@ const struct ath11k_hw_ops ipq5018_ops = - .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, +#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M @@ -885,31 +882,10 @@ Signed-off-by: Ramya Gnanasekar + .rx_desc_get_crypto_header = ath11k_hw_qcn9074_rx_desc_get_crypto_hdr, }; - #define ATH11K_TX_RING_MASK_0 BIT(0) + const struct ath11k_hw_ops wcn6855_ops = { --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h -@@ -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 - #else - /* Num VDEVS per radio */ - #define TARGET_NUM_VDEVS(ab) (ab->hw_params.num_vdevs_peers[ab->qmi.target_mem_mode].num_vdevs) -@@ -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 -+#define ATH11K_DP_RXDMA_REFILL_RING_SIZE 2048 -+#define ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE 2048 - #endif - - /* Num of peers for Single Radio mode */ -@@ -128,6 +135,8 @@ enum ath11k_bus { +@@ -128,6 +128,8 @@ enum ath11k_bus { struct hal_rx_desc; struct hal_tcl_data_cmd; @@ -918,12 +894,10 @@ Signed-off-by: Ramya Gnanasekar struct ath11k_hw_ring_mask { u8 tx[ATH11K_EXT_IRQ_GRP_NUM_MAX]; -@@ -285,7 +294,17 @@ struct ath11k_hw_ops { - bool (*rx_desc_mac_addr2_valid)(struct hal_rx_desc *desc); +@@ -287,6 +289,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); -+ u32 (*rx_desc_get_hal_mpdu_len) (struct hal_rx_mpdu_info *mpdu_info); + 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 @@ -939,7 +913,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 -@@ -6343,6 +6343,7 @@ static int ath11k_mac_config_mon_status_ +@@ -6455,6 +6455,7 @@ static int ath11k_mac_config_mon_status_ tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar); } @@ -1005,7 +979,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 -@@ -2230,7 +2230,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/nss/ath11k/999-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 new file mode 100644 index 00000000000000..c95960f2de04bf --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/999-311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch @@ -0,0 +1,109 @@ +From 246e530a47d9adab9106fb6f2b92197cace17e53 Mon Sep 17 00:00:00 2001 +From: Seevalamuthu Mariappan +Date: Fri, 21 May 2021 14:16:22 +0530 +Subject: [PATCH] ath11k: configure nss radio priority during pdev_init + +pdev's priority value is read from dts. Get scheme_id +using pdev priority. Configure scheme_id during pdev_init. + +Signed-off-by: Seevalamuthu Mariappan +--- + drivers/net/wireless/ath/ath11k/nss.c | 20 +++++++++++++++++++- + drivers/net/wireless/ath/ath11k/nss.h | 3 +++ + 2 files changed, 22 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath11k/nss.c ++++ b/drivers/net/wireless/ath/ath11k/nss.c +@@ -2,6 +2,7 @@ + /* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + */ ++#include + + #include "debug.h" + #include "mac.h" +@@ -4342,6 +4343,7 @@ static int ath11k_nss_init(struct ath11k + nss_tx_status_t status; + struct ath11k_dp *dp; + int i, ret; ++ struct device *dev = ab->dev; + + dp = &ab->dp; + +@@ -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; ++ if (of_property_read_bool(dev->of_node, "nss-radio-priority")) ++ wim->flags |= WIFILI_MULTISOC_THREAD_MAP_ENABLE; + + /* fill hal srng message */ + wim->hssm.dev_base_addr = (u32)ab->mem_pa; +@@ -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; ++ struct device *dev = ab->dev; + int radio_if_num = -1; + int refill_ring_id; + int features = 0; + int dyn_if_type; +- int ret, i; ++ int ret, i, scheme_id = 0; ++ u32 nss_radio_priority; + + dyn_if_type = ath11k_nss_get_dynamic_interface_type(ab); + +@@ -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); + ++ if (!of_property_read_u32(dev->of_node, "nss-radio-priority", &nss_radio_priority)) { ++ scheme_id = nss_wifili_thread_scheme_alloc(ab->nss.ctx, ar->nss.if_num, nss_radio_priority); ++ if (scheme_id == WIFILI_SCHEME_ID_INVALID) { ++ ath11k_warn(ab, "received invalid scheme_id, configuring default value\n"); ++ scheme_id = 0; ++ } ++ } ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "ifnum: %d scheme_id: %d nss_radio_priority: %d\n", ar->nss.if_num, scheme_id, nss_radio_priority); ++ + wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); + if (!wlmsg) { + ret = -ENOMEM; +@@ -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; ++ pdevmsg->scheme_id = scheme_id; + + /* Store rxdma ring info to the message */ + refill_ring_id = ar->dp.rx_refill_buf_ring.refill_buf_ring.ring_id; +@@ -4887,6 +4903,9 @@ int ath11k_nss_pdev_deinit(struct ath11k + /* pdev deinit msg success, dealloc, deregister and return */ + ret = 0; + ++ /* reset thread scheme*/ ++ nss_wifili_thread_scheme_dealloc(ab->nss.ctx, ar->nss.if_num); ++ + nss_dynamic_interface_dealloc_node(ar->nss.if_num, dyn_if_type); + nss_unregister_wifili_radio_if(ar->nss.if_num); + free: +--- a/drivers/net/wireless/ath/ath11k/nss.h ++++ b/drivers/net/wireless/ath/ath11k/nss.h +@@ -70,6 +70,7 @@ struct hal_rx_user_status; + /* Init Flags */ + #define WIFILI_NSS_CCE_DISABLED 0x1 + #define WIFILI_ADDTL_MEM_SEG_SET 0x000000002 ++#define WIFILI_MULTISOC_THREAD_MAP_ENABLE 0x10 + + /* ATH11K NSS PEER Info */ + /* Host memory allocated for peer info storage in nss */ +@@ -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 ++ + enum ath11k_nss_opmode { + ATH11K_NSS_OPMODE_UNKNOWN, + ATH11K_NSS_OPMODE_AP, diff --git a/target/linux/qualcommax/config-6.1 b/target/linux/qualcommax/config-6.1 index 9a970b7a2f1b60..9a6c8e391be63e 100644 --- a/target/linux/qualcommax/config-6.1 +++ b/target/linux/qualcommax/config-6.1 @@ -487,6 +487,11 @@ CONFIG_SERIAL_MSM=y CONFIG_SERIAL_MSM_CONSOLE=y CONFIG_SGL_ALLOC=y CONFIG_SG_POOL=y +# CONFIG_ALLOC_SKB_PAGE_FRAG_DISABLE is not set +# CONFIG_DEBUG_OBJECTS_SKBUFF is not set +CONFIG_SKB_RECYCLER=y +CONFIG_SKB_RECYCLER_MULTI_CPU=y +# CONFIG_SKB_FAST_RECYCLABLE_DEBUG_ENABLE is not set CONFIG_SMP=y # CONFIG_SM_CAMCC_8450 is not set # CONFIG_SM_GCC_8150 is not set diff --git a/target/linux/qualcommax/files/net/core/skbuff_debug.c b/target/linux/qualcommax/files/net/core/skbuff_debug.c new file mode 100644 index 00000000000000..50d06759210995 --- /dev/null +++ b/target/linux/qualcommax/files/net/core/skbuff_debug.c @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include "skbuff_debug.h" +#include "skbuff_notifier.h" +#include "skbuff_recycle.h" + +static int skbuff_debugobj_enabled __read_mostly = 1; + +static int skbuff_debug_event_handler(struct notifier_block *nb, + unsigned long action, void *data); +static struct notifier_block skbuff_debug_notify = { + .notifier_call = skbuff_debug_event_handler, + .priority = 0 +}; + +inline u32 skbuff_debugobj_sum(struct sk_buff *skb) +{ + int pos = offsetof(struct sk_buff, free_addr); + u32 sum = 0; + + while (pos--) + sum += ((u8 *)skb)[pos]; + + return sum; +} + +struct skbuff_debugobj_walking { + int pos; + void **d; +}; + +#ifdef CONFIG_ARM +static int skbuff_debugobj_walkstack(struct stackframe *frame, void *p) { + struct skbuff_debugobj_walking *w = (struct skbuff_debugobj_walking *)p; + unsigned long pc = frame->pc; + + if (w->pos < DEBUG_OBJECTS_SKBUFF_STACKSIZE - 1) { + w->d[w->pos++] = (void *)pc; + return 0; + } + + return -ENOENT; +} +#else +static bool skbuff_debugobj_walkstack(void *p, unsigned long pc) +{ + struct skbuff_debugobj_walking *w = (struct skbuff_debugobj_walking *)p; + + if (w->pos < DEBUG_OBJECTS_SKBUFF_STACKSIZE - 1) { + w->d[w->pos++] = (void *)pc; + return true; + } + + return false; +} +#endif + +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) +static void skbuff_debugobj_get_stack(void **ret) +{ + struct skbuff_debugobj_walking w = {0, ret}; + void *p = &w; + +#ifdef CONFIG_ARM + struct stackframe frame; + register unsigned long current_sp asm ("sp"); + + frame.lr = (unsigned long)__builtin_return_address(0); + frame.fp = (unsigned long)__builtin_frame_address(0); + frame.sp = current_sp; + frame.pc = (unsigned long)skbuff_debugobj_get_stack; + + walk_stackframe(&frame, skbuff_debugobj_walkstack, p); +#else + arch_stack_walk(skbuff_debugobj_walkstack, p, current, NULL); +#endif + + ret[w.pos] = NULL; +} +#else +#error +static void skbuff_debugobj_get_stack(void **ret) +{ + /* not supported */ + ret[0] = 0xdeadbeef; +} +#endif + +void skbuff_debugobj_print_stack(void *const *stack) +{ + int i; + + for (i = 0; stack[i]; i++) + pr_emerg("\t %pS (0x%p)\n", stack[i], stack[i]); +} + +static const char *skbuff_debugobj_state_name(const struct sk_buff *skb) +{ + int obj_state; + + obj_state = debug_object_get_state((struct sk_buff *)skb); + switch (obj_state) { + case ODEBUG_STATE_NONE: + return "none"; + case ODEBUG_STATE_INIT: + return "init"; + case ODEBUG_STATE_INACTIVE: + return "inactive"; + case ODEBUG_STATE_ACTIVE: + return "active"; + case ODEBUG_STATE_DESTROYED: + return "destroyed"; + case ODEBUG_STATE_NOTAVAILABLE: + return "not available"; + default: + return "invalid"; + } +} + +void skbuff_debugobj_print_skb(const struct sk_buff *skb) +{ + pr_emerg("skb_debug: current process = %s (pid %i)\n", + current->comm, current->pid); + pr_emerg("skb_debug: skb 0x%p, next 0x%p, prev 0x%p, state = %s\n", skb, + skb->next, skb->prev, skbuff_debugobj_state_name(skb)); + pr_emerg("skb_debug: free stack:\n"); + skbuff_debugobj_print_stack(skb->free_addr); + pr_emerg("skb_debug: alloc stack:\n"); + skbuff_debugobj_print_stack(skb->alloc_addr); +} +EXPORT_SYMBOL(skbuff_debugobj_print_skb); + +/* skbuff_debugobj_fixup(): + * Called when an error is detected in the state machine for + * the objects + */ +static bool skbuff_debugobj_fixup(void *addr, enum debug_obj_state state) +{ + struct sk_buff *skb = (struct sk_buff *)addr; + ftrace_dump(DUMP_ALL); + WARN(1, "skb_debug: state = %d, skb = 0x%p sum = %d (now %d)\n", + state, skb, skb->sum, skbuff_debugobj_sum(skb)); + skb_recycler_notifier_send_event(SKB_RECYCLER_NOTIFIER_FSM, skb); + + return true; +} + +static struct debug_obj_descr skbuff_debug_descr = { + .name = "sk_buff_struct", + .fixup_init = skbuff_debugobj_fixup, + .fixup_activate = skbuff_debugobj_fixup, + .fixup_destroy = skbuff_debugobj_fixup, + .fixup_free = skbuff_debugobj_fixup, +}; + +inline void skbuff_debugobj_activate(struct sk_buff *skb) +{ + int ret = 0; + + if (!skbuff_debugobj_enabled) + return; + + skbuff_debugobj_get_stack(skb->alloc_addr); + ret = debug_object_activate(skb, &skbuff_debug_descr); + if (ret) + goto err_act; + + skbuff_debugobj_sum_validate(skb); + + return; + +err_act: + ftrace_dump(DUMP_ALL); + WARN(1, "skb_debug: failed to activate err = %d skb = 0x%p sum = %d (now %d)\n", + ret, skb, skb->sum, skbuff_debugobj_sum(skb)); + skb_recycler_notifier_send_event(SKB_RECYCLER_NOTIFIER_DBLALLOC, skb); +} + +inline void skbuff_debugobj_init_and_activate(struct sk_buff *skb) +{ + if (!skbuff_debugobj_enabled) + return; + + /* if we're coming from the slab, the skb->sum might + * be invalid anyways + */ + skb->sum = skbuff_debugobj_sum(skb); + + debug_object_init(skb, &skbuff_debug_descr); + skbuff_debugobj_activate(skb); +} + +inline void skbuff_debugobj_deactivate(struct sk_buff *skb) +{ + int obj_state; + + if (!skbuff_debugobj_enabled) + return; + + skb->sum = skbuff_debugobj_sum(skb); + + obj_state = debug_object_get_state(skb); + + if (obj_state == ODEBUG_STATE_ACTIVE) { + debug_object_deactivate(skb, &skbuff_debug_descr); + skbuff_debugobj_get_stack(skb->free_addr); + return; + } + + ftrace_dump(DUMP_ALL); + WARN(1, "skb_debug: deactivating inactive object skb=0x%p state=%d sum = %d (now %d)\n", + skb, obj_state, skb->sum, skbuff_debugobj_sum(skb)); + skb_recycler_notifier_send_event(SKB_RECYCLER_NOTIFIER_DBLFREE, skb); +} + +inline void _skbuff_debugobj_sum_validate(struct sk_buff *skb, + const char *var, const char *src, + int line, const char *fxn) +{ + if (!skbuff_debugobj_enabled || !skb) + return; + + if (skb->sum == skbuff_debugobj_sum(skb)) + return; + + ftrace_dump(DUMP_ALL); + WARN(1, "skb_debug: skb sum changed skb = 0x%p sum = %d (now %d)\n", + skb, skb->sum, skbuff_debugobj_sum(skb)); + pr_emerg("skb_debug: %s() checking %s in %s:%d\n", fxn, var, src, line); + skb_recycler_notifier_send_event(SKB_RECYCLER_NOTIFIER_SUMERR, skb); +} + +inline void skbuff_debugobj_sum_update(struct sk_buff *skb) +{ + if (!skbuff_debugobj_enabled || !skb) + return; + + skb->sum = skbuff_debugobj_sum(skb); +} + +inline void skbuff_debugobj_destroy(struct sk_buff *skb) +{ + if (!skbuff_debugobj_enabled) + return; + + debug_object_destroy(skb, &skbuff_debug_descr); +} + +static int __init disable_object_debug(char *str) +{ + skbuff_debugobj_enabled = 0; + + pr_info("skb_debug: debug objects is disabled\n"); + return 0; +} + +early_param("no_skbuff_debug_objects", disable_object_debug); + +void skbuff_debugobj_print_skb_list(const struct sk_buff *skb_list, + const char *list_title, int cpu) +{ + int count; + struct sk_buff *skb_i = (struct sk_buff *)skb_list; + u32 sum_i, sum_now; + int obj_state; + + if (cpu < 0) { + cpu = get_cpu(); + put_cpu(); + } + pr_emerg("skb_debug: start skb list '%s' [CPU#%d]\n", list_title, cpu); + count = 0; + if (skb_list) { + do { + obj_state = + debug_object_get_state(skb_i); + if (obj_state < ODEBUG_STATE_NOTAVAILABLE) { + sum_i = skb_i->sum; + sum_now = skbuff_debugobj_sum(skb_i); + } else { + sum_i = 0; + sum_now = 0; + } + if (sum_i != sum_now) { + pr_emerg("skb_debug: [%02d] skb 0x%p, next 0x%p, prev 0x%p, state %d (%s), sum %d (now %d)\n", + count, skb_i, skb_i->next, skb_i->prev, + obj_state, skbuff_debugobj_state_name(skb_i), + sum_i, sum_now); + } + skb_i = skb_i->next; + count++; + } while (skb_list != skb_i); + } + pr_emerg("skb_debug: end skb list '%s'. In total %d skbs iterated.\n", list_title, count); +} + +void skbuff_debugobj_register_callback(void) +{ + skb_recycler_notifier_register(&skbuff_debug_notify); +} + +int skbuff_debug_event_handler(struct notifier_block *nb, unsigned long action, + void *data) +{ + struct sk_buff *skb = (struct sk_buff *)data; + + pr_emerg("skb_debug: notifier event %lu\n", action); + skbuff_debugobj_print_skb(skb); + skb_recycler_print_all_lists(); + + return NOTIFY_DONE; +} diff --git a/target/linux/qualcommax/files/net/core/skbuff_debug.h b/target/linux/qualcommax/files/net/core/skbuff_debug.h new file mode 100644 index 00000000000000..43e37ba43b645e --- /dev/null +++ b/target/linux/qualcommax/files/net/core/skbuff_debug.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#ifndef _LINUX_SKBBUFF_DEBUG_OBJECTS +#define _LINUX_SKBBUFF_DEBUG_OBJECTS + +#ifdef CONFIG_DEBUG_OBJECTS_SKBUFF +void skbuff_debugobj_init_and_activate(struct sk_buff *skb); +void skbuff_debugobj_activate(struct sk_buff *skb); +void skbuff_debugobj_deactivate(struct sk_buff *skb); +void skbuff_debugobj_destroy(struct sk_buff *skb); +#define skbuff_debugobj_sum_validate(skb) _skbuff_debugobj_sum_validate(skb, \ + #skb, __FILE__, __LINE__, __func__) +void _skbuff_debugobj_sum_validate(struct sk_buff *skb, const char *var, + const char *src, int line, const char *fxn); +void skbuff_debugobj_sum_update(struct sk_buff *skb); +void skbuff_debugobj_print_skb(const struct sk_buff *skb); + +void skbuff_debugobj_print_skb_list(const struct sk_buff *skb_list, + const char *list_title, int cpu); +void skbuff_debugobj_register_callback(void); + +#else +static inline void skbuff_debugobj_init_and_activate(struct sk_buff *skb) { } +static inline void skbuff_debugobj_activate(struct sk_buff *skb) { } +static inline void skbuff_debugobj_deactivate(struct sk_buff *skb) { } +static inline void skbuff_debugobj_destroy(struct sk_buff *skb) { } +static inline void skbuff_debugobj_sum_validate(struct sk_buff *skb) { } +static inline void skbuff_debugobj_sum_update(struct sk_buff *skb) { } +static inline void skbuff_debugobj_print_skb(const struct sk_buff *skb) { } + +static inline void skbuff_debugobj_print_skb_list + (const struct sk_buff *skb_list, const char *list_title, int cpu) { } +static inline void skbuff_debugobj_register_callback(void) { } +#endif + +#endif /* _LINUX_SKBBUFF_DEBUG_OBJECTS */ diff --git a/target/linux/qualcommax/files/net/core/skbuff_notifier.c b/target/linux/qualcommax/files/net/core/skbuff_notifier.c new file mode 100644 index 00000000000000..8c59476db7fe38 --- /dev/null +++ b/target/linux/qualcommax/files/net/core/skbuff_notifier.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* Notifier interface for the SKB Recycler */ + +#include "skbuff_notifier.h" + +static BLOCKING_NOTIFIER_HEAD(skb_recycler_notifier); + +int skb_recycler_notifier_register(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&skb_recycler_notifier, nb); +} +EXPORT_SYMBOL(skb_recycler_notifier_register); + +int skb_recycler_notifier_unregister(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&skb_recycler_notifier, nb); +} +EXPORT_SYMBOL(skb_recycler_notifier_unregister); + +int skb_recycler_notifier_send_event(unsigned long action, struct sk_buff *skb) +{ + int ret; + + ret = blocking_notifier_call_chain(&skb_recycler_notifier, action, skb); + + return 0; +} diff --git a/target/linux/qualcommax/files/net/core/skbuff_notifier.h b/target/linux/qualcommax/files/net/core/skbuff_notifier.h new file mode 100644 index 00000000000000..3d8bfa586fc94b --- /dev/null +++ b/target/linux/qualcommax/files/net/core/skbuff_notifier.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef SKBUFF_NOTIFIER_H +#define SKBUFF_NOTIFIER_H + +#include +#include + +/* notifier events */ +#define SKB_RECYCLER_NOTIFIER_SUMERR 0x0001 +#define SKB_RECYCLER_NOTIFIER_DBLFREE 0x0002 +#define SKB_RECYCLER_NOTIFIER_DBLALLOC 0x0004 +#define SKB_RECYCLER_NOTIFIER_FSM 0x0008 + +#if defined(CONFIG_DEBUG_OBJECTS_SKBUFF) +int skb_recycler_notifier_register(struct notifier_block *nb); +int skb_recycler_notifier_unregister(struct notifier_block *nb); +int skb_recycler_notifier_send_event(unsigned long action, + struct sk_buff *skb); +#else +static inline int skb_recycler_notifier_register(struct notifier_block *nb) +{ + return 0; +} + +static inline int skb_recycler_notifier_unregister(struct notifier_block *nb) +{ + return 0; +} + +static inline int skb_recycler_notifier_send_event(unsigned long action, + struct sk_buff *skb) +{ + return 1; +} +#endif /* CONFIG_DEBUG_OBJECTS_SKBUFF */ + +#endif /* SKBUFF_NOTIFIER_H */ diff --git a/target/linux/qualcommax/files/net/core/skbuff_recycle.c b/target/linux/qualcommax/files/net/core/skbuff_recycle.c new file mode 100644 index 00000000000000..41add8d3098fca --- /dev/null +++ b/target/linux/qualcommax/files/net/core/skbuff_recycle.c @@ -0,0 +1,729 @@ +/* + * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* Generic skb recycler */ + +#include "skbuff_recycle.h" +#include +#include + +#include "skbuff_debug.h" + +static struct proc_dir_entry *proc_net_skbrecycler; + +static DEFINE_PER_CPU(struct sk_buff_head, recycle_list); +static int skb_recycle_max_skbs = SKB_RECYCLE_MAX_SKBS; + +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU +static DEFINE_PER_CPU(struct sk_buff_head, recycle_spare_list); +static struct global_recycler glob_recycler; +static int skb_recycle_spare_max_skbs = SKB_RECYCLE_SPARE_MAX_SKBS; +#endif + +inline struct sk_buff *skb_recycler_alloc(struct net_device *dev, + unsigned int length) +{ + unsigned long flags; + struct sk_buff_head *h; + struct sk_buff *skb = NULL; + struct sk_buff *ln = NULL; + + if (unlikely(length > SKB_RECYCLE_SIZE)) + return NULL; + + h = &get_cpu_var(recycle_list); + local_irq_save(flags); + skb = skb_peek(h); + if (skb) { + ln = skb_peek_next(skb, h); + skbuff_debugobj_activate(skb); + /* Recalculate the sum for skb->next as next and prev pointers + * of skb->next will be updated in __skb_unlink + */ + skbuff_debugobj_sum_validate(ln); + __skb_unlink(skb, h); + skbuff_debugobj_sum_update(ln); + } +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + if (unlikely(!skb)) { + u8 head; + + spin_lock(&glob_recycler.lock); + /* If global recycle list is not empty, use global buffers */ + head = glob_recycler.head; + if (unlikely(head == glob_recycler.tail)) { + spin_unlock(&glob_recycler.lock); + } else { + struct sk_buff *gn = glob_recycler.pool[head].next; + struct sk_buff *gp = glob_recycler.pool[head].prev; + + /* Move SKBs from global list to CPU pool */ + skbuff_debugobj_sum_validate(gn); + skbuff_debugobj_sum_validate(gp); + skb_queue_splice_init(&glob_recycler.pool[head], h); + skbuff_debugobj_sum_update(gn); + skbuff_debugobj_sum_update(gp); + + head = (head + 1) & SKB_RECYCLE_MAX_SHARED_POOLS_MASK; + glob_recycler.head = head; + spin_unlock(&glob_recycler.lock); + /* We have refilled the CPU pool - dequeue */ + skb = skb_peek(h); + if (skb) { + /* Recalculate the sum for skb->next as next and + * prev pointers of skb->next will be updated + * in __skb_unlink + */ + ln = skb_peek_next(skb, h); + skbuff_debugobj_activate(skb); + skbuff_debugobj_sum_validate(ln); + __skb_unlink(skb, h); + skbuff_debugobj_sum_update(ln); + } + } + } +#endif + local_irq_restore(flags); + put_cpu_var(recycle_list); + + if (likely(skb)) { + struct skb_shared_info *shinfo; + + /* We're about to write a large amount to the skb to + * zero most of the structure so prefetch the start + * of the shinfo region now so it's in the D-cache + * before we start to write that. + */ + shinfo = skb_shinfo(skb); + prefetchw(shinfo); + + zero_struct(skb, offsetof(struct sk_buff, tail)); + refcount_set(&skb->users, 1); + skb->mac_header = (typeof(skb->mac_header))~0U; + skb->transport_header = (typeof(skb->transport_header))~0U; + zero_struct(shinfo, offsetof(struct skb_shared_info, dataref)); + atomic_set(&shinfo->dataref, 1); + + skb->data = skb->head + NET_SKB_PAD; + skb_reset_tail_pointer(skb); + + skb->dev = dev; + } + + return skb; +} + +inline bool skb_recycler_consume(struct sk_buff *skb) +{ + unsigned long flags; + struct sk_buff_head *h; + struct sk_buff *ln = NULL; + /* Can we recycle this skb? If not, simply return that we cannot */ + if (unlikely(!consume_skb_can_recycle(skb, SKB_RECYCLE_MIN_SIZE, + SKB_RECYCLE_MAX_SIZE))) + return false; + + /* If we can, then it will be much faster for us to recycle this one + * later than to allocate a new one from scratch. + */ + h = &get_cpu_var(recycle_list); + local_irq_save(flags); + /* Attempt to enqueue the CPU hot recycle list first */ + if (likely(skb_queue_len(h) < skb_recycle_max_skbs)) { + ln = skb_peek(h); + /* Recalculate the sum for peek of list as next and prev + * pointers of skb->next will be updated in __skb_queue_head + */ + skbuff_debugobj_sum_validate(ln); + __skb_queue_head(h, skb); + skbuff_debugobj_deactivate(skb); + skbuff_debugobj_sum_update(ln); + local_irq_restore(flags); + preempt_enable(); + return true; + } +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + h = this_cpu_ptr(&recycle_spare_list); + + /* The CPU hot recycle list was full; if the spare list is also full, + * attempt to move the spare list to the global list for other CPUs to + * use. + */ + if (unlikely(skb_queue_len(h) >= skb_recycle_spare_max_skbs)) { + u8 cur_tail, next_tail; + + spin_lock(&glob_recycler.lock); + cur_tail = glob_recycler.tail; + next_tail = (cur_tail + 1) & SKB_RECYCLE_MAX_SHARED_POOLS_MASK; + if (next_tail != glob_recycler.head) { + struct sk_buff_head *p = &glob_recycler.pool[cur_tail]; + struct sk_buff *hn = h->next, *hp = h->prev; + + /* Move SKBs from CPU pool to Global pool*/ + skbuff_debugobj_sum_validate(hp); + skbuff_debugobj_sum_validate(hn); + skb_queue_splice_init(h, p); + skbuff_debugobj_sum_update(hp); + skbuff_debugobj_sum_update(hn); + + /* Done with global list init */ + glob_recycler.tail = next_tail; + spin_unlock(&glob_recycler.lock); + + /* Recalculate the sum for peek of list as next and prev + * pointers of skb->next will be updated in + * __skb_queue_head + */ + ln = skb_peek(h); + skbuff_debugobj_sum_validate(ln); + /* We have now cleared room in the spare; + * Initialize and enqueue skb into spare + */ + __skb_queue_head(h, skb); + skbuff_debugobj_sum_update(ln); + skbuff_debugobj_deactivate(skb); + + local_irq_restore(flags); + preempt_enable(); + return true; + } + /* We still have a full spare because the global is also full */ + spin_unlock(&glob_recycler.lock); + } else { + /* We have room in the spare list; enqueue to spare list */ + ln = skb_peek(h); + /* Recalculate the sum for peek of list as next and prev + * pointers of skb->next will be updated in __skb_queue_head + */ + skbuff_debugobj_sum_validate(ln); + __skb_queue_head(h, skb); + skbuff_debugobj_deactivate(skb); + skbuff_debugobj_sum_update(ln); + local_irq_restore(flags); + preempt_enable(); + return true; + } +#endif + + local_irq_restore(flags); + preempt_enable(); + + return false; +} + +/** + * skb_recycler_consume_list_fast - free a list of skbs + * @skb_list: head of the buffer list + * + * Add the list of given SKBs to CPU list. Assumption is that these buffers + * have been allocated originally from recycler and have been transmitted through + * a controlled fast xmit path, thus removing the need for additional checks + * before recycling the buffers back to pool + */ +#ifdef CONFIG_DEBUG_OBJECTS_SKBUFF +inline bool skb_recycler_consume_list_fast(struct sk_buff_head *skb_list) +{ + struct sk_buff *skb = NULL, *next = NULL; + + skb_queue_walk_safe(skb_list, skb, next) { + if (skb) { + __skb_unlink(skb, skb_list); + skb_recycler_consume(skb); + } + } + + return true; +} +#else +inline bool skb_recycler_consume_list_fast(struct sk_buff_head *skb_list) +{ + unsigned long flags; + struct sk_buff_head *h; + + h = &get_cpu_var(recycle_list); + local_irq_save(flags); + /* Attempt to enqueue the CPU hot recycle list first */ + if (likely(skb_queue_len(h) < skb_recycle_max_skbs)) { + skb_queue_splice(skb_list,h); + local_irq_restore(flags); + preempt_enable(); + return true; + } + + local_irq_restore(flags); + preempt_enable(); + + return false; +} +#endif + +static void skb_recycler_free_skb(struct sk_buff_head *list) +{ + struct sk_buff *skb = NULL, *next = NULL; + unsigned long flags; + + spin_lock_irqsave(&list->lock, flags); + while ((skb = skb_peek(list)) != NULL) { + skbuff_debugobj_activate(skb); + next = skb->next; + __skb_unlink(skb, list); + skb_release_data(skb); + kfree_skbmem(skb); + /* + * Update the skb->sum for next due to skb_link operation + */ + if (next) { + skbuff_debugobj_sum_update(next); + } + } + spin_unlock_irqrestore(&list->lock, flags); +} + +static int skb_cpu_callback(unsigned int ocpu) +{ + unsigned long oldcpu = (unsigned long)ocpu; + + skb_recycler_free_skb(&per_cpu(recycle_list, oldcpu)); +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + spin_lock(&glob_recycler.lock); + skb_recycler_free_skb(&per_cpu(recycle_spare_list, oldcpu)); + spin_unlock(&glob_recycler.lock); +#endif + + return NOTIFY_DONE; +} + +#ifdef CONFIG_SKB_RECYCLER_PREALLOC +static int __init skb_prealloc_init_list(void) +{ + int i; + struct sk_buff *skb; + + for (i = 0; i < SKB_RECYCLE_MAX_PREALLOC_SKBS; i++) { + skb = __alloc_skb(SKB_RECYCLE_MAX_SIZE + NET_SKB_PAD, + GFP_KERNEL, 0, NUMA_NO_NODE); + if (unlikely(!skb)) + return -ENOMEM; + + skb_reserve(skb, NET_SKB_PAD); + + skb_recycler_consume(skb); + } + return 0; +} +#endif + +/* procfs: count + * Show skb counts + */ +static int proc_skb_count_show(struct seq_file *seq, void *v) +{ + int cpu; + int len; + int total; +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + unsigned int i; + unsigned long flags; +#endif + + total = 0; + + for_each_online_cpu(cpu) { + len = skb_queue_len(&per_cpu(recycle_list, cpu)); + seq_printf(seq, "recycle_list[%d]: %d\n", cpu, len); + total += len; + } + +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + for_each_online_cpu(cpu) { + len = skb_queue_len(&per_cpu(recycle_spare_list, cpu)); + seq_printf(seq, "recycle_spare_list[%d]: %d\n", cpu, len); + total += len; + } + + for (i = 0; i < SKB_RECYCLE_MAX_SHARED_POOLS; i++) { + spin_lock_irqsave(&glob_recycler.lock, flags); + len = skb_queue_len(&glob_recycler.pool[i]); + spin_unlock_irqrestore(&glob_recycler.lock, flags); + seq_printf(seq, "global_list[%d]: %d\n", i, len); + total += len; + } +#endif + + seq_printf(seq, "total: %d\n", total); + return 0; +} + +static int proc_skb_count_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_skb_count_show, pde_data(inode)); +} + +static const struct proc_ops proc_skb_count_fops = { + .proc_open = proc_skb_count_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_release = single_release, +}; + +/* procfs: flush + * Flush skbs + */ +static void skb_recycler_flush_task(struct work_struct *work) +{ + unsigned long flags; + struct sk_buff_head *h; + struct sk_buff_head tmp; + struct sk_buff *skb = NULL; + + skb_queue_head_init(&tmp); + + h = &get_cpu_var(recycle_list); + local_irq_save(flags); + skb_queue_splice_init(h, &tmp); + /* + * Update the sum for first skb present in tmp list. + * Since the skb is changed in splice init + */ + skb = skb_peek(&tmp); + skbuff_debugobj_sum_update(skb); + local_irq_restore(flags); + put_cpu_var(recycle_list); + skb_recycler_free_skb(&tmp); + +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + h = &get_cpu_var(recycle_spare_list); + local_irq_save(flags); + skb_queue_splice_init(h, &tmp); + skb = skb_peek(&tmp); + skbuff_debugobj_sum_update(skb); + local_irq_restore(flags); + put_cpu_var(recycle_spare_list); + skb_recycler_free_skb(&tmp); +#endif +} + +static ssize_t proc_skb_flush_write(struct file *file, + const char __user *buf, + size_t count, + loff_t *ppos) +{ +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + unsigned int i; + unsigned long flags; +#endif + schedule_on_each_cpu(&skb_recycler_flush_task); + +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + spin_lock_irqsave(&glob_recycler.lock, flags); + for (i = 0; i < SKB_RECYCLE_MAX_SHARED_POOLS; i++) + skb_recycler_free_skb(&glob_recycler.pool[i]); + glob_recycler.head = 0; + glob_recycler.tail = 0; + spin_unlock_irqrestore(&glob_recycler.lock, flags); +#endif + return count; +} + +static const struct proc_ops proc_skb_flush_fops = { + .proc_write = proc_skb_flush_write, + .proc_open = simple_open, + .proc_lseek = noop_llseek, +}; + +/* procfs: max_skbs + * Show max skbs + */ +static int proc_skb_max_skbs_show(struct seq_file *seq, void *v) +{ + seq_printf(seq, "%d\n", skb_recycle_max_skbs); + return 0; +} + +static int proc_skb_max_skbs_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_skb_max_skbs_show, pde_data(inode)); +} + +static ssize_t proc_skb_max_skbs_write(struct file *file, + const char __user *buf, + size_t count, + loff_t *ppos) +{ + int ret; + int max; + char buffer[13]; + + memset(buffer, 0, sizeof(buffer)); + if (count > sizeof(buffer) - 1) + count = sizeof(buffer) - 1; + if (copy_from_user(buffer, buf, count) != 0) + return -EFAULT; + ret = kstrtoint(strstrip(buffer), 10, &max); + if (ret == 0 && max >= 0) + skb_recycle_max_skbs = max; + + return count; +} + +static const struct proc_ops proc_skb_max_skbs_fops = { + .proc_open = proc_skb_max_skbs_open, + .proc_read = seq_read, + .proc_write = proc_skb_max_skbs_write, + .proc_release = single_release, +}; + +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU +/* procfs: max_spare_skbs + * Show max spare skbs + */ +static int proc_skb_max_spare_skbs_show(struct seq_file *seq, void *v) +{ + seq_printf(seq, "%d\n", skb_recycle_spare_max_skbs); + return 0; +} + +static int proc_skb_max_spare_skbs_open(struct inode *inode, struct file *file) +{ + return single_open(file, + proc_skb_max_spare_skbs_show, + pde_data(inode)); +} + +static ssize_t +proc_skb_max_spare_skbs_write(struct file *file, + const char __user *buf, + size_t count, + loff_t *ppos) +{ + int ret; + int max; + char buffer[13]; + + memset(buffer, 0, sizeof(buffer)); + if (count > sizeof(buffer) - 1) + count = sizeof(buffer) - 1; + if (copy_from_user(buffer, buf, count) != 0) + return -EFAULT; + ret = kstrtoint(strstrip(buffer), 10, &max); + if (ret == 0 && max >= 0) + skb_recycle_spare_max_skbs = max; + + return count; +} + +static const struct proc_ops proc_skb_max_spare_skbs_fops = { + .proc_open = proc_skb_max_spare_skbs_open, + .proc_read = seq_read, + .proc_write = proc_skb_max_spare_skbs_write, + .proc_release = single_release, +}; +#endif /* CONFIG_SKB_RECYCLER_MULTI_CPU */ + +static void skb_recycler_init_procfs(void) +{ + proc_net_skbrecycler = proc_mkdir("skb_recycler", init_net.proc_net); + if (!proc_net_skbrecycler) { + pr_err("cannot create skb_recycle proc dir"); + return; + } + + if (!proc_create("count", + S_IRUGO, + proc_net_skbrecycler, + &proc_skb_count_fops)) + pr_err("cannot create proc net skb_recycle held\n"); + + if (!proc_create("flush", + S_IWUGO, + proc_net_skbrecycler, + &proc_skb_flush_fops)) + pr_err("cannot create proc net skb_recycle flush\n"); + + if (!proc_create("max_skbs", + S_IRUGO | S_IWUGO, + proc_net_skbrecycler, + &proc_skb_max_skbs_fops)) + pr_err("cannot create proc net skb_recycle max_skbs\n"); + +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + if (!proc_create("max_spare_skbs", + S_IRUGO | S_IWUGO, + proc_net_skbrecycler, + &proc_skb_max_spare_skbs_fops)) + pr_err("cannot create proc net skb_recycle max_spare_skbs\n"); +#endif +} + +void __init skb_recycler_init(void) +{ + int cpu; +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + unsigned int i; +#endif + + for_each_possible_cpu(cpu) { + skb_queue_head_init(&per_cpu(recycle_list, cpu)); + } + +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + for_each_possible_cpu(cpu) { + skb_queue_head_init(&per_cpu(recycle_spare_list, cpu)); + } + + spin_lock_init(&glob_recycler.lock); + + for (i = 0; i < SKB_RECYCLE_MAX_SHARED_POOLS; i++) + skb_queue_head_init(&glob_recycler.pool[i]); + glob_recycler.head = 0; + glob_recycler.tail = 0; +#endif + +#ifdef CONFIG_SKB_RECYCLER_PREALLOC + if (skb_prealloc_init_list()) + pr_err("Failed to preallocate SKBs for recycle list\n"); +#endif + cpuhp_setup_state_nocalls(CPUHP_SKB_RECYCLER_DEAD, "net/skbuff_recycler:dead:",NULL, skb_cpu_callback); + skbuff_debugobj_register_callback(); + skb_recycler_init_procfs(); +} + +void skb_recycler_print_all_lists(void) +{ + unsigned long flags; + int cpu; +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + int i; + struct sk_buff_head *h; + + cpu = get_cpu(); + spin_lock_irqsave(&glob_recycler.lock, flags); + for (i = 0; i < SKB_RECYCLE_MAX_SHARED_POOLS; i++) + skbuff_debugobj_print_skb_list((&glob_recycler.pool[i])->next, + "Global Pool", -1); + spin_unlock_irqrestore(&glob_recycler.lock, flags); + + preempt_disable(); + local_irq_save(flags); + + h = &per_cpu(recycle_spare_list, cpu); + skbuff_debugobj_print_skb_list(h->next, "Recycle Spare", cpu); + + local_irq_restore(flags); + preempt_enable(); +#endif + + preempt_disable(); + local_irq_save(flags); + h = &per_cpu(recycle_list, cpu); + skbuff_debugobj_print_skb_list(h->next, "Recycle List", cpu); + + local_irq_restore(flags); + preempt_enable(); +} + +#ifdef SKB_FAST_RECYCLABLE_DEBUG_ENABLE +/** + * consume_skb_can_fast_recycle_debug - Debug API to flag any sanity check + * failures on a fast recycled skb + * @skb: buffer to be checked + * @min_skb_size: minimum skb size allowed + * @max_skb_size: maximum skb size allowed + * + * Returns false with warning message if any of the checks fail + */ +static inline bool consume_skb_can_fast_recycle_debug(const struct sk_buff *skb, + int min_skb_size, int max_skb_size) +{ + if (unlikely(irqs_disabled())) { + WARN(1, "skb_debug: irqs_disabled for skb = 0x%p \n", skb); + return false; + } + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY)) { + WARN(1, "skb_debug: ZEROCOPY flag set for skb = 0x%p \n", skb); + return false; + } + if (unlikely(skb_is_nonlinear(skb))) { + WARN(1, "skb_debug: non-linear skb = 0x%p \n", skb); + return false; + } + if (unlikely(skb_shinfo(skb)->frag_list)) { + WARN(1, "skb_debug: set frag_list for skb = 0x%p \n", skb); + return false; + } + if (unlikely(skb_shinfo(skb)->nr_frags)) { + WARN(1, "skb_debug: set nr_frags for skb = 0x%p \n", skb); + return false; + } + if (unlikely(skb->fclone != SKB_FCLONE_UNAVAILABLE)) { + WARN(1, "skb_debug: FCLONE available for skb = 0x%p \n", skb); + return false; + } + min_skb_size = SKB_DATA_ALIGN(min_skb_size + NET_SKB_PAD); + if (unlikely(skb_end_pointer(skb) - skb->head < min_skb_size)) { + WARN(1, "skb_debug: invalid min size for skb = 0x%p \n", skb); + return false; + } + max_skb_size = SKB_DATA_ALIGN(max_skb_size + NET_SKB_PAD); + if (unlikely(skb_end_pointer(skb) - skb->head > max_skb_size)) { + WARN(1, "skb_debug: invalid max size for skb = 0x%p \n", skb); + return false; + } + if (unlikely(skb_cloned(skb))) { + WARN(1, "skb_debug: cloned skb = 0x%p \n", skb); + return false; + } + if (unlikely(skb_pfmemalloc(skb))) { + WARN(1, "skb_debug: enabled pfmemalloc for skb = 0x%p \n", skb); + return false; + } + if (skb->_skb_refdst) { + WARN(1, "skb_debug: _skb_refdst flag enabled = 0x%p \n", skb); + return false; + } + if (skb->destructor) { + WARN(1, "skb_debug: destructor flag enabled = 0x%p \n", skb); + return false; + } + if (skb->active_extensions) { + WARN(1, "skb_debug: active_extensions flag enabled = 0x%p \n", + skb); + return false; + } +#if IS_ENABLED(CONFIG_NF_CONNTRACK) + if (skb->_nfct & NFCT_PTRMASK) { + WARN(1, "skb_debug: nfctinfo bits set for skb = 0x%p \n", skb); + return false; + } +#endif + return true; +} + +/** + * check_skb_fast_recyclable - Debug API to flag any sanity check failures + * on a fast recycled skb + * @skb: buffer to be checked + * + * Checks skb recyclability + */ +void check_skb_fast_recyclable(struct sk_buff *skb) +{ + bool check = true; + check = consume_skb_can_fast_recycle_debug(skb, SKB_RECYCLE_MIN_SIZE, SKB_RECYCLE_MAX_SIZE); + if (!check) + BUG_ON(1); +} +EXPORT_SYMBOL(check_skb_fast_recyclable); +#endif diff --git a/target/linux/qualcommax/files/net/core/skbuff_recycle.h b/target/linux/qualcommax/files/net/core/skbuff_recycle.h new file mode 100644 index 00000000000000..cbbc3ee1f0d6ee --- /dev/null +++ b/target/linux/qualcommax/files/net/core/skbuff_recycle.h @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. + * + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ +/* Definitions for the skb recycler functions */ + +#ifndef _LINUX_SKBUFF_RECYCLE_H +#define _LINUX_SKBUFF_RECYCLE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_NET_CLS_ACT +#include +#endif +#include +#include +#include +#include +#include +#include + +#define SKB_RECYCLE_SIZE 2304 +#define SKB_RECYCLE_MIN_SIZE SKB_RECYCLE_SIZE +#define SKB_RECYCLE_MAX_SIZE SKB_RECYCLE_SIZE +#define SKB_RECYCLE_MAX_SKBS 1024 + +#define SKB_RECYCLE_SPARE_MAX_SKBS 256 + +#ifdef CONFIG_SKB_RECYCLER_PREALLOC +#define SKB_RECYCLE_MAX_PREALLOC_SKBS CONFIG_SKB_RECYCLE_MAX_PREALLOC_SKBS +#define SKB_RECYCLE_MAX_SHARED_POOLS \ + DIV_ROUND_UP(SKB_RECYCLE_MAX_PREALLOC_SKBS, \ + SKB_RECYCLE_SPARE_MAX_SKBS) +#else +#define SKB_RECYCLE_MAX_SHARED_POOLS 8 +#endif + +#define SKB_RECYCLE_MAX_SHARED_POOLS_MASK \ + (SKB_RECYCLE_MAX_SHARED_POOLS - 1) + +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU +struct global_recycler { + /* Global circular list which holds the shared skb pools */ + struct sk_buff_head pool[SKB_RECYCLE_MAX_SHARED_POOLS]; + u8 head; /* head of the circular list */ + u8 tail; /* tail of the circular list */ + spinlock_t lock; +}; +#endif + +static __always_inline void zero_struct(void *v, int size) +{ + u32 *s = (u32 *)v; + + /* We assume that size is word aligned; in fact, it's constant */ + WARN_ON((size & 3) != 0); + + /* This looks odd but we "know" size is a constant, and so the + * compiler can fold away all of the conditionals. The compiler is + * pretty smart here, and can fold away the loop, too! + */ + while (size > 0) { + if (size >= 4) + s[0] = 0; + if (size >= 8) + s[1] = 0; + if (size >= 12) + s[2] = 0; + if (size >= 16) + s[3] = 0; + if (size >= 20) + s[4] = 0; + if (size >= 24) + s[5] = 0; + if (size >= 28) + s[6] = 0; + if (size >= 32) + s[7] = 0; + if (size >= 36) + s[8] = 0; + if (size >= 40) + s[9] = 0; + if (size >= 44) + s[10] = 0; + if (size >= 48) + s[11] = 0; + if (size >= 52) + s[12] = 0; + if (size >= 56) + s[13] = 0; + if (size >= 60) + s[14] = 0; + if (size >= 64) + s[15] = 0; + size -= 64; + s += 16; + } +} + +static inline bool consume_skb_can_recycle(const struct sk_buff *skb, + int min_skb_size, int max_skb_size) +{ + if (unlikely(irqs_disabled())) + return false; + + if (unlikely(skb_shinfo(skb)->tx_flags & SKBFL_ZEROCOPY_ENABLE)) + return false; + + if (unlikely(skb->head_frag)) + return false; + + if (unlikely(skb_is_nonlinear(skb))) + return false; + + if (unlikely(skb_shinfo(skb)->frag_list)) + return false; + + if (unlikely(skb_shinfo(skb)->nr_frags)) + return false; + + if (unlikely(skb->fclone != SKB_FCLONE_UNAVAILABLE)) + return false; + + min_skb_size = SKB_DATA_ALIGN(min_skb_size + NET_SKB_PAD); + if (unlikely(skb_end_pointer(skb) - skb->head < min_skb_size)) + return false; + + max_skb_size = SKB_DATA_ALIGN(max_skb_size + NET_SKB_PAD); + if (unlikely(skb_end_pointer(skb) - skb->head > max_skb_size)) + return false; + + if (unlikely(skb_cloned(skb))) + return false; + + if (unlikely(skb_pfmemalloc(skb))) + return false; + + return true; +} + +#ifdef CONFIG_SKB_RECYCLER +void __init skb_recycler_init(void); +struct sk_buff *skb_recycler_alloc(struct net_device *dev, unsigned int length); +bool skb_recycler_consume(struct sk_buff *skb); +bool skb_recycler_consume_list_fast(struct sk_buff_head *skb_list); +void skb_recycler_print_all_lists(void); +#else +#define skb_recycler_init() {} +#define skb_recycler_alloc(dev, len) NULL +#define skb_recycler_consume(skb) false +#define skb_recycler_consume_list_fast(skb_list) false +#define skb_recycler_print_all_lists() false +#endif +#endif diff --git a/target/linux/qualcommax/patches-6.1/9990-0272-net-skbuff-cache-for-skb-data-for-LM-profiles.patch b/target/linux/qualcommax/patches-6.1/9990-0272-net-skbuff-cache-for-skb-data-for-LM-profiles.patch new file mode 100644 index 00000000000000..b3dd71696c8f40 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/9990-0272-net-skbuff-cache-for-skb-data-for-LM-profiles.patch @@ -0,0 +1,69 @@ +From 35958c73762695bf64bd7e657c00e136cd8156ec Mon Sep 17 00:00:00 2001 +From: Kathiravan T +Date: Thu, 29 Apr 2021 16:29:02 +0530 +Subject: [PATCH 272/281] net: skbuff: cache for skb->data for LM profiles + +Signed-off-by: Kathiravan T +Change-Id: I7bcac8d05a11aa3d1a9e015d6530562ed81477a0 +--- + net/core/skbuff.c | 30 ++++++++++++++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 deletions(-) + +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -84,6 +84,12 @@ + #include "dev.h" + #include "sock_destructor.h" + ++ ++#if defined(CONFIG_SKB_FIXED_SIZE_2K) && !defined(__LP64__) ++struct kmem_cache *skb_data_cache; ++#define SKB_DATA_CACHE_SIZE 2176 ++#endif ++ + struct kmem_cache *skbuff_head_cache __ro_after_init; + static struct kmem_cache *skbuff_fclone_cache __ro_after_init; + #ifdef CONFIG_SKB_EXTENSIONS +@@ -444,6 +450,13 @@ static void *kmalloc_reserve(unsigned in + * Try a regular allocation, when that fails and we're not entitled + * to the reserves, fail. + */ ++#if defined(CONFIG_SKB_FIXED_SIZE_2K) && !defined(__LP64__) ++ if (obj_size > SZ_2K && obj_size <= SKB_DATA_CACHE_SIZE) ++ obj = kmem_cache_alloc_node(skb_data_cache, ++ flags | __GFP_NOMEMALLOC | __GFP_NOWARN, ++ node); ++ else ++#endif + obj = kmalloc_node_track_caller(obj_size, + flags | __GFP_NOMEMALLOC | __GFP_NOWARN, + node); +@@ -452,7 +465,12 @@ static void *kmalloc_reserve(unsigned in + + /* Try again but now we are using pfmemalloc reserves */ + ret_pfmemalloc = true; +- obj = kmalloc_node_track_caller(obj_size, flags, node); ++#if defined(CONFIG_SKB_FIXED_SIZE_2K) && !defined(__LP64__) ++ if (obj_size > SZ_2K && obj_size <= SKB_DATA_CACHE_SIZE) ++ obj = kmem_cache_alloc_node(skb_data_cache, flags, node); ++ else ++#endif ++ obj = kmalloc_node_track_caller(obj_size, flags, node); + + out: + if (pfmemalloc) +@@ -4557,6 +4575,14 @@ static void skb_extensions_init(void) {} + + void __init skb_init(void) + { ++ ++#if defined(CONFIG_SKB_FIXED_SIZE_2K) && !defined(__LP64__) ++ skb_data_cache = kmem_cache_create_usercopy("skb_data_cache", ++ SKB_DATA_CACHE_SIZE, ++ 0, 0, 0, SKB_DATA_CACHE_SIZE, ++ NULL); ++#endif ++ + skbuff_head_cache = kmem_cache_create_usercopy("skbuff_head_cache", + sizeof(struct sk_buff), + 0, diff --git a/target/linux/qualcommax/patches-6.1/9990-0273-net-skbuff-Cache-for-skb-data-for-all-profiles.patch b/target/linux/qualcommax/patches-6.1/9990-0273-net-skbuff-Cache-for-skb-data-for-all-profiles.patch new file mode 100644 index 00000000000000..6d2cdc660d28d9 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/9990-0273-net-skbuff-Cache-for-skb-data-for-all-profiles.patch @@ -0,0 +1,91 @@ +From aef6fe6fba93af65b66354aa7ad463cf370723c0 Mon Sep 17 00:00:00 2001 +From: Sneha Maganahalli +Date: Fri, 4 Feb 2022 14:29:37 +0530 +Subject: [PATCH 273/281] net: skbuff: Cache for skb->data for all profiles. + +Cache for skb->data for all profiles. + +Change-Id: Ib84a1b0c037bc27febb24edbee91ffe6427d528d +Signed-off-by: Sneha Maganahalli +--- + net/core/skbuff.c | 34 +++++++++++++++++++++++----------- + 1 file changed, 23 insertions(+), 11 deletions(-) + +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -84,10 +84,29 @@ + #include "dev.h" + #include "sock_destructor.h" + +- +-#if defined(CONFIG_SKB_FIXED_SIZE_2K) && !defined(__LP64__) + struct kmem_cache *skb_data_cache; +-#define SKB_DATA_CACHE_SIZE 2176 ++ ++/* ++ * For low memory profile, NSS_SKB_FIXED_SIZE_2K is enabled and ++ * CONFIG_SKB_RECYCLER is disabled. For premium and enterprise profile ++ * CONFIG_SKB_RECYCLER is enabled and NSS_SKB_FIXED_SIZE_2K is disabled. ++ * Irrespective of NSS_SKB_FIXED_SIZE_2K enabled/disabled, the ++ * CONFIG_SKB_RECYCLER and __LP64__ determines the value of SKB_DATA_CACHE_SIZE ++ */ ++#if defined(CONFIG_SKB_RECYCLER) ++/* ++ * 2688 for 64bit arch, 2624 for 32bit arch ++ */ ++#define SKB_DATA_CACHE_SIZE (SKB_DATA_ALIGN(SKB_RECYCLE_SIZE + NET_SKB_PAD) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) ++#else ++/* ++ * 2368 for 64bit arch, 2176 for 32bit arch ++ */ ++#if defined(__LP64__) ++#define SKB_DATA_CACHE_SIZE ((SKB_DATA_ALIGN(1984 + NET_SKB_PAD)) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) ++#else ++#define SKB_DATA_CACHE_SIZE ((SKB_DATA_ALIGN(1856 + NET_SKB_PAD)) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) ++#endif + #endif + + struct kmem_cache *skbuff_head_cache __ro_after_init; +@@ -450,14 +469,12 @@ static void *kmalloc_reserve(unsigned in + * Try a regular allocation, when that fails and we're not entitled + * to the reserves, fail. + */ +-#if defined(CONFIG_SKB_FIXED_SIZE_2K) && !defined(__LP64__) + if (obj_size > SZ_2K && obj_size <= SKB_DATA_CACHE_SIZE) + obj = kmem_cache_alloc_node(skb_data_cache, + flags | __GFP_NOMEMALLOC | __GFP_NOWARN, + node); + else +-#endif +- obj = kmalloc_node_track_caller(obj_size, ++ obj = kmalloc_node_track_caller(obj_size, + flags | __GFP_NOMEMALLOC | __GFP_NOWARN, + node); + if (obj || !(gfp_pfmemalloc_allowed(flags))) +@@ -465,11 +482,9 @@ static void *kmalloc_reserve(unsigned in + + /* Try again but now we are using pfmemalloc reserves */ + ret_pfmemalloc = true; +-#if defined(CONFIG_SKB_FIXED_SIZE_2K) && !defined(__LP64__) + if (obj_size > SZ_2K && obj_size <= SKB_DATA_CACHE_SIZE) + obj = kmem_cache_alloc_node(skb_data_cache, flags, node); + else +-#endif + obj = kmalloc_node_track_caller(obj_size, flags, node); + + out: +@@ -4575,13 +4590,10 @@ static void skb_extensions_init(void) {} + + void __init skb_init(void) + { +- +-#if defined(CONFIG_SKB_FIXED_SIZE_2K) && !defined(__LP64__) + skb_data_cache = kmem_cache_create_usercopy("skb_data_cache", + SKB_DATA_CACHE_SIZE, +- 0, 0, 0, SKB_DATA_CACHE_SIZE, ++ 0, SLAB_PANIC, 0, SKB_DATA_CACHE_SIZE, + NULL); +-#endif + + skbuff_head_cache = kmem_cache_create_usercopy("skbuff_head_cache", + sizeof(struct sk_buff), diff --git a/target/linux/qualcommax/patches-6.1/9990-0367-Generic-rx-to-rx-skb-recycler.patch b/target/linux/qualcommax/patches-6.1/9990-0367-Generic-rx-to-rx-skb-recycler.patch new file mode 100644 index 00000000000000..223f5efda5092c --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/9990-0367-Generic-rx-to-rx-skb-recycler.patch @@ -0,0 +1,207 @@ +From 86479de8f60d947e6cef9decebe1b215ac428b21 Mon Sep 17 00:00:00 2001 +From: Tian Yang +Date: Mon, 13 Apr 2020 10:14:08 -0700 +Subject: [PATCH] Generic rx-to-rx skb recycler + +Porting from 3.4 kernel (banana branch). + +Removing kmemcheck header and the no longer valid cpuhotplug notifier function. + +Change-Id: Ie81a7d812ec14a40da8f22cf4e0f7ddaaf166cff +Signed-off-by: Varadarajan Narayanan +Signed-off-by: Pamidipati, Vijay +Signed-off-by: Casey Chen +Signed-off-by: Tian Yang +--- + MAINTAINERS | 5 ++++ + include/linux/skbuff.h | 2 ++ + net/Kconfig | 15 ++++++++++ + net/core/Makefile | 1 + + net/core/skbuff.c | 68 +++++++++++++++++++++++++++++++++++++----- + 5 files changed, 84 insertions(+), 7 deletions(-) + +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -143,6 +143,11 @@ Maintainers List + first. When adding to this list, please keep the entries in + alphabetical order. + ++SKB RECYCLER SUPPORT ++M: Casey Chen ++S: Maintained ++F: net/core/skbuff_recycle.* ++ + 3C59X NETWORK DRIVER + M: Steffen Klassert + L: netdev@vger.kernel.org +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -1252,6 +1252,8 @@ static inline void consume_skb(struct sk + void __consume_stateless_skb(struct sk_buff *skb); + void __kfree_skb(struct sk_buff *skb); + extern struct kmem_cache *skbuff_head_cache; ++extern void kfree_skbmem(struct sk_buff *skb); ++extern void skb_release_data(struct sk_buff *skb); + + void kfree_skb_partial(struct sk_buff *skb, bool head_stolen); + bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from, +--- a/net/Kconfig ++++ b/net/Kconfig +@@ -332,6 +332,21 @@ config NET_FLOW_LIMIT + with many clients some protection against DoS by a single (spoofed) + flow that greatly exceeds average workload. + ++config SKB_RECYCLER ++ bool "Generic skb recycling" ++ default y ++ help ++ SKB_RECYCLER is used to implement RX-to-RX skb recycling. ++ This config enables the recycling scheme for bridging and ++ routing workloads. It can reduce skbuff freeing or ++ reallocation overhead. ++ ++ ++config SKB_RECYCLER_MULTI_CPU ++ bool "Cross-CPU recycling for CPU-locked workloads" ++ depends on SMP && SKB_RECYCLER ++ default n ++ + menu "Network testing" + + config NET_PKTGEN +--- a/net/core/Makefile ++++ b/net/core/Makefile +@@ -40,3 +40,4 @@ obj-$(CONFIG_NET_SOCK_MSG) += skmsg.o + obj-$(CONFIG_BPF_SYSCALL) += sock_map.o + obj-$(CONFIG_BPF_SYSCALL) += bpf_sk_storage.o + obj-$(CONFIG_OF) += of_net.o ++obj-$(CONFIG_SKB_RECYCLER) += skbuff_recycle.o +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -109,6 +109,8 @@ struct kmem_cache *skb_data_cache; + #endif + #endif + ++#include "skbuff_recycle.h" ++ + struct kmem_cache *skbuff_head_cache __ro_after_init; + static struct kmem_cache *skbuff_fclone_cache __ro_after_init; + #ifdef CONFIG_SKB_EXTENSIONS +@@ -584,7 +586,7 @@ EXPORT_SYMBOL(__alloc_skb); + /** + * __netdev_alloc_skb - allocate an skbuff for rx on a specific device + * @dev: network device to receive on +- * @len: length to allocate ++ * @length: length to allocate + * @gfp_mask: get_free_pages mask, passed to alloc_skb + * + * Allocate a new &sk_buff and assign it a usage count of one. The +@@ -594,11 +596,28 @@ EXPORT_SYMBOL(__alloc_skb); + * + * %NULL is returned if there is no free memory. + */ +-struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int len, +- gfp_t gfp_mask) ++struct sk_buff *__netdev_alloc_skb(struct net_device *dev, ++ unsigned int length, gfp_t gfp_mask) + { +- struct page_frag_cache *nc; + struct sk_buff *skb; ++ unsigned int len = length; ++ ++#ifdef CONFIG_SKB_RECYCLER ++ skb = skb_recycler_alloc(dev, length); ++ if (likely(skb)) ++ return skb; ++ ++ len = SKB_RECYCLE_SIZE; ++ if (unlikely(length > SKB_RECYCLE_SIZE)) ++ len = length; ++ ++ skb = __alloc_skb(len + NET_SKB_PAD, gfp_mask, ++ SKB_ALLOC_RX, NUMA_NO_NODE); ++ if (!skb) ++ goto skb_fail; ++ goto skb_success; ++#else ++ struct page_frag_cache *nc; + bool pfmemalloc; + void *data; + +@@ -645,6 +664,7 @@ struct sk_buff *__netdev_alloc_skb(struc + if (pfmemalloc) + skb->pfmemalloc = 1; + skb->head_frag = 1; ++#endif + + skb_success: + skb_reserve(skb, NET_SKB_PAD); +@@ -813,7 +833,7 @@ static void skb_free_head(struct sk_buff + } + } + +-static void skb_release_data(struct sk_buff *skb) ++void skb_release_data(struct sk_buff *skb) + { + struct skb_shared_info *shinfo = skb_shinfo(skb); + int i; +@@ -855,7 +875,7 @@ exit: + /* + * Free an skbuff by memory without cleaning the state. + */ +-static void kfree_skbmem(struct sk_buff *skb) ++void kfree_skbmem(struct sk_buff *skb) + { + struct sk_buff_fclones *fclones; + +@@ -1081,8 +1101,41 @@ void consume_skb(struct sk_buff *skb) + if (!skb_unref(skb)) + return; + ++ prefetch(&skb->destructor); ++ ++ /*Tian: Not sure if we need to continue using this since ++ * since unref does the work in 5.4 ++ */ ++ ++ /* ++ if (likely(atomic_read(&skb->users) == 1)) ++ smp_rmb(); ++ else if (likely(!atomic_dec_and_test(&skb->users))) ++ return; ++ */ ++ ++ /* If possible we'd like to recycle any skb rather than just free it, ++ * but in order to do that we need to release any head state too. ++ * We don't want to do this later because we'll be in a pre-emption ++ * disabled state. ++ */ ++ skb_release_head_state(skb); ++ ++ /* Can we recycle this skb? If we can then it will be much faster ++ * for us to recycle this one later than to allocate a new one ++ * from scratch. ++ */ ++ if (likely(skb_recycler_consume(skb))) ++ return; ++ + trace_consume_skb(skb); +- __kfree_skb(skb); ++ ++ /* We're not recycling so now we need to do the rest of what we would ++ * have done in __kfree_skb (above and beyond the skb_release_head_state ++ * that we already did). ++ */ ++ skb_release_data(skb); ++ kfree_skbmem(skb); + } + EXPORT_SYMBOL(consume_skb); + #endif +@@ -4608,6 +4661,7 @@ void __init skb_init(void) + SLAB_HWCACHE_ALIGN|SLAB_PANIC, + NULL); + skb_extensions_init(); ++ skb_recycler_init(); + } + + static int diff --git a/target/linux/qualcommax/patches-6.1/9990-0368-skbuff_debug-track-functions-that-free-SKBs.patch b/target/linux/qualcommax/patches-6.1/9990-0368-skbuff_debug-track-functions-that-free-SKBs.patch new file mode 100644 index 00000000000000..4f66fd49baad38 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/9990-0368-skbuff_debug-track-functions-that-free-SKBs.patch @@ -0,0 +1,51 @@ +From 9a3850e377ff8b567d7edeb64cf7b6d6eda817f2 Mon Sep 17 00:00:00 2001 +From: Tian Yang +Date: Thu, 1 Oct 2015 16:31:33 -0500 +Subject: [PATCH] skbuff_debug: track functions that free SKBs + +This adds a member to struct skbuff if +CONFIG_DEBUG_OBJECTS_SKBUFF is turned on that tracks +the caller that last free'd the SKB. + +This should work for SLAB and SKB recycler free since this +element of the SKB should not get overwritten when allocated +from either pool of objects. + +Performance info for before/after: + +Before: + + speed was 53.45 Mbit/s + cycles = 97974050028 (per pkt = 35368.7482818) + instructions = 26722549696 (per pkt = 9646.87213988) + dcache_misses = 512380452 (per pkt = 184.969950983) + icache_misses = 1268005369 (per pkt = 457.75144238) + +After: + + speed was 48.91 Mbit/s + cycles = 98737753294 (per pkt = 38614.9009095) + instructions = 25770915740 (per pkt = 10078.6307613) + dcache_misses = 589106068 (per pkt = 230.39082501) + icache_misses = 1146428790 (per pkt = 448.351645128) + +Change-Id: Ie9e854015dc040fc30b97f89dd0663601b8f0344 +Signed-off-by: Matthew McClintock +Signed-off-by: Casey Chen +--- + include/linux/skbuff.h | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -1062,6 +1062,10 @@ struct sk_buff { + /* only useable after checking ->active_extensions != 0 */ + struct skb_ext *extensions; + #endif ++ ++#ifdef CONFIG_DEBUG_OBJECTS_SKBUFF ++ void *free_addr; ++#endif + }; + + /* if you move pkt_type around you also must adapt those constants */ diff --git a/target/linux/qualcommax/patches-6.1/9990-0369-net-skbuff-use-debug-objects-to-track-skb-allocation.patch b/target/linux/qualcommax/patches-6.1/9990-0369-net-skbuff-use-debug-objects-to-track-skb-allocation.patch new file mode 100644 index 00000000000000..bb8f11101aadab --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/9990-0369-net-skbuff-use-debug-objects-to-track-skb-allocation.patch @@ -0,0 +1,126 @@ +From d30297828bd54324ca19412ae8097d878319556b Mon Sep 17 00:00:00 2001 +From: Tian Yang +Date: Mon, 21 Sep 2015 18:50:13 -0500 +Subject: [PATCH] net: skbuff: use debug objects to track skb allocations + +* tracks skb allocations and frees and warns / errors if + re-use occurs +* init/destroy for slab allocations +* activate/deactivate for in use + +Change-Id: Ia2dd0c7549d765a282295daf27bee6f99e5c7a43 +Signed-off-by: Matthew McClintock +Signed-off-by: Casey Chen +Signed-off-by: Tian Yang +--- + MAINTAINERS | 1 + + lib/Kconfig.debug | 6 ++++++ + net/core/Makefile | 1 + + net/core/dev.c | 1 + + net/core/skbuff.c | 9 ++++++++- + 5 files changed, 17 insertions(+), 1 deletion(-) + +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -147,6 +147,7 @@ SKB RECYCLER SUPPORT + M: Casey Chen + S: Maintained + F: net/core/skbuff_recycle.* ++F: net/core/skbuff_debug.* + + 3C59X NETWORK DRIVER + M: Steffen Klassert +--- a/lib/Kconfig.debug ++++ b/lib/Kconfig.debug +@@ -710,6 +710,12 @@ config DEBUG_OBJECTS_PERCPU_COUNTER + percpu counter routines to track the life time of percpu counter + objects and validate the percpu counter operations. + ++config DEBUG_OBJECTS_SKBUFF ++ bool "Debug sk_buff allocations" ++ depends on DEBUG_OBJECTS ++ help ++ Enable this to turn on debugging of sk_buff's (incl. recycler) ++ + config DEBUG_OBJECTS_ENABLE_DEFAULT + int "debug_objects bootup default value (0-1)" + range 0 1 +--- a/net/core/Makefile ++++ b/net/core/Makefile +@@ -41,3 +41,4 @@ obj-$(CONFIG_BPF_SYSCALL) += sock_map.o + obj-$(CONFIG_BPF_SYSCALL) += bpf_sk_storage.o + obj-$(CONFIG_OF) += of_net.o + obj-$(CONFIG_SKB_RECYCLER) += skbuff_recycle.o ++obj-$(CONFIG_DEBUG_OBJECTS_SKBUFF) += skbuff_debug.o +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -153,6 +153,7 @@ + + #include "dev.h" + #include "net-sysfs.h" ++#include "skbuff_debug.h" + + + static DEFINE_SPINLOCK(ptype_lock); +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -110,6 +110,7 @@ struct kmem_cache *skb_data_cache; + #endif + + #include "skbuff_recycle.h" ++#include "skbuff_debug.h" + + struct kmem_cache *skbuff_head_cache __ro_after_init; + static struct kmem_cache *skbuff_fclone_cache __ro_after_init; +@@ -320,8 +321,8 @@ static void __build_skb_around(struct sk + shinfo = skb_shinfo(skb); + memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); + atomic_set(&shinfo->dataref, 1); +- + skb_set_kcov_handle(skb, kcov_common_handle()); ++ skbuff_debugobj_init_and_activate(skb); + } + + /** +@@ -575,6 +576,7 @@ struct sk_buff *__alloc_skb(unsigned int + refcount_set(&fclones->fclone_ref, 1); + } + ++ skbuff_debugobj_init_and_activate(skb); + return skb; + + nodata: +@@ -881,6 +883,7 @@ void kfree_skbmem(struct sk_buff *skb) + + switch (skb->fclone) { + case SKB_FCLONE_UNAVAILABLE: ++ skbuff_debugobj_deactivate(skb); + kmem_cache_free(skbuff_head_cache, skb); + return; + +@@ -901,7 +904,9 @@ void kfree_skbmem(struct sk_buff *skb) + } + if (!refcount_dec_and_test(&fclones->fclone_ref)) + return; ++ + fastpath: ++ skbuff_debugobj_deactivate(&fclones->skb1); + kmem_cache_free(skbuff_fclone_cache, fclones); + } + +@@ -1765,6 +1770,7 @@ struct sk_buff *skb_clone(struct sk_buff + return NULL; + + n->fclone = SKB_FCLONE_UNAVAILABLE; ++ skbuff_debugobj_init_and_activate(n); + } + + return __skb_clone(n, skb); +@@ -5523,6 +5529,7 @@ void kfree_skb_partial(struct sk_buff *s + if (head_stolen) { + skb_release_head_state(skb); + kmem_cache_free(skbuff_head_cache, skb); ++ skbuff_debugobj_deactivate(skb); + } else { + __kfree_skb(skb); + } diff --git a/target/linux/qualcommax/patches-6.1/9990-0373-skbuff_debug-move-activate-deactivate-sites.patch b/target/linux/qualcommax/patches-6.1/9990-0373-skbuff_debug-move-activate-deactivate-sites.patch new file mode 100644 index 00000000000000..3617ae55bc1cbc --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/9990-0373-skbuff_debug-move-activate-deactivate-sites.patch @@ -0,0 +1,75 @@ +From 73886237a0742a19bb0630820829972c39c1e80e Mon Sep 17 00:00:00 2001 +From: Tian Yang +Date: Tue, 29 Dec 2015 13:02:21 -0600 +Subject: [PATCH] skbuff_debug: move activate/deactivate sites + +This way we can see if next/prev in SKB was changed +while the SKB was not being used. + +Change-Id: I281267e230d3406181a07d095a76ae6bc58e2c8d +Signed-off-by: Matthew McClintock +Signed-off-by: Casey Chen +Signed-off-by: Tian Yang +--- + net/core/skbuff.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -322,7 +322,6 @@ static void __build_skb_around(struct sk + memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); + atomic_set(&shinfo->dataref, 1); + skb_set_kcov_handle(skb, kcov_common_handle()); +- skbuff_debugobj_init_and_activate(skb); + } + + /** +@@ -351,6 +350,7 @@ struct sk_buff *__build_skb(void *data, + skb = kmem_cache_alloc(skbuff_head_cache, GFP_ATOMIC); + if (unlikely(!skb)) + return NULL; ++ skbuff_debugobj_init_and_activate(skb); + + memset(skb, 0, offsetof(struct sk_buff, tail)); + __build_skb_around(skb, data, frag_size); +@@ -542,6 +542,7 @@ struct sk_buff *__alloc_skb(unsigned int + skb = kmem_cache_alloc_node(cache, gfp_mask & ~GFP_DMA, node); + if (unlikely(!skb)) + return NULL; ++ skbuff_debugobj_init_and_activate(skb); + prefetchw(skb); + + /* We do our best to align skb_shared_info on a separate cache +@@ -576,10 +577,10 @@ struct sk_buff *__alloc_skb(unsigned int + refcount_set(&fclones->fclone_ref, 1); + } + +- skbuff_debugobj_init_and_activate(skb); + return skb; + + nodata: ++ skbuff_debugobj_deactivate(skb); + kmem_cache_free(cache, skb); + return NULL; + } +@@ -1768,9 +1769,9 @@ struct sk_buff *skb_clone(struct sk_buff + n = kmem_cache_alloc(skbuff_head_cache, gfp_mask); + if (!n) + return NULL; ++ skbuff_debugobj_init_and_activate(n); + + n->fclone = SKB_FCLONE_UNAVAILABLE; +- skbuff_debugobj_init_and_activate(n); + } + + return __skb_clone(n, skb); +@@ -5528,8 +5529,8 @@ void kfree_skb_partial(struct sk_buff *s + { + if (head_stolen) { + skb_release_head_state(skb); +- kmem_cache_free(skbuff_head_cache, skb); + skbuff_debugobj_deactivate(skb); ++ kmem_cache_free(skbuff_head_cache, skb); + } else { + __kfree_skb(skb); + } diff --git a/target/linux/qualcommax/patches-6.1/9990-0374-skbuff_debug-track-alloc-and-free-complete-stacks.patch b/target/linux/qualcommax/patches-6.1/9990-0374-skbuff_debug-track-alloc-and-free-complete-stacks.patch new file mode 100644 index 00000000000000..d6cc5e4c87278e --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/9990-0374-skbuff_debug-track-alloc-and-free-complete-stacks.patch @@ -0,0 +1,28 @@ +From a7e6e645b640ed82ce6d6b2101e36694d5ef8cb3 Mon Sep 17 00:00:00 2001 +From: Tian Yang +Date: Tue, 29 Dec 2015 14:04:41 -0600 +Subject: [PATCH] skbuff_debug: track alloc and free complete stacks + +This adds support to record a complete stack trace for all +alloc's and free's of SKBs. + +Change-Id: I81fc76240d49d18035e99c234abcb8e4b9cb14a5 +Signed-off-by: Matthew McClintock +Signed-off-by: Casey Chen +--- + include/linux/skbuff.h | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -1064,7 +1064,9 @@ struct sk_buff { + #endif + + #ifdef CONFIG_DEBUG_OBJECTS_SKBUFF +- void *free_addr; ++#define DEBUG_OBJECTS_SKBUFF_STACKSIZE 20 ++ void *free_addr[DEBUG_OBJECTS_SKBUFF_STACKSIZE]; ++ void *alloc_addr[DEBUG_OBJECTS_SKBUFF_STACKSIZE]; + #endif + }; + diff --git a/target/linux/qualcommax/patches-6.1/9990-0375-skbuff_debug-track-sum-of-skb-while-not-in-use.patch b/target/linux/qualcommax/patches-6.1/9990-0375-skbuff_debug-track-sum-of-skb-while-not-in-use.patch new file mode 100644 index 00000000000000..f035bbf3e5c4f3 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/9990-0375-skbuff_debug-track-sum-of-skb-while-not-in-use.patch @@ -0,0 +1,29 @@ +From 1e47f8144d8ff9954e693efa87cf8cc015c28bd2 Mon Sep 17 00:00:00 2001 +From: Tian Yang +Date: Tue, 29 Dec 2015 15:20:54 -0600 +Subject: [PATCH] skbuff_debug: track sum of skb while not in use + +Add a simple sum check across the range of the SKB struct +to see if something else modified after it was freed to the +SKB recycler. + +Right now, we just check for the SKB recycler as freeing to +the slab tends to let other changes to the struct occur. + +Change-Id: I41b4163bf735cc047dd7150cb009098665c9b94e +Signed-off-by: Matthew McClintock +Signed-off-by: Casey Chen +--- + include/linux/skbuff.h | 1 + + 1 file changed, 1 insertion(+) + +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -1067,6 +1067,7 @@ struct sk_buff { + #define DEBUG_OBJECTS_SKBUFF_STACKSIZE 20 + void *free_addr[DEBUG_OBJECTS_SKBUFF_STACKSIZE]; + void *alloc_addr[DEBUG_OBJECTS_SKBUFF_STACKSIZE]; ++ u32 sum; + #endif + }; + diff --git a/target/linux/qualcommax/patches-6.1/9990-0376-Add-notifier-interface.patch b/target/linux/qualcommax/patches-6.1/9990-0376-Add-notifier-interface.patch new file mode 100644 index 00000000000000..cd3b81777e15ad --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/9990-0376-Add-notifier-interface.patch @@ -0,0 +1,116 @@ +From 1d79518dee2de6f5ad72c13bd291077e3a06acbf Mon Sep 17 00:00:00 2001 +From: Tian Yang +Date: Thu, 27 Oct 2016 11:46:24 -0500 +Subject: [PATCH] Add notifier interface + +Add a notifier interface for the SKB recycler. This notifier will +propagate events related to skb problems (double free, double alloc, +checksum mismatch). + +The following change is merged together: + + Don't call BUG_ON in the notifier + + The notifier was meant to be terminal, i.e. after propagating the + event it stops the system. + This is causing confusion however, under the assumption that there is + an actual problem in the notifier code. + + This commit removes the BUG_ON call in the notifier, so that the event + originator gets to stop the system (as it was done before the notifier + was introduced). + + Change Id: I5a7af0374dc4991539d742712331de03aa3833d1 + Author and Committer: Cristian Prundeanu + +Change-Id: I35262581ad964ef97d21946a965170531ca9034f +Signed-off-by: Cristian Prundeanu +Signed-off-by: Casey Chen +Signed-off-by: Tian Yang +--- + MAINTAINERS | 1 + + include/linux/debugobjects.h | 14 ++++++++------ + lib/debugobjects.c | 23 +++++++++++++++++++++++ + net/core/Makefile | 2 +- + 4 files changed, 33 insertions(+), 7 deletions(-) + +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -148,6 +148,7 @@ M: Casey Chen + S: Maintained + F: net/core/skbuff_recycle.* + F: net/core/skbuff_debug.* ++F: net/core/skbuff_notifier.* + + 3C59X NETWORK DRIVER + M: Steffen Klassert +--- a/include/linux/debugobjects.h ++++ b/include/linux/debugobjects.h +@@ -66,12 +66,13 @@ struct debug_obj_descr { + #ifdef CONFIG_DEBUG_OBJECTS + extern void debug_object_init (void *addr, const struct debug_obj_descr *descr); + extern void +-debug_object_init_on_stack(void *addr, const struct debug_obj_descr *descr); +-extern int debug_object_activate (void *addr, const struct debug_obj_descr *descr); +-extern void debug_object_deactivate(void *addr, const struct debug_obj_descr *descr); +-extern void debug_object_destroy (void *addr, const struct debug_obj_descr *descr); +-extern void debug_object_free (void *addr, const struct debug_obj_descr *descr); +-extern void debug_object_assert_init(void *addr, const struct debug_obj_descr *descr); ++debug_object_init_on_stack(void *addr, struct debug_obj_descr *descr); ++extern int debug_object_activate (void *addr, struct debug_obj_descr *descr); ++extern int debug_object_get_state(void *addr); ++extern void debug_object_deactivate(void *addr, struct debug_obj_descr *descr); ++extern void debug_object_destroy (void *addr, struct debug_obj_descr *descr); ++extern void debug_object_free (void *addr, struct debug_obj_descr *descr); ++extern void debug_object_assert_init(void *addr, struct debug_obj_descr *descr); + + /* + * Active state: +@@ -85,6 +86,7 @@ debug_object_active_state(void *addr, co + extern void debug_objects_early_init(void); + extern void debug_objects_mem_init(void); + #else ++static inline int debug_object_get_state(void *addr) { return 0; } + static inline void + debug_object_init (void *addr, const struct debug_obj_descr *descr) { } + static inline void +--- a/lib/debugobjects.c ++++ b/lib/debugobjects.c +@@ -493,6 +493,29 @@ static struct debug_bucket *get_bucket(u + return &obj_hash[hash]; + } + ++/* ++ * debug_object_get_state(): ++ * returns the state of an object given an address ++ */ ++int debug_object_get_state(void *addr) ++{ ++ struct debug_bucket *db; ++ struct debug_obj *obj; ++ unsigned long flags; ++ enum debug_obj_state state = ODEBUG_STATE_NOTAVAILABLE; ++ ++ db = get_bucket((unsigned long) addr); ++ ++ raw_spin_lock_irqsave(&db->lock, flags); ++ obj = lookup_object(addr, db); ++ if (obj) ++ state = obj->state; ++ raw_spin_unlock_irqrestore(&db->lock, flags); ++ ++ return state; ++} ++EXPORT_SYMBOL(debug_object_get_state); ++ + static void debug_print_object(struct debug_obj *obj, char *msg) + { + const struct debug_obj_descr *descr = obj->descr; +--- a/net/core/Makefile ++++ b/net/core/Makefile +@@ -41,4 +41,4 @@ obj-$(CONFIG_BPF_SYSCALL) += sock_map.o + obj-$(CONFIG_BPF_SYSCALL) += bpf_sk_storage.o + obj-$(CONFIG_OF) += of_net.o + obj-$(CONFIG_SKB_RECYCLER) += skbuff_recycle.o +-obj-$(CONFIG_DEBUG_OBJECTS_SKBUFF) += skbuff_debug.o ++obj-$(CONFIG_DEBUG_OBJECTS_SKBUFF) += skbuff_debug.o skbuff_notifier.o diff --git a/target/linux/qualcommax/patches-6.1/9990-0377-net-Check-if-sk_buff-head-is-valid-in-consume_skb.patch b/target/linux/qualcommax/patches-6.1/9990-0377-net-Check-if-sk_buff-head-is-valid-in-consume_skb.patch new file mode 100644 index 00000000000000..d12ccba300bff7 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/9990-0377-net-Check-if-sk_buff-head-is-valid-in-consume_skb.patch @@ -0,0 +1,51 @@ +From 7913da3088d10013c5e447547cc247b4d126ed73 Mon Sep 17 00:00:00 2001 +From: Vivek Nataraja +Date: Mon, 29 Jun 2015 11:31:50 +0530 +Subject: [PATCH] net: Check if sk_buff head is valid in consume_skb() + +Commit (0ebd0ac net: add function to allocate sk_buff head +without data area) changes skb_release_all() to check if the +skb has a data area to allow the skb destructor to clear the +data pointer in case only a head has been allocated. + +This was later fixed to check skb->head instead of skb->data +in 'commit 5e71d9d77c07 ("net: fix sk_buff head without data area")'. +as skb->head points to the beginning of the data area. + +Since, this was done only in kfree_skb path and not in consume_skb +path, this leads to kernel panic in some cases. + +Also, since skb_shared_info is not initialized in such skbs, +accessing that in skb_recycler_consume() leads to kernel panic. + +Fix this by checking if skb->head is valid in both the cases. + +Change-Id: Iad9fcbaa91f5f1d1b8b00b88ae279b52db385f0c +Signed-off-by: Vivek Nataraja +Signed-off-by: Casey Chen +--- + net/core/skbuff.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -1131,7 +1131,7 @@ void consume_skb(struct sk_buff *skb) + * for us to recycle this one later than to allocate a new one + * from scratch. + */ +- if (likely(skb_recycler_consume(skb))) ++ if (likely(skb->head) && likely(skb_recycler_consume(skb))) + return; + + trace_consume_skb(skb); +@@ -1140,7 +1140,9 @@ void consume_skb(struct sk_buff *skb) + * have done in __kfree_skb (above and beyond the skb_release_head_state + * that we already did). + */ +- skb_release_data(skb); ++ if (likely(skb->head)) ++ skb_release_data(skb); ++ + kfree_skbmem(skb); + } + EXPORT_SYMBOL(consume_skb); diff --git a/target/linux/qualcommax/patches-6.1/9990-0378-net-core-Disable-page-frag-allocations-for-SKB-for-2.patch b/target/linux/qualcommax/patches-6.1/9990-0378-net-core-Disable-page-frag-allocations-for-SKB-for-2.patch new file mode 100644 index 00000000000000..665877a3d6d685 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/9990-0378-net-core-Disable-page-frag-allocations-for-SKB-for-2.patch @@ -0,0 +1,69 @@ +From 0d2da79c9c91c3ecd79feeafbab850eacd26a43e Mon Sep 17 00:00:00 2001 +From: Tian Yang +Date: Tue, 30 Apr 2019 18:43:02 +0530 +Subject: [PATCH] net core: Disable page frag allocations for SKB for 256MB + profile + +For low memory profiles such as 256MB, using __alloc_page_frag() +for skb allocations can potentially cause pages to be held up +for longer duration without getting freed by the kernel memory +manageer. This can potentially cause out-of-memory situaions. +This patch disabled page frag based SKB allocations for such +low memory profiles. + +Change-Id: Ibc674ad8b46211b8394f0bf7db55366d7210bb01 +Signed-off-by: Adil irfan +Signed-off-by: Kiran Kumar C.S.K +--- + net/Kconfig | 8 +++++++- + net/core/skbuff.c | 8 +++++++- + 2 files changed, 14 insertions(+), 2 deletions(-) + +--- a/net/Kconfig ++++ b/net/Kconfig +@@ -341,12 +341,18 @@ config SKB_RECYCLER + routing workloads. It can reduce skbuff freeing or + reallocation overhead. + +- + config SKB_RECYCLER_MULTI_CPU + bool "Cross-CPU recycling for CPU-locked workloads" + depends on SMP && SKB_RECYCLER + default n + ++config ALLOC_SKB_PAGE_FRAG_DISABLE ++ bool "Disable page fragment based skbuff payload allocations" ++ depends on !SKB_RECYCLER ++ default n ++ help ++ Disable page fragment based allocations for skbuff payloads. ++ + menu "Network testing" + + config NET_PKTGEN +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -622,16 +622,22 @@ struct sk_buff *__netdev_alloc_skb(struc + #else + struct page_frag_cache *nc; + bool pfmemalloc; ++ bool page_frag_alloc_enable = true; + void *data; + + len += NET_SKB_PAD; + ++ ++#ifdef CONFIG_ALLOC_SKB_PAGE_FRAG_DISABLE ++ page_frag_alloc_enable = false; ++#endif + /* If requested length is either too small or too big, + * we use kmalloc() for skb->head allocation. + */ + if (len <= SKB_WITH_OVERHEAD(1024) || + len > SKB_WITH_OVERHEAD(PAGE_SIZE) || +- (gfp_mask & (__GFP_DIRECT_RECLAIM | GFP_DMA))) { ++ (gfp_mask & (__GFP_DIRECT_RECLAIM | GFP_DMA)) || ++ !page_frag_alloc_enable) { + skb = __alloc_skb(len, gfp_mask, SKB_ALLOC_RX, NUMA_NO_NODE); + if (!skb) + goto skb_fail; diff --git a/target/linux/qualcommax/patches-6.1/9990-0422-net-Fix-kernel-option-check-to-enable-skb-recycler-c.patch b/target/linux/qualcommax/patches-6.1/9990-0422-net-Fix-kernel-option-check-to-enable-skb-recycler-c.patch new file mode 100644 index 00000000000000..b21a4c7b818013 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/9990-0422-net-Fix-kernel-option-check-to-enable-skb-recycler-c.patch @@ -0,0 +1,54 @@ +From cd9333020eac302df781f2e7dd715cd9b10aff0a Mon Sep 17 00:00:00 2001 +From: Swati Singh +Date: Tue, 22 Aug 2023 17:39:12 +0530 +Subject: [PATCH] net: Fix kernel option check to enable skb recycler code + +Use CONFIG_SKB_RECYCLER instead of CONFIG_TRACEPOINTS. + +Change-Id: Iad2d11ec90a305f8b170a15c7addb4d3e031adc3 +Signed-off-by: Swati Singh +--- + include/linux/skbuff.h | 2 +- + net/core/skbuff.c | 5 ++--- + 2 files changed, 3 insertions(+), 4 deletions(-) + +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -1247,7 +1247,7 @@ static inline void kfree_skb_list(struct + kfree_skb_list_reason(segs, SKB_DROP_REASON_NOT_SPECIFIED); + } + +-#ifdef CONFIG_TRACEPOINTS ++#ifdef CONFIG_SKB_RECYCLER + void consume_skb(struct sk_buff *skb); + #else + static inline void consume_skb(struct sk_buff *skb) +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -1099,7 +1099,6 @@ void skb_tx_error(struct sk_buff *skb) + } + EXPORT_SYMBOL(skb_tx_error); + +-#ifdef CONFIG_TRACEPOINTS + /** + * consume_skb - free an skbuff + * @skb: buffer to free +@@ -1140,8 +1139,9 @@ void consume_skb(struct sk_buff *skb) + if (likely(skb->head) && likely(skb_recycler_consume(skb))) + return; + ++#ifdef CONFIG_TRACEPOINTS + trace_consume_skb(skb); +- ++#endif + /* We're not recycling so now we need to do the rest of what we would + * have done in __kfree_skb (above and beyond the skb_release_head_state + * that we already did). +@@ -1152,7 +1152,6 @@ void consume_skb(struct sk_buff *skb) + kfree_skbmem(skb); + } + EXPORT_SYMBOL(consume_skb); +-#endif + + /** + * __consume_stateless_skb - free an skbuff, assuming it is stateless diff --git a/target/linux/qualcommax/patches-6.1/9990-0429-net-skbuff-Fix-compile-error-when-recycler-is-disabl.patch b/target/linux/qualcommax/patches-6.1/9990-0429-net-skbuff-Fix-compile-error-when-recycler-is-disabl.patch new file mode 100644 index 00000000000000..19e631145d637b --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/9990-0429-net-skbuff-Fix-compile-error-when-recycler-is-disabl.patch @@ -0,0 +1,32 @@ +From 1c46d6dbc82a65198344424a736b9800d1387213 Mon Sep 17 00:00:00 2001 +From: Swati Singh +Date: Tue, 5 Sep 2023 10:08:26 +0530 +Subject: [PATCH] net: skbuff: Fix compile error when recycler is disabled + +consume_skb recycle function should be enclosed within +CONFIG_SKB_RECYCLER macro. + +Change-Id: I1703919d8da10102951ec3795eb63cf7ecf9a44b +Signed-off-by: Swati Singh +--- + net/core/skbuff.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -1107,6 +1107,7 @@ EXPORT_SYMBOL(skb_tx_error); + * Functions identically to kfree_skb, but kfree_skb assumes that the frame + * is being dropped after a failure and notes that + */ ++#ifdef CONFIG_SKB_RECYCLER + void consume_skb(struct sk_buff *skb) + { + if (!skb_unref(skb)) +@@ -1152,6 +1153,7 @@ void consume_skb(struct sk_buff *skb) + kfree_skbmem(skb); + } + EXPORT_SYMBOL(consume_skb); ++#endif + + /** + * __consume_stateless_skb - free an skbuff, assuming it is stateless diff --git a/target/linux/qualcommax/patches-6.1/9990-0444-net-prefetch-skb-while-dequeuing-from-backlog-list.patch b/target/linux/qualcommax/patches-6.1/9990-0444-net-prefetch-skb-while-dequeuing-from-backlog-list.patch new file mode 100644 index 00000000000000..341f95da7390bf --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/9990-0444-net-prefetch-skb-while-dequeuing-from-backlog-list.patch @@ -0,0 +1,31 @@ +From 636896a375ffbc62f0ef6c10d8102854021e3c4d Mon Sep 17 00:00:00 2001 +From: KRITHI D SHETTY +Date: Thu, 7 Sep 2023 10:47:59 +0530 +Subject: [PATCH] net: prefetch skb while dequeuing from backlog list. + +Change-Id: I01f1fdadd643a8f2850587200b0133c4c5984f26 +Signed-off-by: KRITHI D SHETTY +--- + net/core/dev.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -5975,10 +5975,16 @@ static int process_backlog(struct napi_s + + napi->weight = READ_ONCE(dev_rx_weight); + while (again) { +- struct sk_buff *skb; ++ struct sk_buff *skb, *next_skb; + + while ((skb = __skb_dequeue(&sd->process_queue))) { + rcu_read_lock(); ++ ++ next_skb = skb_peek(&sd->process_queue); ++ if (likely(next_skb)) { ++ prefetch(next_skb->data); ++ } ++ + __netif_receive_skb(skb); + rcu_read_unlock(); + input_queue_head_incr(sd); diff --git a/target/linux/qualcommax/patches-6.1/9990-0498-skbuff-Fix-the-skb-allocation-to-allocate-the-skbs-f.patch b/target/linux/qualcommax/patches-6.1/9990-0498-skbuff-Fix-the-skb-allocation-to-allocate-the-skbs-f.patch new file mode 100644 index 00000000000000..11603dfc54b7a4 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/9990-0498-skbuff-Fix-the-skb-allocation-to-allocate-the-skbs-f.patch @@ -0,0 +1,158 @@ +From 475bbd3c053a0ed73ed33e41eb7a620a01f583cb Mon Sep 17 00:00:00 2001 +From: Manish Verma +Date: Tue, 10 Oct 2023 22:35:14 +0530 +Subject: [PATCH] [skbuff] Fix the skb allocation to allocate the skbs from the + SKB SLAB + +Due to the kmalloc_size_roundup() function added in the __alloc_skb() +API in 6.1, this API is not allocating the SKBs from the NSS +SKB SLAB area even when the request size is SKB_DATA_CACHE_SIZE. + +This change is deferring the kmalloc_size_roundup() function call after +the SKB is allocated from the NSS SKB SLAB. + +Change-Id: Ic6d75d66163f677b12c915ee26afbbcb26536512 +Signed-off-by: Manish Verma +--- + net/core/skbuff.c | 61 +++++++++++++++++++++++++++-------------------- + 1 file changed, 35 insertions(+), 26 deletions(-) + +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -454,41 +454,47 @@ EXPORT_SYMBOL(napi_build_skb); + * memory is free + */ + static void *kmalloc_reserve(unsigned int *size, gfp_t flags, int node, +- bool *pfmemalloc) +-{ +- bool ret_pfmemalloc = false; +- size_t obj_size; +- void *obj; ++ bool *pfmemalloc) ++ { ++ void *obj; ++ bool ret_pfmemalloc = false; ++ unsigned int obj_size = *size; + +- obj_size = SKB_HEAD_ALIGN(*size); ++ if (obj_size > SZ_2K && obj_size <= SKB_DATA_CACHE_SIZE) { ++ obj = kmem_cache_alloc_node(skb_data_cache, ++ flags | __GFP_NOMEMALLOC | __GFP_NOWARN, ++ node); ++ *size = SKB_DATA_CACHE_SIZE; ++ if (obj || !(gfp_pfmemalloc_allowed(flags))) ++ goto out; ++ ++ /* Try again but now we are using pfmemalloc reserves */ ++ ret_pfmemalloc = true; ++ obj = kmem_cache_alloc_node(skb_data_cache, flags, node); ++ goto out; ++ } + + obj_size = kmalloc_size_roundup(obj_size); +- /* The following cast might truncate high-order bits of obj_size, this +- * is harmless because kmalloc(obj_size >= 2^32) will fail anyway. +- */ +- *size = (unsigned int)obj_size; + + /* +- * Try a regular allocation, when that fails and we're not entitled +- * to the reserves, fail. ++ * The following cast might truncate high-order bits of obj_size, this ++ * is harmless because kmalloc(obj_size >= 2^32) will fail anyway. + */ +- if (obj_size > SZ_2K && obj_size <= SKB_DATA_CACHE_SIZE) +- obj = kmem_cache_alloc_node(skb_data_cache, +- flags | __GFP_NOMEMALLOC | __GFP_NOWARN, +- node); +- else +- obj = kmalloc_node_track_caller(obj_size, +- flags | __GFP_NOMEMALLOC | __GFP_NOWARN, +- node); +- if (obj || !(gfp_pfmemalloc_allowed(flags))) +- goto out; ++ *size = (unsigned int)obj_size; + +- /* Try again but now we are using pfmemalloc reserves */ +- ret_pfmemalloc = true; +- if (obj_size > SZ_2K && obj_size <= SKB_DATA_CACHE_SIZE) +- obj = kmem_cache_alloc_node(skb_data_cache, flags, node); +- else +- obj = kmalloc_node_track_caller(obj_size, flags, node); ++ /* ++ * Try a regular allocation, when that fails and we're not entitled ++ * to the reserves, fail. ++ */ ++ obj = kmalloc_node_track_caller(obj_size, ++ flags | __GFP_NOMEMALLOC | __GFP_NOWARN, ++ node); ++ if (obj || !(gfp_pfmemalloc_allowed(flags))) ++ goto out; ++ ++ /* Try again but now we are using pfmemalloc reserves */ ++ ret_pfmemalloc = true; ++ obj = kmalloc_node_track_caller(obj_size, flags, node); + + out: + if (pfmemalloc) +@@ -550,10 +556,12 @@ struct sk_buff *__alloc_skb(unsigned int + * aligned memory blocks, unless SLUB/SLAB debug is enabled. + * Both skb->head and skb_shared_info are cache line aligned. + */ ++ size = SKB_DATA_ALIGN(size); ++ size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + data = kmalloc_reserve(&size, gfp_mask, node, &pfmemalloc); + if (unlikely(!data)) + goto nodata; +- /* kmalloc_size_roundup() might give us more room than requested. ++ /* kmalloc_reserve(size) might give us more room than requested. + * Put skb_shared_info exactly at the end of allocated zone, + * to allow max possible filling before reallocation. + */ +@@ -644,7 +652,8 @@ struct sk_buff *__netdev_alloc_skb(struc + goto skb_success; + } + +- len = SKB_HEAD_ALIGN(len); ++ len += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); ++ len = SKB_DATA_ALIGN(len); + + if (sk_memalloc_socks()) + gfp_mask |= __GFP_MEMALLOC; +@@ -744,7 +753,8 @@ struct sk_buff *__napi_alloc_skb(struct + data = page_frag_alloc_1k(&nc->page_small, gfp_mask); + pfmemalloc = NAPI_SMALL_PAGE_PFMEMALLOC(nc->page_small); + } else { +- len = SKB_HEAD_ALIGN(len); ++ len += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); ++ len = SKB_DATA_ALIGN(len); + + data = page_frag_alloc(&nc->page, len, gfp_mask); + pfmemalloc = nc->page.pfmemalloc; +@@ -1958,6 +1968,8 @@ int pskb_expand_head(struct sk_buff *skb + if (skb_pfmemalloc(skb)) + gfp_mask |= __GFP_MEMALLOC; + ++ size = SKB_DATA_ALIGN(size); ++ size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + data = kmalloc_reserve(&size, gfp_mask, NUMA_NO_NODE, NULL); + if (!data) + goto nodata; +@@ -6333,6 +6345,8 @@ static int pskb_carve_inside_header(stru + if (skb_pfmemalloc(skb)) + gfp_mask |= __GFP_MEMALLOC; + ++ size = SKB_DATA_ALIGN(size); ++ size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + data = kmalloc_reserve(&size, gfp_mask, NUMA_NO_NODE, NULL); + if (!data) + return -ENOMEM; +@@ -6449,6 +6463,8 @@ static int pskb_carve_inside_nonlinear(s + if (skb_pfmemalloc(skb)) + gfp_mask |= __GFP_MEMALLOC; + ++ size = SKB_DATA_ALIGN(size); ++ size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + data = kmalloc_reserve(&size, gfp_mask, NUMA_NO_NODE, NULL); + if (!data) + return -ENOMEM; diff --git a/target/linux/qualcommax/patches-6.1/9990-0527-net-Fix-the-crash-in-skbuff.c-for-debug-build.patch b/target/linux/qualcommax/patches-6.1/9990-0527-net-Fix-the-crash-in-skbuff.c-for-debug-build.patch new file mode 100644 index 00000000000000..f73753c65ad2a7 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/9990-0527-net-Fix-the-crash-in-skbuff.c-for-debug-build.patch @@ -0,0 +1,26 @@ +From 9bdf7a1d0a1cb12e4e1036b1514c64872bbdafee Mon Sep 17 00:00:00 2001 +From: Pavithra R +Date: Fri, 3 Nov 2023 22:43:32 +0530 +Subject: [PATCH] net: Fix the crash in skbuff.c for debug build + +When skb is allocated in NAPI context we aren't +initializing and activating the skb object. Add support +for init and activating skb in napi_build_skb. + +Change-Id: Idcc3d6c260831be12ec85df474bcdc17f86d3292 +Signed-off-by: Pavithra R +--- + net/core/skbuff.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -417,6 +417,8 @@ static struct sk_buff *__napi_build_skb( + if (unlikely(!skb)) + return NULL; + ++ skbuff_debugobj_init_and_activate(skb); ++ + memset(skb, 0, offsetof(struct sk_buff, tail)); + __build_skb_around(skb, data, frag_size); + diff --git a/target/linux/qualcommax/patches-6.1/9990-0558-net-Fix-the-crash-due-to-missing-skb-debug-deactivat.patch b/target/linux/qualcommax/patches-6.1/9990-0558-net-Fix-the-crash-due-to-missing-skb-debug-deactivat.patch new file mode 100644 index 00000000000000..da70404d62c05b --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/9990-0558-net-Fix-the-crash-due-to-missing-skb-debug-deactivat.patch @@ -0,0 +1,57 @@ +From 9f2362ee17aef209a42aa7a9f6f41ca2aa82d2eb Mon Sep 17 00:00:00 2001 +From: Pavithra R +Date: Wed, 22 Nov 2023 20:57:45 +0530 +Subject: [PATCH] net: Fix the crash due to missing skb debug deactivation + +Napi allocation and consume involves activation and deactivation of +skb. In napi_skb_finish function the deactivation was not happening. +The patch fixes the same. Also deactivation was missing in napi_consume_skb. + +Change-Id: I7ea2240c138ec2a4e2796e33f37b1ce923ca7a4d +Signed-off-by: Pavithra R +--- + net/core/gro.c | 6 ++++-- + net/core/skbuff.c | 2 ++ + 2 files changed, 6 insertions(+), 2 deletions(-) + +--- a/net/core/gro.c ++++ b/net/core/gro.c +@@ -3,6 +3,7 @@ + #include + #include + #include ++#include "skbuff_debug.h" + + #define MAX_GRO_SKBS 8 + +@@ -631,9 +632,10 @@ static gro_result_t napi_skb_finish(stru + break; + + case GRO_MERGED_FREE: +- if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD) ++ if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD) { ++ skbuff_debugobj_deactivate(skb); + napi_skb_free_stolen_head(skb); +- else if (skb->fclone != SKB_FCLONE_UNAVAILABLE) ++ } else if (skb->fclone != SKB_FCLONE_UNAVAILABLE) + __kfree_skb(skb); + else + __kfree_skb_defer(skb); +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -1202,6 +1202,7 @@ static void napi_skb_cache_put(struct sk + + void __kfree_skb_defer(struct sk_buff *skb) + { ++ skbuff_debugobj_deactivate(skb); + skb_release_all(skb); + napi_skb_cache_put(skb); + } +@@ -1240,6 +1241,7 @@ void napi_consume_skb(struct sk_buff *sk + return; + } + ++ skbuff_debugobj_deactivate(skb); + skb_release_all(skb); + napi_skb_cache_put(skb); + } From 09b52ea0a54f7d0ff2addee0be13c388ee85a82f Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 9 Mar 2024 14:34:34 -0500 Subject: [PATCH 132/225] ssdk: switch back to 3.0 from 3.1 This version is mostly for newer switches and doesn't bring anything new to existing switches. Switch back to version 3.0 to stay in sync with upstream. --- package/kernel/qca-ssdk/Makefile | 6 +++--- .../qca-ssdk/patches/0004-fix-compile-warnings.patch | 12 ++++++------ ...support-selecting-PCS-channel-for-PORT3-on-.patch | 8 +++++--- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/package/kernel/qca-ssdk/Makefile b/package/kernel/qca-ssdk/Makefile index ecb30ed49722b6..ca8b0a4bfea5aa 100644 --- a/package/kernel/qca-ssdk/Makefile +++ b/package/kernel/qca-ssdk/Makefile @@ -5,9 +5,9 @@ PKG_RELEASE:=5 PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/qca-ssdk.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2023-11-30 -PKG_SOURCE_VERSION:=3153d9068a87198dabf1b8f2c80801fd31a493b3 -PKG_MIRROR_HASH:=05595ba16b22873f5b52609a0ba316ee5264d7fe4ed5b2fb9198da7fe43e4a08 +PKG_SOURCE_DATE:=2023-10-04 +PKG_SOURCE_VERSION:=23a5aa4a4d5834da7a07efb58baebfbee91786b0 +PKG_MIRROR_HASH:=9d169ce924a46a4e530031061d3183b92f23c7f46b3106f0b9ba3587846a73ee PKG_FLAGS:=nonshared PKG_BUILD_PARALLEL:=1 diff --git a/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch b/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch index fa1cd895c2c0a5..caa4f37bf569d7 100644 --- a/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch +++ b/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch @@ -1,6 +1,6 @@ --- a/src/adpt/adpt.c +++ b/src/adpt/adpt.c -@@ -399,11 +399,6 @@ sw_error_t adpt_init(a_uint32_t dev_id, +@@ -394,11 +394,6 @@ sw_error_t adpt_init(a_uint32_t dev_id, #endif #endif #if defined(HPPE) @@ -45,12 +45,12 @@ --- a/Makefile +++ b/Makefile -@@ -27,7 +27,7 @@ all: $(BIN_DIR) kslib - # LNX Modules-Style Makefile +@@ -18,7 +18,7 @@ include $(PRJ_PATH)/Makefile.modules + # SSDK-Style Makefile #################################################################### - modules: $(BIN_DIR) kslib_c -- mkdir -p ./temp/;cp * ./temp -a;cd ./temp;cp ../Makefile.modules ./Makefile; + all: $(BIN_DIR) kslib +- mkdir -p ./temp/;cd ./temp;cp ../build/bin/ssdk_ks_km.a ./;ar -x ssdk_ks_km.a; cp ../ko_Makefile ./Makefile; + mkdir -p ./temp/;cp app config include ko_Makefile make Makefile.modules src ./temp -a;cd ./temp;cp ../Makefile.modules ./Makefile; - make -C $(SYS_PATH) M=$(PRJ_PATH)/temp $(LNX_MAKEOPTS) modules + $(MAKE) $(PKG_JOBS) -C $(SYS_PATH) M=$(PRJ_PATH)/temp/ CROSS_COMPILE=$(TOOLPREFIX) modules cp $(PRJ_PATH)/temp/Module.symvers $(PRJ_PATH)/Module.symvers; cp temp/*.ko build/bin; diff --git a/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch b/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch index 9711330a411eed..e56e754fad8689 100644 --- a/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch +++ b/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch @@ -24,7 +24,7 @@ Signed-off-by: Mantas Pucka --- a/include/init/ssdk_dts.h +++ b/include/init/ssdk_dts.h -@@ -99,6 +99,7 @@ typedef struct +@@ -101,6 +101,7 @@ typedef struct a_uint32_t emu_chip_ver; /*only valid when is_emulation is true*/ a_uint32_t clk_mode; a_uint32_t pcie_hw_base; @@ -92,10 +92,11 @@ Signed-off-by: Mantas Pucka +a_uint32_t ssdk_dts_port3_pcs_channel_get(a_uint32_t dev_id) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; -+ ++ + return cfg->port3_pcs_channel; +} + + #ifndef BOARD_AR71XX #if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) static void ssdk_dt_parse_mac_mode(a_uint32_t dev_id, @@ -306,6 +313,25 @@ static void ssdk_dt_parse_mac_mode(a_uin @@ -108,7 +109,7 @@ Signed-off-by: Mantas Pucka +{ + const __be32 *port3_pcs_channel; + a_uint32_t len = 0; -+ ++ + port3_pcs_channel = of_get_property(switch_node, "port3_pcs_channel", &len); + if (!port3_pcs_channel) { + ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->port3_pcs_channel = 2; @@ -132,3 +133,4 @@ Signed-off-by: Mantas Pucka ssdk_dt_parse_mdio(*dev_id, switch_node, cfg); ssdk_dt_parse_port_bmp(*dev_id, switch_node, cfg); ssdk_dt_parse_interrupt(*dev_id, switch_node); + From 1c9999743b2807e679cdec404edac358327d8d23 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 9 Mar 2024 15:02:07 -0500 Subject: [PATCH 133/225] ssdk: fix parallel building --- package/kernel/qca-ssdk/Makefile | 8 +-- .../patches/0001-allow-parallel-build.patch | 57 +++++++++++++++++++ .../patches/0004-fix-compile-warnings.patch | 11 ---- 3 files changed, 61 insertions(+), 15 deletions(-) create mode 100644 package/kernel/qca-ssdk/patches/0001-allow-parallel-build.patch diff --git a/package/kernel/qca-ssdk/Makefile b/package/kernel/qca-ssdk/Makefile index ca8b0a4bfea5aa..58daf929ee284e 100644 --- a/package/kernel/qca-ssdk/Makefile +++ b/package/kernel/qca-ssdk/Makefile @@ -22,7 +22,7 @@ define KernelPackage/qca-ssdk SUBMENU:=Network Devices TITLE:=Qualcom SSDK switch driver DEPENDS:=@(TARGET_qualcommax) - FILES:=$(PKG_BUILD_DIR)/build/bin/qca-ssdk.ko + FILES:=$(PKG_BUILD_DIR)/qca-ssdk.ko AUTOLOAD:=$(call AutoLoad,30,qca-ssdk) endef @@ -32,7 +32,7 @@ endef GCC_VERSION=$(shell echo "$(CONFIG_GCC_VERSION)" | sed 's/[^0-9.]*\([0-9.]*\).*/\1/') -LNX_CONFIG_OPTS = LNX_MAKEOPTS='$(KERNEL_MAKEOPTS)' MODULE_TYPE=KSLIB modules +LNX_CONFIG_OPTS = LNX_MAKEOPTS='$(KERNEL_MAKEOPTS)' PRJ_PATH=$(PKG_BUILD_DIR) MODULE_TYPE=KSLIB modules MAKE_FLAGS+= \ TARGET_NAME=$(CONFIG_TARGET_NAME) \ @@ -54,13 +54,13 @@ ifeq ($(CONFIG_TARGET_SUBTARGET), "ipq807x") MAKE_FLAGS+= CHIP_TYPE=HPPE endif - ifeq ($(CONFIG_TARGET_SUBTARGET), "ipq60xx") MAKE_FLAGS+= CHIP_TYPE=CPPE endif + define Build/Compile - +$(MAKE) $(MAKE_FLAGS) -C $(PKG_BUILD_DIR) $(LNX_CONFIG_OPTS) + +$(MAKE) $(PKG_JOBS) $(MAKE_FLAGS) -C $(PKG_BUILD_DIR) $(LNX_CONFIG_OPTS) endef define Build/InstallDev diff --git a/package/kernel/qca-ssdk/patches/0001-allow-parallel-build.patch b/package/kernel/qca-ssdk/patches/0001-allow-parallel-build.patch new file mode 100644 index 00000000000000..7b5aed9f637293 --- /dev/null +++ b/package/kernel/qca-ssdk/patches/0001-allow-parallel-build.patch @@ -0,0 +1,57 @@ +--- a/Makefile ++++ b/Makefile +@@ -1,23 +1,25 @@ +-include ./config +- + ifndef PRJ_PATH + PRJ_PATH=$(shell pwd) + endif + export PRJ_PATH + +-include ./make/config.mk +-include ./make/tools.mk +-include ./make/$(OS)_opt.mk ++include $(PRJ_PATH)/config ++ ++include $(PRJ_PATH)/make/config.mk ++include $(PRJ_PATH)/make/tools.mk ++include $(PRJ_PATH)/make/$(OS)_opt.mk + + SUB_DIR=$(patsubst %/, %, $(dir $(wildcard src/*/Makefile))) + SUB_LIB=$(subst src/, , $(SUB_DIR)) + ++include $(PRJ_PATH)/Makefile.modules ++ + #################################################################### + # SSDK-Style Makefile + #################################################################### + all: $(BIN_DIR) kslib + mkdir -p ./temp/;cd ./temp;cp ../build/bin/ssdk_ks_km.a ./;ar -x ssdk_ks_km.a; cp ../ko_Makefile ./Makefile; +- make -C $(SYS_PATH) M=$(PRJ_PATH)/temp/ CROSS_COMPILE=$(TOOLPREFIX) modules ++ $(MAKE) $(PKG_JOBS) -C $(SYS_PATH) M=$(PRJ_PATH)/temp/ CROSS_COMPILE=$(TOOLPREFIX) modules + cp $(PRJ_PATH)/temp/Module.symvers $(PRJ_PATH)/Module.symvers; + cp temp/*.ko build/bin; + rm -Rf ./temp/*.o ./temp/*.ko ./temp/*.a +@@ -27,11 +29,7 @@ all: $(BIN_DIR) kslib + # LNX Modules-Style Makefile + #################################################################### + modules: $(BIN_DIR) kslib_c +- mkdir -p ./temp/;cp * ./temp -a;cd ./temp;cp ../Makefile.modules ./Makefile; +- make -C $(SYS_PATH) M=$(PRJ_PATH)/temp $(LNX_MAKEOPTS) modules +- cp $(PRJ_PATH)/temp/Module.symvers $(PRJ_PATH)/Module.symvers; +- cp temp/*.ko build/bin; +- rm -Rf ./temp/*.o ./temp/*.ko ./temp/*.a ++ @$(MAKE) -C $(SYS_PATH) M=$(PRJ_PATH) $(LNX_MAKEOPTS) modules + @echo "---Build [SSDK-$(VERSION)] at $(BUILD_DATE) finished." + + kslib_c: +--- a/make/linux_opt.mk ++++ b/make/linux_opt.mk +@@ -777,6 +777,6 @@ LOCAL_CFLAGS += $(CPU_CFLAG) -D"KBUILD_M + #################################################################### + # cflags for LNX Modules-Style Makefile + #################################################################### +-LNX_LOCAL_CFLAGS += $(MODULE_INC) $(MODULE_CFLAG) ${EXTRA_INC} -DFALLTHROUGH ++LNX_LOCAL_CFLAGS = $(MODULE_INC) $(MODULE_CFLAG) ${EXTRA_INC} -DFALLTHROUGH + export LNX_LOCAL_CFLAGS + diff --git a/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch b/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch index caa4f37bf569d7..48807888fb008a 100644 --- a/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch +++ b/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch @@ -43,14 +43,3 @@ { sw_error_t rv; ---- a/Makefile -+++ b/Makefile -@@ -18,7 +18,7 @@ include $(PRJ_PATH)/Makefile.modules - # SSDK-Style Makefile - #################################################################### - all: $(BIN_DIR) kslib -- mkdir -p ./temp/;cd ./temp;cp ../build/bin/ssdk_ks_km.a ./;ar -x ssdk_ks_km.a; cp ../ko_Makefile ./Makefile; -+ mkdir -p ./temp/;cp app config include ko_Makefile make Makefile.modules src ./temp -a;cd ./temp;cp ../Makefile.modules ./Makefile; - $(MAKE) $(PKG_JOBS) -C $(SYS_PATH) M=$(PRJ_PATH)/temp/ CROSS_COMPILE=$(TOOLPREFIX) modules - cp $(PRJ_PATH)/temp/Module.symvers $(PRJ_PATH)/Module.symvers; - cp temp/*.ko build/bin; From 8da30d81ed8dae1984ebb5668626d4904c28eeeb Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 9 Mar 2024 14:34:34 -0500 Subject: [PATCH 134/225] ssdk: switch back to NHSS.QSDK.12.4 NOTE: Incorrectly stated version 3.0 which is the SSDK version, and not 'NHSS.QSDK' version with is an entire release. SSDK version in NHSS.QSDK.12.4.5.r3 is mostly for newer switches and doesn't bring anything new to existing switches. Switch back to version NHSS.QSDK.12.4 to stay in sync with upstream. --- package/kernel/qca-ssdk/Makefile | 6 +++--- .../qca-ssdk/patches/0004-fix-compile-warnings.patch | 12 ++++++------ ...support-selecting-PCS-channel-for-PORT3-on-.patch | 8 +++++--- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/package/kernel/qca-ssdk/Makefile b/package/kernel/qca-ssdk/Makefile index ecb30ed49722b6..ca8b0a4bfea5aa 100644 --- a/package/kernel/qca-ssdk/Makefile +++ b/package/kernel/qca-ssdk/Makefile @@ -5,9 +5,9 @@ PKG_RELEASE:=5 PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/qca-ssdk.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2023-11-30 -PKG_SOURCE_VERSION:=3153d9068a87198dabf1b8f2c80801fd31a493b3 -PKG_MIRROR_HASH:=05595ba16b22873f5b52609a0ba316ee5264d7fe4ed5b2fb9198da7fe43e4a08 +PKG_SOURCE_DATE:=2023-10-04 +PKG_SOURCE_VERSION:=23a5aa4a4d5834da7a07efb58baebfbee91786b0 +PKG_MIRROR_HASH:=9d169ce924a46a4e530031061d3183b92f23c7f46b3106f0b9ba3587846a73ee PKG_FLAGS:=nonshared PKG_BUILD_PARALLEL:=1 diff --git a/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch b/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch index fa1cd895c2c0a5..caa4f37bf569d7 100644 --- a/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch +++ b/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch @@ -1,6 +1,6 @@ --- a/src/adpt/adpt.c +++ b/src/adpt/adpt.c -@@ -399,11 +399,6 @@ sw_error_t adpt_init(a_uint32_t dev_id, +@@ -394,11 +394,6 @@ sw_error_t adpt_init(a_uint32_t dev_id, #endif #endif #if defined(HPPE) @@ -45,12 +45,12 @@ --- a/Makefile +++ b/Makefile -@@ -27,7 +27,7 @@ all: $(BIN_DIR) kslib - # LNX Modules-Style Makefile +@@ -18,7 +18,7 @@ include $(PRJ_PATH)/Makefile.modules + # SSDK-Style Makefile #################################################################### - modules: $(BIN_DIR) kslib_c -- mkdir -p ./temp/;cp * ./temp -a;cd ./temp;cp ../Makefile.modules ./Makefile; + all: $(BIN_DIR) kslib +- mkdir -p ./temp/;cd ./temp;cp ../build/bin/ssdk_ks_km.a ./;ar -x ssdk_ks_km.a; cp ../ko_Makefile ./Makefile; + mkdir -p ./temp/;cp app config include ko_Makefile make Makefile.modules src ./temp -a;cd ./temp;cp ../Makefile.modules ./Makefile; - make -C $(SYS_PATH) M=$(PRJ_PATH)/temp $(LNX_MAKEOPTS) modules + $(MAKE) $(PKG_JOBS) -C $(SYS_PATH) M=$(PRJ_PATH)/temp/ CROSS_COMPILE=$(TOOLPREFIX) modules cp $(PRJ_PATH)/temp/Module.symvers $(PRJ_PATH)/Module.symvers; cp temp/*.ko build/bin; diff --git a/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch b/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch index 9711330a411eed..e56e754fad8689 100644 --- a/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch +++ b/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch @@ -24,7 +24,7 @@ Signed-off-by: Mantas Pucka --- a/include/init/ssdk_dts.h +++ b/include/init/ssdk_dts.h -@@ -99,6 +99,7 @@ typedef struct +@@ -101,6 +101,7 @@ typedef struct a_uint32_t emu_chip_ver; /*only valid when is_emulation is true*/ a_uint32_t clk_mode; a_uint32_t pcie_hw_base; @@ -92,10 +92,11 @@ Signed-off-by: Mantas Pucka +a_uint32_t ssdk_dts_port3_pcs_channel_get(a_uint32_t dev_id) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; -+ ++ + return cfg->port3_pcs_channel; +} + + #ifndef BOARD_AR71XX #if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) static void ssdk_dt_parse_mac_mode(a_uint32_t dev_id, @@ -306,6 +313,25 @@ static void ssdk_dt_parse_mac_mode(a_uin @@ -108,7 +109,7 @@ Signed-off-by: Mantas Pucka +{ + const __be32 *port3_pcs_channel; + a_uint32_t len = 0; -+ ++ + port3_pcs_channel = of_get_property(switch_node, "port3_pcs_channel", &len); + if (!port3_pcs_channel) { + ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->port3_pcs_channel = 2; @@ -132,3 +133,4 @@ Signed-off-by: Mantas Pucka ssdk_dt_parse_mdio(*dev_id, switch_node, cfg); ssdk_dt_parse_port_bmp(*dev_id, switch_node, cfg); ssdk_dt_parse_interrupt(*dev_id, switch_node); + From 8b8f7c1a7667bb4ebb688e0eb0b685e7ed2bdf0e Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 9 Mar 2024 15:14:38 -0500 Subject: [PATCH 135/225] ssdk: fix parallel building --- package/kernel/qca-ssdk/Makefile | 8 +-- .../patches/0001-allow-parallel-build.patch | 57 +++++++++++++++++++ .../patches/0004-fix-compile-warnings.patch | 11 ---- 3 files changed, 61 insertions(+), 15 deletions(-) create mode 100644 package/kernel/qca-ssdk/patches/0001-allow-parallel-build.patch diff --git a/package/kernel/qca-ssdk/Makefile b/package/kernel/qca-ssdk/Makefile index ca8b0a4bfea5aa..58daf929ee284e 100644 --- a/package/kernel/qca-ssdk/Makefile +++ b/package/kernel/qca-ssdk/Makefile @@ -22,7 +22,7 @@ define KernelPackage/qca-ssdk SUBMENU:=Network Devices TITLE:=Qualcom SSDK switch driver DEPENDS:=@(TARGET_qualcommax) - FILES:=$(PKG_BUILD_DIR)/build/bin/qca-ssdk.ko + FILES:=$(PKG_BUILD_DIR)/qca-ssdk.ko AUTOLOAD:=$(call AutoLoad,30,qca-ssdk) endef @@ -32,7 +32,7 @@ endef GCC_VERSION=$(shell echo "$(CONFIG_GCC_VERSION)" | sed 's/[^0-9.]*\([0-9.]*\).*/\1/') -LNX_CONFIG_OPTS = LNX_MAKEOPTS='$(KERNEL_MAKEOPTS)' MODULE_TYPE=KSLIB modules +LNX_CONFIG_OPTS = LNX_MAKEOPTS='$(KERNEL_MAKEOPTS)' PRJ_PATH=$(PKG_BUILD_DIR) MODULE_TYPE=KSLIB modules MAKE_FLAGS+= \ TARGET_NAME=$(CONFIG_TARGET_NAME) \ @@ -54,13 +54,13 @@ ifeq ($(CONFIG_TARGET_SUBTARGET), "ipq807x") MAKE_FLAGS+= CHIP_TYPE=HPPE endif - ifeq ($(CONFIG_TARGET_SUBTARGET), "ipq60xx") MAKE_FLAGS+= CHIP_TYPE=CPPE endif + define Build/Compile - +$(MAKE) $(MAKE_FLAGS) -C $(PKG_BUILD_DIR) $(LNX_CONFIG_OPTS) + +$(MAKE) $(PKG_JOBS) $(MAKE_FLAGS) -C $(PKG_BUILD_DIR) $(LNX_CONFIG_OPTS) endef define Build/InstallDev diff --git a/package/kernel/qca-ssdk/patches/0001-allow-parallel-build.patch b/package/kernel/qca-ssdk/patches/0001-allow-parallel-build.patch new file mode 100644 index 00000000000000..7b5aed9f637293 --- /dev/null +++ b/package/kernel/qca-ssdk/patches/0001-allow-parallel-build.patch @@ -0,0 +1,57 @@ +--- a/Makefile ++++ b/Makefile +@@ -1,23 +1,25 @@ +-include ./config +- + ifndef PRJ_PATH + PRJ_PATH=$(shell pwd) + endif + export PRJ_PATH + +-include ./make/config.mk +-include ./make/tools.mk +-include ./make/$(OS)_opt.mk ++include $(PRJ_PATH)/config ++ ++include $(PRJ_PATH)/make/config.mk ++include $(PRJ_PATH)/make/tools.mk ++include $(PRJ_PATH)/make/$(OS)_opt.mk + + SUB_DIR=$(patsubst %/, %, $(dir $(wildcard src/*/Makefile))) + SUB_LIB=$(subst src/, , $(SUB_DIR)) + ++include $(PRJ_PATH)/Makefile.modules ++ + #################################################################### + # SSDK-Style Makefile + #################################################################### + all: $(BIN_DIR) kslib + mkdir -p ./temp/;cd ./temp;cp ../build/bin/ssdk_ks_km.a ./;ar -x ssdk_ks_km.a; cp ../ko_Makefile ./Makefile; +- make -C $(SYS_PATH) M=$(PRJ_PATH)/temp/ CROSS_COMPILE=$(TOOLPREFIX) modules ++ $(MAKE) $(PKG_JOBS) -C $(SYS_PATH) M=$(PRJ_PATH)/temp/ CROSS_COMPILE=$(TOOLPREFIX) modules + cp $(PRJ_PATH)/temp/Module.symvers $(PRJ_PATH)/Module.symvers; + cp temp/*.ko build/bin; + rm -Rf ./temp/*.o ./temp/*.ko ./temp/*.a +@@ -27,11 +29,7 @@ all: $(BIN_DIR) kslib + # LNX Modules-Style Makefile + #################################################################### + modules: $(BIN_DIR) kslib_c +- mkdir -p ./temp/;cp * ./temp -a;cd ./temp;cp ../Makefile.modules ./Makefile; +- make -C $(SYS_PATH) M=$(PRJ_PATH)/temp $(LNX_MAKEOPTS) modules +- cp $(PRJ_PATH)/temp/Module.symvers $(PRJ_PATH)/Module.symvers; +- cp temp/*.ko build/bin; +- rm -Rf ./temp/*.o ./temp/*.ko ./temp/*.a ++ @$(MAKE) -C $(SYS_PATH) M=$(PRJ_PATH) $(LNX_MAKEOPTS) modules + @echo "---Build [SSDK-$(VERSION)] at $(BUILD_DATE) finished." + + kslib_c: +--- a/make/linux_opt.mk ++++ b/make/linux_opt.mk +@@ -777,6 +777,6 @@ LOCAL_CFLAGS += $(CPU_CFLAG) -D"KBUILD_M + #################################################################### + # cflags for LNX Modules-Style Makefile + #################################################################### +-LNX_LOCAL_CFLAGS += $(MODULE_INC) $(MODULE_CFLAG) ${EXTRA_INC} -DFALLTHROUGH ++LNX_LOCAL_CFLAGS = $(MODULE_INC) $(MODULE_CFLAG) ${EXTRA_INC} -DFALLTHROUGH + export LNX_LOCAL_CFLAGS + diff --git a/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch b/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch index caa4f37bf569d7..48807888fb008a 100644 --- a/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch +++ b/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch @@ -43,14 +43,3 @@ { sw_error_t rv; ---- a/Makefile -+++ b/Makefile -@@ -18,7 +18,7 @@ include $(PRJ_PATH)/Makefile.modules - # SSDK-Style Makefile - #################################################################### - all: $(BIN_DIR) kslib -- mkdir -p ./temp/;cd ./temp;cp ../build/bin/ssdk_ks_km.a ./;ar -x ssdk_ks_km.a; cp ../ko_Makefile ./Makefile; -+ mkdir -p ./temp/;cp app config include ko_Makefile make Makefile.modules src ./temp -a;cd ./temp;cp ../Makefile.modules ./Makefile; - $(MAKE) $(PKG_JOBS) -C $(SYS_PATH) M=$(PRJ_PATH)/temp/ CROSS_COMPILE=$(TOOLPREFIX) modules - cp $(PRJ_PATH)/temp/Module.symvers $(PRJ_PATH)/Module.symvers; - cp temp/*.ko build/bin; From efece524800c53db97c5b80e8f2b6827135df882 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 9 Mar 2024 16:16:46 -0500 Subject: [PATCH 136/225] skb_recycler: Add missing cpustate patch for skb_recycler --- ...cler-Add-a-cpustate-for-skb_recycler.patch | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.1/9990-0379-skb_recycler-Add-a-cpustate-for-skb_recycler.patch diff --git a/target/linux/qualcommax/patches-6.1/9990-0379-skb_recycler-Add-a-cpustate-for-skb_recycler.patch b/target/linux/qualcommax/patches-6.1/9990-0379-skb_recycler-Add-a-cpustate-for-skb_recycler.patch new file mode 100644 index 00000000000000..ae4c22ef01acac --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/9990-0379-skb_recycler-Add-a-cpustate-for-skb_recycler.patch @@ -0,0 +1,25 @@ +From 3b5e3bb21a496d03739aa44b3a860db37c96321c Mon Sep 17 00:00:00 2001 +From: Tian Yang +Date: Wed, 29 Jul 2020 17:39:28 -0700 +Subject: [PATCH] skb_recycler: Add a cpustate for skb_recycler + +Add one cpu hotplug state for skb_recycler, called CPUHP_SKB_RECYCLER_DEAD +to avoid using NET_DEV state, this solves a warning calltrace issue from net_dev +since it cannot register its NET_DEV_CPU_DEAD callback during its initialization. + +Signed-off-by: Tian Yang +Change-Id: I6f5729ee300248ade42317114847959fda42dd20 +--- + include/linux/cpuhotplug.h | 1 + + 1 file changed, 1 insertion(+) + +--- a/include/linux/cpuhotplug.h ++++ b/include/linux/cpuhotplug.h +@@ -94,6 +94,7 @@ enum cpuhp_state { + CPUHP_RADIX_DEAD, + CPUHP_PAGE_ALLOC, + CPUHP_NET_DEV_DEAD, ++ CPUHP_SKB_RECYCLER_DEAD, + CPUHP_PCI_XGENE_DEAD, + CPUHP_IOMMU_IOVA_DEAD, + CPUHP_LUSTRE_CFS_DEAD, From 9fd5ca5fce9f53cecd6709270323749d504ffd2c Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 9 Mar 2024 19:53:37 -0500 Subject: [PATCH 137/225] ath11k_nss: fix typo in 512M memory profile --- .../999-233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/kernel/mac80211/patches/nss/ath11k/999-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 index 155f383efc8dd0..bb4bd483244731 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/999-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 @@ -34,7 +34,7 @@ Signed-off-by: Ramya Gnanasekar #define DP_REO_STATUS_RING_SIZE 2048 #define DP_RXDMA_BUF_RING_SIZE 4096 #define DP_RXDMA_REFILL_RING_SIZE 2048 -+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512MB ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M +#define DP_RXDMA_NSS_REFILL_RING_SIZE 1816 +#else +#define DP_RXDMA_NSS_REFILL_RING_SIZE 2048 From 1b4396a857698c3f90bc6df85495d6d9b54c93ff Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 11 Mar 2024 20:06:47 -0400 Subject: [PATCH 138/225] refresh patches --- .../nat46/patches/900-kernel-6.1-compat.patch | 6 ++-- ...-selecting-PCS-channel-for-PORT3-on-.patch | 1 - .../iproute2/patches/400-add-nss-qdisc.patch | 12 ++++---- .../iproute2/patches/500-add-nssmirred.patch | 2 +- .../0600-1-qca-nss-ecm-support-CORE.patch | 30 +++++++++---------- ...-2-qca-nss-ecm-support-PPPOE-offload.patch | 4 +-- ...00-3-qca-nss-ecm-support-net-bonding.patch | 6 ++-- ...pport-net-bonding-over-LAG-interface.patch | 22 +++++++------- ...-1-qca-nss-clients-add-qdisc-support.patch | 4 +-- ...qca-nss-clients-add-iptunnel-support.patch | 2 +- ...-5-qca-nss-clients-add-vxlan-support.patch | 4 +-- ...a-nss-clients-iptunnel-lock-this-cpu.patch | 2 +- .../0604-qca-add-mcs-support.patch | 8 ++--- ...l-pointer-dereference-in-ipv6-output.patch | 2 +- ...ilter_optional_tcp_window_check.patc.patch | 19 ++++-------- ...-netdevice-Add-IFF_EXT_HW_NO_OFFLOAD.patch | 4 +-- ...-api-disallow-identical-driver-names.patch | 6 ++-- 17 files changed, 62 insertions(+), 72 deletions(-) diff --git a/package/kernel/nat46/patches/900-kernel-6.1-compat.patch b/package/kernel/nat46/patches/900-kernel-6.1-compat.patch index ed7e4aaf55fade..79cf653df9787d 100644 --- a/package/kernel/nat46/patches/900-kernel-6.1-compat.patch +++ b/package/kernel/nat46/patches/900-kernel-6.1-compat.patch @@ -2,7 +2,7 @@ +++ b/nat46/modules/nat46-netdev.c @@ -92,8 +92,8 @@ static netdev_tx_t nat46_netdev_xmit(str struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats); - + u64_stats_update_begin(&tstats->syncp); - tstats->rx_packets++; - tstats->rx_bytes += skb->len; @@ -13,7 +13,7 @@ if(ETH_P_IP == ntohs(skb->protocol)) { @@ -110,8 +110,8 @@ void nat46_netdev_count_xmit(struct sk_b struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats); - + u64_stats_update_begin(&tstats->syncp); - tstats->tx_packets++; - tstats->tx_bytes += skb->len; @@ -24,7 +24,7 @@ } @@ -122,10 +122,10 @@ void nat46_update_stats(struct net_devic struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats); - + u64_stats_update_begin(&tstats->syncp); - tstats->rx_packets += rx_packets; - tstats->rx_bytes += rx_bytes; diff --git a/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch b/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch index e56e754fad8689..5e390d8ee339c0 100644 --- a/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch +++ b/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch @@ -133,4 +133,3 @@ Signed-off-by: Mantas Pucka ssdk_dt_parse_mdio(*dev_id, switch_node, cfg); ssdk_dt_parse_port_bmp(*dev_id, switch_node, cfg); ssdk_dt_parse_interrupt(*dev_id, switch_node); - diff --git a/package/network/utils/iproute2/patches/400-add-nss-qdisc.patch b/package/network/utils/iproute2/patches/400-add-nss-qdisc.patch index e5d7024904d0d7..299710f79169d0 100644 --- a/package/network/utils/iproute2/patches/400-add-nss-qdisc.patch +++ b/package/network/utils/iproute2/patches/400-add-nss-qdisc.patch @@ -1,9 +1,9 @@ --- a/include/uapi/linux/pkt_sched.h +++ b/include/uapi/linux/pkt_sched.h @@ -119,6 +119,251 @@ enum { - + #define TCA_STAB_MAX (__TCA_STAB_MAX - 1) - + +enum { + TCA_NSS_ACCEL_MODE_NSS_FW, + TCA_NSS_ACCEL_MODE_PPE, @@ -250,18 +250,18 @@ + + /* FIFO section */ - + struct tc_fifo_qopt { --- a/tc/Makefile +++ b/tc/Makefile -@@ -82,6 +82,7 @@ TCMODULES += q_etf.o +@@ -77,6 +77,7 @@ TCMODULES += q_etf.o TCMODULES += q_taprio.o TCMODULES += q_plug.o TCMODULES += q_ets.o +TCMODULES += q_nss.o - + TCSO := - ifeq ($(TC_CONFIG_ATM),y) + --- /dev/null +++ b/tc/q_nss.c @@ -0,0 +1,1826 @@ diff --git a/package/network/utils/iproute2/patches/500-add-nssmirred.patch b/package/network/utils/iproute2/patches/500-add-nssmirred.patch index d5b0d2384e6a54..f4c3bc587d124c 100644 --- a/package/network/utils/iproute2/patches/500-add-nssmirred.patch +++ b/package/network/utils/iproute2/patches/500-add-nssmirred.patch @@ -1,6 +1,6 @@ --- a/tc/Makefile +++ b/tc/Makefile -@@ -55,6 +55,7 @@ TCMODULES += m_tunnel_key.o +@@ -50,6 +50,7 @@ TCMODULES += m_tunnel_key.o TCMODULES += m_sample.o TCMODULES += m_ct.o TCMODULES += m_gate.o diff --git a/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch b/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch index 9f71b49166ca95..32f7c70d4e3409 100644 --- a/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch +++ b/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch @@ -55,7 +55,7 @@ #endif --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h -@@ -227,7 +227,28 @@ extern void vlan_vids_del_by_dev(struct +@@ -235,7 +235,28 @@ extern void vlan_vids_del_by_dev(struct extern bool vlan_uses_dev(const struct net_device *dev); @@ -86,7 +86,7 @@ __be16 vlan_proto, u16 vlan_id) --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h -@@ -2831,6 +2831,10 @@ enum netdev_cmd { +@@ -2855,6 +2855,10 @@ enum netdev_cmd { NETDEV_OFFLOAD_XSTATS_DISABLE, NETDEV_OFFLOAD_XSTATS_REPORT_USED, NETDEV_OFFLOAD_XSTATS_REPORT_DELTA, @@ -99,7 +99,7 @@ --- a/include/net/addrconf.h +++ b/include/net/addrconf.h -@@ -506,4 +506,9 @@ int if6_proc_init(void); +@@ -514,4 +514,9 @@ int if6_proc_init(void); void if6_proc_exit(void); #endif @@ -169,7 +169,7 @@ #endif --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c -@@ -548,4 +548,52 @@ static int __init vlan_offload_init(void +@@ -555,4 +555,52 @@ static int __init vlan_offload_init(void return 0; } @@ -521,7 +521,7 @@ +/* QCA NSS ECM support - End */ --- a/net/core/neighbour.c +++ b/net/core/neighbour.c -@@ -1268,6 +1268,22 @@ static void neigh_update_hhs(struct neig +@@ -1275,6 +1275,22 @@ static void neigh_update_hhs(struct neig } } @@ -544,7 +544,7 @@ /* Generic update routine. -- lladdr is new lladdr or NULL, if it is not supplied. -- new is new state. -@@ -1296,6 +1312,7 @@ static int __neigh_update(struct neighbo +@@ -1303,6 +1319,7 @@ static int __neigh_update(struct neighbo struct net_device *dev; int err, notify = 0; u8 old; @@ -552,7 +552,7 @@ trace_neigh_update(neigh, lladdr, new, flags, nlmsg_pid); -@@ -1310,7 +1327,10 @@ static int __neigh_update(struct neighbo +@@ -1317,7 +1334,10 @@ static int __neigh_update(struct neighbo new = old; goto out; } @@ -564,7 +564,7 @@ (old & (NUD_NOARP | NUD_PERMANENT))) goto out; -@@ -1347,7 +1367,12 @@ static int __neigh_update(struct neighbo +@@ -1354,7 +1374,12 @@ static int __neigh_update(struct neighbo - compare new & old - if they are different, check override flag */ @@ -578,7 +578,7 @@ !memcmp(lladdr, neigh->ha, dev->addr_len)) lladdr = neigh->ha; } else { -@@ -1469,8 +1494,11 @@ out: +@@ -1476,8 +1501,11 @@ out: neigh_update_gc_list(neigh); if (managed_update) neigh_update_managed_list(neigh); @@ -656,7 +656,7 @@ const struct in6_addr *daddr) --- a/net/ipv6/route.c +++ b/net/ipv6/route.c -@@ -3857,6 +3857,9 @@ out_free: +@@ -3854,6 +3854,9 @@ out_free: return ERR_PTR(err); } @@ -666,7 +666,7 @@ int ip6_route_add(struct fib6_config *cfg, gfp_t gfp_flags, struct netlink_ext_ack *extack) { -@@ -3868,6 +3871,10 @@ int ip6_route_add(struct fib6_config *cf +@@ -3865,6 +3868,10 @@ int ip6_route_add(struct fib6_config *cf return PTR_ERR(rt); err = __ip6_ins_rt(rt, &cfg->fc_nlinfo, extack); @@ -677,7 +677,7 @@ fib6_info_release(rt); return err; -@@ -3889,6 +3896,9 @@ static int __ip6_del_rt(struct fib6_info +@@ -3886,6 +3893,9 @@ static int __ip6_del_rt(struct fib6_info err = fib6_del(rt, info); spin_unlock_bh(&table->tb6_lock); @@ -687,7 +687,7 @@ out: fib6_info_release(rt); return err; -@@ -6342,6 +6352,20 @@ static int ip6_route_dev_notify(struct n +@@ -6339,6 +6349,20 @@ static int ip6_route_dev_notify(struct n return NOTIFY_OK; } @@ -720,7 +720,7 @@ return "UNKNOWN_NETDEV_EVENT"; --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c -@@ -987,6 +987,7 @@ void inet6_ifa_finish_destroy(struct ine +@@ -1002,6 +1002,7 @@ void inet6_ifa_finish_destroy(struct ine kfree_rcu(ifp, rcu); } @@ -728,7 +728,7 @@ static void ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) -@@ -2045,6 +2046,36 @@ struct inet6_ifaddr *ipv6_get_ifaddr(str +@@ -2060,6 +2061,36 @@ struct inet6_ifaddr *ipv6_get_ifaddr(str return result; } diff --git a/target/linux/qualcommax/patches-6.1/0600-2-qca-nss-ecm-support-PPPOE-offload.patch b/target/linux/qualcommax/patches-6.1/0600-2-qca-nss-ecm-support-PPPOE-offload.patch index 25e21bc09183ff..6d6119e8bf2836 100644 --- a/target/linux/qualcommax/patches-6.1/0600-2-qca-nss-ecm-support-PPPOE-offload.patch +++ b/target/linux/qualcommax/patches-6.1/0600-2-qca-nss-ecm-support-PPPOE-offload.patch @@ -466,7 +466,7 @@ #endif /* !(__LINUX_IF_PPPOX_H) */ --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h -@@ -1709,6 +1709,24 @@ enum netdev_priv_flags { +@@ -1733,6 +1733,24 @@ enum netdev_priv_flags { IFF_NO_IP_ALIGN = BIT_ULL(33), }; @@ -491,7 +491,7 @@ #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN #define IFF_EBRIDGE IFF_EBRIDGE #define IFF_BONDING IFF_BONDING -@@ -2051,7 +2069,8 @@ struct net_device { +@@ -2075,7 +2093,8 @@ struct net_device { /* Read-mostly cache-line for fast-path access */ unsigned int flags; unsigned long long priv_flags; diff --git a/target/linux/qualcommax/patches-6.1/0600-3-qca-nss-ecm-support-net-bonding.patch b/target/linux/qualcommax/patches-6.1/0600-3-qca-nss-ecm-support-net-bonding.patch index a56b877a526d98..508ad0ff585076 100644 --- a/target/linux/qualcommax/patches-6.1/0600-3-qca-nss-ecm-support-net-bonding.patch +++ b/target/linux/qualcommax/patches-6.1/0600-3-qca-nss-ecm-support-net-bonding.patch @@ -9,7 +9,7 @@ static struct flow_dissector flow_keys_bonding __read_mostly; /*-------------------------- Forward declarations ---------------------------*/ -@@ -4377,6 +4379,24 @@ static int bond_get_lowest_level_rcu(str +@@ -4383,6 +4385,24 @@ static int bond_get_lowest_level_rcu(str } #endif @@ -34,7 +34,7 @@ static void bond_get_stats(struct net_device *bond_dev, struct rtnl_link_stats64 *stats) { -@@ -5789,6 +5809,11 @@ static void bond_destructor(struct net_d +@@ -5795,6 +5815,11 @@ static void bond_destructor(struct net_d if (bond->rr_tx_counter) free_percpu(bond->rr_tx_counter); @@ -46,7 +46,7 @@ } void bond_setup(struct net_device *bond_dev) -@@ -6352,6 +6377,14 @@ int bond_create(struct net *net, const c +@@ -6358,6 +6383,14 @@ int bond_create(struct net *net, const c bond_work_init_all(bond); diff --git a/target/linux/qualcommax/patches-6.1/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch b/target/linux/qualcommax/patches-6.1/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch index d931107e7b0bcc..27d55711fac142 100644 --- a/target/linux/qualcommax/patches-6.1/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch +++ b/target/linux/qualcommax/patches-6.1/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch @@ -238,7 +238,7 @@ if (bond_is_lb(bond)) bond_alb_handle_link_change(bond, new_active, BOND_LINK_UP); } else { -@@ -1803,7 +1820,8 @@ int bond_enslave(struct net_device *bond +@@ -1809,7 +1826,8 @@ int bond_enslave(struct net_device *bond const struct net_device_ops *slave_ops = slave_dev->netdev_ops; struct slave *new_slave = NULL, *prev_slave; struct sockaddr_storage ss; @@ -248,7 +248,7 @@ int res = 0, i; if (slave_dev->flags & IFF_MASTER && -@@ -2246,6 +2264,15 @@ int bond_enslave(struct net_device *bond +@@ -2252,6 +2270,15 @@ int bond_enslave(struct net_device *bond bond_is_active_slave(new_slave) ? "an active" : "a backup", new_slave->link != BOND_LINK_DOWN ? "an up" : "a down"); @@ -264,7 +264,7 @@ /* enslave is successful */ bond_queue_slave_event(new_slave); return 0; -@@ -2311,6 +2338,15 @@ err_undo_flags: +@@ -2317,6 +2344,15 @@ err_undo_flags: } } @@ -280,7 +280,7 @@ return res; } -@@ -2333,7 +2369,8 @@ static int __bond_release_one(struct net +@@ -2339,7 +2375,8 @@ static int __bond_release_one(struct net struct slave *slave, *oldcurrent; struct sockaddr_storage ss; int old_flags = bond_dev->flags; @@ -290,7 +290,7 @@ /* slave is not a slave or master is not master of this slave */ if (!(slave_dev->flags & IFF_SLAVE) || -@@ -2354,6 +2391,15 @@ static int __bond_release_one(struct net +@@ -2360,6 +2397,15 @@ static int __bond_release_one(struct net bond_set_slave_inactive_flags(slave, BOND_SLAVE_NOTIFY_NOW); @@ -306,7 +306,7 @@ bond_sysfs_slave_del(slave); /* recompute stats just before removing the slave */ -@@ -2673,6 +2719,8 @@ static void bond_miimon_commit(struct bo +@@ -2679,6 +2725,8 @@ static void bond_miimon_commit(struct bo struct slave *slave, *primary, *active; bool do_failover = false; struct list_head *iter; @@ -315,7 +315,7 @@ ASSERT_RTNL(); -@@ -2712,6 +2760,12 @@ static void bond_miimon_commit(struct bo +@@ -2718,6 +2766,12 @@ static void bond_miimon_commit(struct bo bond_set_active_slave(slave); } @@ -328,7 +328,7 @@ slave_info(bond->dev, slave->dev, "link status definitely up, %u Mbps %s duplex\n", slave->speed == SPEED_UNKNOWN ? 0 : slave->speed, slave->duplex ? "full" : "half"); -@@ -2760,6 +2814,16 @@ static void bond_miimon_commit(struct bo +@@ -2766,6 +2820,16 @@ static void bond_miimon_commit(struct bo unblock_netpoll_tx(); } @@ -345,7 +345,7 @@ bond_set_carrier(bond); } -@@ -4007,8 +4071,219 @@ static inline u32 bond_eth_hash(struct s +@@ -4013,8 +4077,219 @@ static inline u32 bond_eth_hash(struct s return 0; ep = (struct ethhdr *)(data + mhoff); @@ -566,7 +566,7 @@ static bool bond_flow_ip(struct sk_buff *skb, struct flow_keys *fk, const void *data, int hlen, __be16 l2_proto, int *nhoff, int *ip_proto, bool l34) -@@ -5205,15 +5480,23 @@ static netdev_tx_t bond_3ad_xor_xmit(str +@@ -5211,15 +5486,23 @@ static netdev_tx_t bond_3ad_xor_xmit(str struct net_device *dev) { struct bonding *bond = netdev_priv(dev); @@ -597,7 +597,7 @@ } /* in broadcast mode, we send everything to all usable interfaces. */ -@@ -5463,8 +5746,9 @@ static netdev_tx_t __bond_start_xmit(str +@@ -5469,8 +5752,9 @@ static netdev_tx_t __bond_start_xmit(str return bond_xmit_roundrobin(skb, dev); case BOND_MODE_ACTIVEBACKUP: return bond_xmit_activebackup(skb, dev); diff --git a/target/linux/qualcommax/patches-6.1/0603-1-qca-nss-clients-add-qdisc-support.patch b/target/linux/qualcommax/patches-6.1/0603-1-qca-nss-clients-add-qdisc-support.patch index 671516cfcdde9e..78a22e59fd1959 100644 --- a/target/linux/qualcommax/patches-6.1/0603-1-qca-nss-clients-add-qdisc-support.patch +++ b/target/linux/qualcommax/patches-6.1/0603-1-qca-nss-clients-add-qdisc-support.patch @@ -52,7 +52,7 @@ dev->needs_free_netdev = true; --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h -@@ -4588,6 +4588,15 @@ void dev_uc_flush(struct net_device *dev +@@ -4612,6 +4612,15 @@ void dev_uc_flush(struct net_device *dev void dev_uc_init(struct net_device *dev); /** @@ -68,7 +68,7 @@ * __dev_uc_sync - Synchonize device's unicast list * @dev: device to sync * @sync: function to call if address should be added -@@ -5133,6 +5142,11 @@ static inline bool netif_is_failover_sla +@@ -5157,6 +5166,11 @@ static inline bool netif_is_failover_sla return dev->priv_flags & IFF_FAILOVER_SLAVE; } diff --git a/target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-add-iptunnel-support.patch b/target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-add-iptunnel-support.patch index 928510087da42a..6b48489367faa9 100644 --- a/target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-add-iptunnel-support.patch +++ b/target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-add-iptunnel-support.patch @@ -22,7 +22,7 @@ #endif /* __NET_IP_TUNNELS_H */ --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c -@@ -2398,6 +2398,26 @@ nla_put_failure: +@@ -2413,6 +2413,26 @@ nla_put_failure: return -EMSGSIZE; } diff --git a/target/linux/qualcommax/patches-6.1/0603-5-qca-nss-clients-add-vxlan-support.patch b/target/linux/qualcommax/patches-6.1/0603-5-qca-nss-clients-add-vxlan-support.patch index 8c14040bb5d76a..68674783dc1519 100644 --- a/target/linux/qualcommax/patches-6.1/0603-5-qca-nss-clients-add-vxlan-support.patch +++ b/target/linux/qualcommax/patches-6.1/0603-5-qca-nss-clients-add-vxlan-support.patch @@ -61,7 +61,7 @@ /* caller should hold vxlan->hash_lock */ static struct vxlan_rdst *vxlan_fdb_find_rdst(struct vxlan_fdb *f, union vxlan_addr *ip, __be16 port, -@@ -2654,6 +2685,9 @@ static void vxlan_xmit_one(struct sk_buf +@@ -2658,6 +2689,9 @@ static void vxlan_xmit_one(struct sk_buf goto out_unlock; } @@ -71,7 +71,7 @@ tos = ip_tunnel_ecn_encap(tos, old_iph, skb); ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr), -@@ -2725,7 +2759,10 @@ static void vxlan_xmit_one(struct sk_buf +@@ -2729,7 +2763,10 @@ static void vxlan_xmit_one(struct sk_buf if (err < 0) goto tx_error; diff --git a/target/linux/qualcommax/patches-6.1/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch b/target/linux/qualcommax/patches-6.1/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch index faba23d8630d8c..17c0fe3c971daf 100644 --- a/target/linux/qualcommax/patches-6.1/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch +++ b/target/linux/qualcommax/patches-6.1/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch @@ -1,6 +1,6 @@ --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c -@@ -2404,7 +2404,7 @@ nla_put_failure: +@@ -2419,7 +2419,7 @@ nla_put_failure: */ void ip6_update_offload_stats(struct net_device *dev, void *ptr) { diff --git a/target/linux/qualcommax/patches-6.1/0604-qca-add-mcs-support.patch b/target/linux/qualcommax/patches-6.1/0604-qca-add-mcs-support.patch index c8ad52104b75ee..835ca83e91deb0 100644 --- a/target/linux/qualcommax/patches-6.1/0604-qca-add-mcs-support.patch +++ b/target/linux/qualcommax/patches-6.1/0604-qca-add-mcs-support.patch @@ -538,7 +538,7 @@ static const struct fib_rules_ops __net_initconst ipmr_rules_ops_template = { .family = RTNL_FAMILY_IPMR, .rule_size = sizeof(struct ipmr_rule), -@@ -1193,6 +1424,11 @@ static int ipmr_mfc_delete(struct mr_tab +@@ -1192,6 +1423,11 @@ static int ipmr_mfc_delete(struct mr_tab mroute_netlink_event(mrt, c, RTM_DELROUTE); mr_cache_put(&c->_c); @@ -550,7 +550,7 @@ return 0; } -@@ -1222,6 +1458,12 @@ static int ipmr_mfc_add(struct net *net, +@@ -1221,6 +1457,12 @@ static int ipmr_mfc_add(struct net *net, call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_REPLACE, c, mrt->id); mroute_netlink_event(mrt, c, RTM_NEWROUTE); @@ -563,7 +563,7 @@ return 0; } -@@ -1282,6 +1524,7 @@ static void mroute_clean_tables(struct m +@@ -1281,6 +1523,7 @@ static void mroute_clean_tables(struct m struct net *net = read_pnet(&mrt->net); struct mr_mfc *c, *tmp; struct mfc_cache *cache; @@ -571,7 +571,7 @@ LIST_HEAD(list); int i; -@@ -1306,10 +1549,19 @@ static void mroute_clean_tables(struct m +@@ -1305,10 +1548,19 @@ static void mroute_clean_tables(struct m rhltable_remove(&mrt->mfc_hash, &c->mnode, ipmr_rht_params); list_del_rcu(&c->list); cache = (struct mfc_cache *)c; diff --git a/target/linux/qualcommax/patches-6.1/0611-ipv6-Fix-null-pointer-dereference-in-ipv6-output.patch b/target/linux/qualcommax/patches-6.1/0611-ipv6-Fix-null-pointer-dereference-in-ipv6-output.patch index 608ab7f2b33675..25f99fc4adef3c 100644 --- a/target/linux/qualcommax/patches-6.1/0611-ipv6-Fix-null-pointer-dereference-in-ipv6-output.patch +++ b/target/linux/qualcommax/patches-6.1/0611-ipv6-Fix-null-pointer-dereference-in-ipv6-output.patch @@ -68,7 +68,7 @@ Signed-off-by: Andrea Righi --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c -@@ -492,6 +492,9 @@ int ip6_forward(struct sk_buff *skb) +@@ -498,6 +498,9 @@ int ip6_forward(struct sk_buff *skb) u32 mtu; idev = __in6_dev_get_safely(dev_get_by_index_rcu(net, IP6CB(skb)->iif)); diff --git a/target/linux/qualcommax/patches-6.1/0613-netfilter_optional_tcp_window_check.patc.patch b/target/linux/qualcommax/patches-6.1/0613-netfilter_optional_tcp_window_check.patc.patch index 150853573d0116..a130ec999f0dc7 100644 --- a/target/linux/qualcommax/patches-6.1/0613-netfilter_optional_tcp_window_check.patc.patch +++ b/target/linux/qualcommax/patches-6.1/0613-netfilter_optional_tcp_window_check.patc.patch @@ -17,8 +17,6 @@ Signed-off-by: Ram Chandra Jangir net/netfilter/nf_conntrack_standalone.c | 10 ++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) -diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h -index 1f463b3957c7..2af4f8d24282 100644 --- a/include/net/netns/conntrack.h +++ b/include/net/netns/conntrack.h @@ -26,6 +26,7 @@ struct nf_tcp_net { @@ -29,11 +27,9 @@ index 1f463b3957c7..2af4f8d24282 100644 u8 tcp_max_retrans; u8 tcp_ignore_invalid_rst; #if IS_ENABLED(CONFIG_NF_FLOW_TABLE) -diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c -index 3ac1af6f59fc..0a2badd52b54 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c -@@ -513,11 +513,15 @@ tcp_in_window(struct nf_conn *ct, enum ip_conntrack_dir dir, +@@ -515,11 +515,15 @@ tcp_in_window(struct nf_conn *ct, enum i struct ip_ct_tcp *state = &ct->proto.tcp; struct ip_ct_tcp_state *sender = &state->seen[dir]; struct ip_ct_tcp_state *receiver = &state->seen[!dir]; @@ -49,7 +45,7 @@ index 3ac1af6f59fc..0a2badd52b54 100644 /* * Get the required data from the packet. */ -@@ -1257,7 +1261,7 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct, +@@ -1294,7 +1298,7 @@ int nf_conntrack_tcp_packet(struct nf_co IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED && timeouts[new_state] > timeouts[TCP_CONNTRACK_UNACK]) timeout = timeouts[TCP_CONNTRACK_UNACK]; @@ -58,7 +54,7 @@ index 3ac1af6f59fc..0a2badd52b54 100644 timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS]) timeout = timeouts[TCP_CONNTRACK_RETRANS]; else -@@ -1573,6 +1577,9 @@ void nf_conntrack_tcp_init_net(struct net *net) +@@ -1610,6 +1614,9 @@ void nf_conntrack_tcp_init_net(struct ne */ tn->tcp_be_liberal = 0; @@ -68,8 +64,6 @@ index 3ac1af6f59fc..0a2badd52b54 100644 /* If it's non-zero, we turn off RST sequence number check */ tn->tcp_ignore_invalid_rst = 0; -diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c -index e9654169b005..84b8e28f0782 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -637,6 +637,7 @@ enum nf_ct_sysctl_index { @@ -80,7 +74,7 @@ index e9654169b005..84b8e28f0782 100644 NF_SYSCTL_CT_PROTO_TCP_IGNORE_INVALID_RST, NF_SYSCTL_CT_PROTO_TCP_MAX_RETRANS, NF_SYSCTL_CT_PROTO_TIMEOUT_UDP, -@@ -844,6 +845,14 @@ static struct ctl_table nf_ct_sysctl_table[] = { +@@ -844,6 +845,14 @@ static struct ctl_table nf_ct_sysctl_tab .extra1 = SYSCTL_ZERO, .extra2 = SYSCTL_ONE, }, @@ -95,7 +89,7 @@ index e9654169b005..84b8e28f0782 100644 [NF_SYSCTL_CT_PROTO_TCP_IGNORE_INVALID_RST] = { .procname = "nf_conntrack_tcp_ignore_invalid_rst", .maxlen = sizeof(u8), -@@ -1054,6 +1063,7 @@ static void nf_conntrack_standalone_init_tcp_sysctl(struct net *net, +@@ -1054,6 +1063,7 @@ static void nf_conntrack_standalone_init XASSIGN(LOOSE, &tn->tcp_loose); XASSIGN(LIBERAL, &tn->tcp_be_liberal); @@ -103,6 +97,3 @@ index e9654169b005..84b8e28f0782 100644 XASSIGN(MAX_RETRANS, &tn->tcp_max_retrans); XASSIGN(IGNORE_INVALID_RST, &tn->tcp_ignore_invalid_rst); #undef XASSIGN --- -2.17.1 - diff --git a/target/linux/qualcommax/patches-6.1/0614-netdevice-Add-IFF_EXT_HW_NO_OFFLOAD.patch b/target/linux/qualcommax/patches-6.1/0614-netdevice-Add-IFF_EXT_HW_NO_OFFLOAD.patch index df24e0ea1de8fb..d969adf3636033 100644 --- a/target/linux/qualcommax/patches-6.1/0614-netdevice-Add-IFF_EXT_HW_NO_OFFLOAD.patch +++ b/target/linux/qualcommax/patches-6.1/0614-netdevice-Add-IFF_EXT_HW_NO_OFFLOAD.patch @@ -1,6 +1,6 @@ --- a/include/linux/netdevice.h -+++ a/include/linux/netdevice.h -@@ -1725,6 +1725,8 @@ ++++ b/include/linux/netdevice.h +@@ -1749,6 +1749,8 @@ enum netdev_priv_flags_ext { IFF_EXT_GRE_V4_TAP = 1<<4, IFF_EXT_GRE_V6_TAP = 1<<5, IFF_EXT_IFB = 1<<6, diff --git a/target/linux/qualcommax/patches-6.1/9999-revert-crypto-api-disallow-identical-driver-names.patch b/target/linux/qualcommax/patches-6.1/9999-revert-crypto-api-disallow-identical-driver-names.patch index 60cc5e6de280a2..0f4862e7fa287c 100644 --- a/target/linux/qualcommax/patches-6.1/9999-revert-crypto-api-disallow-identical-driver-names.patch +++ b/target/linux/qualcommax/patches-6.1/9999-revert-crypto-api-disallow-identical-driver-names.patch @@ -1,6 +1,6 @@ ---- b/crypto/algapi.c -+++ a/crypto/algapi.c -@@ -217,7 +217,6 @@ +--- a/crypto/algapi.c ++++ b/crypto/algapi.c +@@ -290,7 +290,6 @@ static struct crypto_larval *__crypto_re } if (!strcmp(q->cra_driver_name, alg->cra_name) || From 854b56c60efee77c26d11496fb29e6de340873c9 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Fri, 15 Mar 2024 17:09:11 -0400 Subject: [PATCH 139/225] ath11k_nss: remove SFE patch 718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly It is not relevant to NSS builds and only meant for SFE. --- ...-the-frame-to-driver-tx-ops-directly.patch | 74 ------------------- 1 file changed, 74 deletions(-) delete mode 100644 package/kernel/mac80211/patches/nss/subsys/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch diff --git a/package/kernel/mac80211/patches/nss/subsys/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch b/package/kernel/mac80211/patches/nss/subsys/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch deleted file mode 100644 index 8d8c3c68d58c91..00000000000000 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -4571,6 +4571,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; -@@ -4834,7 +4835,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, From c761ad846b10bbdba65fe72765dde74366f6ab81 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Fri, 15 Mar 2024 17:12:51 -0400 Subject: [PATCH 140/225] ath11k_nss: remove unecessary patches Color collision should be left on by default, as it's a primary feature of 802.11AX. --- ...rt-to-enable-disable-color-collision.patch | 46 ----------- ...ort-to-enable-disable-bss-color-coll.patch | 78 ------------------- 2 files changed, 124 deletions(-) delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/218-ath11k-add-support-to-enable-disable-color-collision.patch delete mode 100644 package/kernel/mac80211/patches/nss/subsys/649-nl80211-Add-support-to-enable-disable-bss-color-coll.patch diff --git a/package/kernel/mac80211/patches/nss/ath11k/218-ath11k-add-support-to-enable-disable-color-collision.patch b/package/kernel/mac80211/patches/nss/ath11k/218-ath11k-add-support-to-enable-disable-color-collision.patch deleted file mode 100644 index 24520cbeafbc7a..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/218-ath11k-add-support-to-enable-disable-color-collision.patch +++ /dev/null @@ -1,46 +0,0 @@ -From ee8c401bdfa08c6b98fb5b016841db5603ba4059 Mon Sep 17 00:00:00 2001 -From: Lavanya Suresh -Date: Wed, 23 Sep 2020 21:54:34 +0530 -Subject: [PATCH] ath11k: add support to enable/disable bss color collision - detection - -Added module param to enable or disable bss color collision detection. -By default, it is disabled. This config should be changed before VAP -bringup only. - - -Signed-off-by: Lavanya Suresh ---- - drivers/net/wireless/ath/ath11k/mac.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/ath/ath11k/mac.c -+++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -53,6 +54,10 @@ - .max_power = 30, \ - } - -+unsigned int color_collision_enable = 0; -+module_param_named(color_collision_detect, color_collision_enable, uint, 0644); -+MODULE_PARM_DESC(color_collision_detect, "BSS color collision detecion: 0-disable 1-enable"); -+ - static const struct ieee80211_channel ath11k_2ghz_channels[] = { - CHAN2G(1, 2412, 0), - CHAN2G(2, 2417, 0), -@@ -3723,7 +3728,7 @@ static void ath11k_mac_op_bss_info_chang - ret = ath11k_wmi_send_obss_color_collision_cfg_cmd( - ar, arvif->vdev_id, info->he_bss_color.color, - ATH11K_BSS_COLOR_COLLISION_DETECTION_AP_PERIOD_MS, -- info->he_bss_color.enabled); -+ (info->he_bss_color.enabled & color_collision_enable)); - if (ret) - ath11k_warn(ar->ab, "failed to set bss color collision on vdev %i: %d\n", - arvif->vdev_id, ret); diff --git a/package/kernel/mac80211/patches/nss/subsys/649-nl80211-Add-support-to-enable-disable-bss-color-coll.patch b/package/kernel/mac80211/patches/nss/subsys/649-nl80211-Add-support-to-enable-disable-bss-color-coll.patch deleted file mode 100644 index 058d983c8a15f6..00000000000000 --- a/package/kernel/mac80211/patches/nss/subsys/649-nl80211-Add-support-to-enable-disable-bss-color-coll.patch +++ /dev/null @@ -1,78 +0,0 @@ -From e4439779d28949a61228b359a27f399df9b42b1a Mon Sep 17 00:00:00 2001 -From: Rameshkumar Sundaram -Date: Mon, 25 Oct 2021 19:06:04 +0530 -Subject: [PATCH 1/2] nl80211: add support to enable/disable bss color - collision detection - -As per 802.11ax-2021, STAs shall process BSS Color Change Announcement -(BCCA) from AP and switch to new color, but some STAs aren't processing -BCCA from AP and not doing color switch, causing them to drop data -frames from AP post color change. - -Provide an option to disable color collision detection and therefore -not to do BCCA to mitigate the same from AP. If it's required in case -where STA supports BCCA handling, then it can enabled in AP using this -option. - -Signed-off-by: Rameshkumar Sundaram -Signed-off-by: Dinesh Karthikeyan ---- - include/net/cfg80211.h | 2 ++ - include/uapi/linux/nl80211.h | 3 +++ - net/wireless/nl80211.c | 3 +++ - 3 files changed, 8 insertions(+) - ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -312,11 +312,13 @@ struct ieee80211_he_obss_pd { - * @color: the current color. - * @enabled: HE BSS color is used - * @partial: define the AID equation. -+ * @collision_detection_enabled: HE BSS color collision detection is enabled. - */ - struct cfg80211_he_bss_color { - u8 color; - bool enabled; - bool partial; -+ bool collision_detection_enabled; - }; - - /** ---- a/include/uapi/linux/nl80211.h -+++ b/include/uapi/linux/nl80211.h -@@ -7566,6 +7566,8 @@ enum nl80211_obss_pd_attributes { - * @NL80211_HE_BSS_COLOR_ATTR_COLOR: the current BSS Color. - * @NL80211_HE_BSS_COLOR_ATTR_DISABLED: is BSS coloring disabled. - * @NL80211_HE_BSS_COLOR_ATTR_PARTIAL: the AID equation to be used.. -+ * @NL80211_HE_BSS_COLOR_ATTR_COLLISION_DETECTION_DISABLED: is BSS -+ * color collision detection disabled. - * - * @__NL80211_HE_BSS_COLOR_ATTR_LAST: Internal - * @NL80211_HE_BSS_COLOR_ATTR_MAX: highest BSS Color attribute. -@@ -7576,6 +7578,7 @@ enum nl80211_bss_color_attributes { - NL80211_HE_BSS_COLOR_ATTR_COLOR, - NL80211_HE_BSS_COLOR_ATTR_DISABLED, - NL80211_HE_BSS_COLOR_ATTR_PARTIAL, -+ NL80211_HE_BSS_COLOR_ATTR_COLLISION_DETECTION_DISABLED, - - /* keep last */ - __NL80211_HE_BSS_COLOR_ATTR_LAST, ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -378,6 +378,7 @@ he_bss_color_policy[NL80211_HE_BSS_COLOR - [NL80211_HE_BSS_COLOR_ATTR_COLOR] = NLA_POLICY_RANGE(NLA_U8, 1, 63), - [NL80211_HE_BSS_COLOR_ATTR_DISABLED] = { .type = NLA_FLAG }, - [NL80211_HE_BSS_COLOR_ATTR_PARTIAL] = { .type = NLA_FLAG }, -+ [NL80211_HE_BSS_COLOR_ATTR_COLLISION_DETECTION_DISABLED] = { .type = NLA_FLAG }, - }; - - static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = { -@@ -5495,6 +5496,8 @@ static int nl80211_parse_he_bss_color(st - !nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_DISABLED]); - he_bss_color->partial = - nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_PARTIAL]); -+ he_bss_color->collision_detection_enabled = -+ !nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_COLLISION_DETECTION_DISABLED]); - - return 0; - } From ee8aa91fcdb065cf77c2612811b13b8e4912409c Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 18 Mar 2024 04:19:22 -0400 Subject: [PATCH 141/225] qca-ssdk: renumber patches and fix up parallel build --- ...rallel-build.patch => 200-allow-parallel-build.patch} | 9 +-------- ...ile-warnings.patch => 201-fix-compile-warnings.patch} | 0 2 files changed, 1 insertion(+), 8 deletions(-) rename package/kernel/qca-ssdk/patches/{0001-allow-parallel-build.patch => 200-allow-parallel-build.patch} (78%) rename package/kernel/qca-ssdk/patches/{0004-fix-compile-warnings.patch => 201-fix-compile-warnings.patch} (100%) diff --git a/package/kernel/qca-ssdk/patches/0001-allow-parallel-build.patch b/package/kernel/qca-ssdk/patches/200-allow-parallel-build.patch similarity index 78% rename from package/kernel/qca-ssdk/patches/0001-allow-parallel-build.patch rename to package/kernel/qca-ssdk/patches/200-allow-parallel-build.patch index 7b5aed9f637293..5635c2fdcfb307 100644 --- a/package/kernel/qca-ssdk/patches/0001-allow-parallel-build.patch +++ b/package/kernel/qca-ssdk/patches/200-allow-parallel-build.patch @@ -1,6 +1,6 @@ --- a/Makefile +++ b/Makefile -@@ -1,23 +1,25 @@ +@@ -1,17 +1,19 @@ -include ./config - ifndef PRJ_PATH @@ -25,13 +25,6 @@ #################################################################### # SSDK-Style Makefile #################################################################### - all: $(BIN_DIR) kslib - mkdir -p ./temp/;cd ./temp;cp ../build/bin/ssdk_ks_km.a ./;ar -x ssdk_ks_km.a; cp ../ko_Makefile ./Makefile; -- make -C $(SYS_PATH) M=$(PRJ_PATH)/temp/ CROSS_COMPILE=$(TOOLPREFIX) modules -+ $(MAKE) $(PKG_JOBS) -C $(SYS_PATH) M=$(PRJ_PATH)/temp/ CROSS_COMPILE=$(TOOLPREFIX) modules - cp $(PRJ_PATH)/temp/Module.symvers $(PRJ_PATH)/Module.symvers; - cp temp/*.ko build/bin; - rm -Rf ./temp/*.o ./temp/*.ko ./temp/*.a @@ -27,11 +29,7 @@ all: $(BIN_DIR) kslib # LNX Modules-Style Makefile #################################################################### diff --git a/package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch b/package/kernel/qca-ssdk/patches/201-fix-compile-warnings.patch similarity index 100% rename from package/kernel/qca-ssdk/patches/0004-fix-compile-warnings.patch rename to package/kernel/qca-ssdk/patches/201-fix-compile-warnings.patch From 255dde7221d1936430c09ee7d6d72b5f0356fc4c Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 18 Mar 2024 04:22:09 -0400 Subject: [PATCH 142/225] ath11k_nss: fix spacing --- .../nss/ath11k/330-ath11k-sync-wds_ast_entry-updates.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/kernel/mac80211/patches/nss/ath11k/330-ath11k-sync-wds_ast_entry-updates.patch b/package/kernel/mac80211/patches/nss/ath11k/330-ath11k-sync-wds_ast_entry-updates.patch index 662e11697f4d9c..361c9064148acd 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/330-ath11k-sync-wds_ast_entry-updates.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/330-ath11k-sync-wds_ast_entry-updates.patch @@ -91,7 +91,7 @@ Signed-off-by: Rameshkumar Sundaram + struct work_struct wmi_ast_work; + struct list_head wmi_ast_list; - bool stats_disable; + bool stats_disable; /* must be last */ --- a/drivers/net/wireless/ath/ath11k/nss.c +++ b/drivers/net/wireless/ath/ath11k/nss.c From 046bc9e3a4da2772b6b96d431b3fcabc88e15cdb Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 18 Mar 2024 04:23:39 -0400 Subject: [PATCH 143/225] ath11k_nss: Remove unnecessary TKIP bloat Remove TKIP patches that are not being used as 99% of folks are running modern encryption (AES-CCMP,SAE,etc). --- ...-fix-tkip-encryption-traffic-failure.patch | 25 ----------- ...treaming-not-working-for-wan-to-wlan.patch | 44 ------------------- ...support-to-send-the-QoS-Null-Data-fr.patch | 10 ++--- 3 files changed, 5 insertions(+), 74 deletions(-) delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch diff --git a/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch b/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch deleted file mode 100644 index f57faaa465ae76..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -2564,7 +2564,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/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch b/package/kernel/mac80211/patches/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch deleted file mode 100644 index 020df707b6e6a4..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch +++ /dev/null @@ -1,44 +0,0 @@ -From c9bcb26f30a1b2e3434d851aea19200a6d757cca Mon Sep 17 00:00:00 2001 -From: Aaradhana Sahu -Date: Sat, 3 Jun 2023 18:33:54 +0530 -Subject: [PATCH] ath11k: fix VLC streaming not working for wan to wlan when - multicast to unicast flag enable - -Currently, additional two bytes after 802.11 header are seen on the air. -When per-packet encap mode is native wifi and vdev level encap mode is -eth mode, native wifi encap functionality is skipped. - -This leaves QoS header unremoved in the 802.11 header of the packet. When -sending the packet HW will also add (one more) QoS header. The additional -two bytes before LLC/SNAP header confuses the receiver and those packets -will get dropped at receiver. - -Fix this issue by removing QoS header (native wifi encap functionality) -for all the packets which will be enqueued to hw in native wifi mode. - -Signed-off-by: Aaradhana Sahu ---- - drivers/net/wireless/ath/ath11k/dp_tx.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/ath/ath11k/dp_tx.c -+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -@@ -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)) - is_diff_encap = true; - else - ath11k_dp_tx_encap_nwifi(skb); -@@ -247,7 +248,7 @@ tcl_ring_sel: - if ((!test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) && - !(info->control.flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && - !info->control.hw_key && ieee80211_has_protected(hdr->frame_control)) || -- (skb->protocol == cpu_to_be16(ETH_P_PAE) && is_diff_encap)) { -+ is_diff_encap) { - /* HW requirement is that metadata should always point to a - * 8-byte aligned address. So we add alignment pad to start of - * buffer. HTT Metadata should be ensured to be multiple of 8-bytes diff --git a/package/kernel/mac80211/patches/nss/ath11k/458-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 index 6399718268b0b1..88903faddfdbf6 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/458-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,13 +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 -@@ -222,7 +222,8 @@ 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) && -- skb->protocol == cpu_to_be16(ETH_P_PAE)) -+ (skb->protocol == cpu_to_be16(ETH_P_PAE) || -+ ieee80211_is_qos_nullfunc(hdr->frame_control))) +- if (arvif->vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) ++ if ((arvif->vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) && ++ ieee80211_is_qos_nullfunc(hdr->frame_control)) is_diff_encap = true; else ath11k_dp_tx_encap_nwifi(skb); From 6f432e48ab879741f94d12f93760d625b24b5210 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 18 Mar 2024 04:28:04 -0400 Subject: [PATCH 144/225] ath11k_nss: parameterize DP_RXDMA_REFILL_RING_SIZE memory profile --- ...11k-Disable-rx_header-tlv-for-2K-SKB.patch | 44 ++++++++++++++----- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/package/kernel/mac80211/patches/nss/ath11k/999-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 index bb4bd483244731..85562dc463a211 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/999-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 @@ -30,19 +30,17 @@ 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 -@@ -238,6 +238,11 @@ 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 - #define DP_RXDMA_REFILL_RING_SIZE 2048 -+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M -+#define DP_RXDMA_NSS_REFILL_RING_SIZE 1816 -+#else -+#define DP_RXDMA_NSS_REFILL_RING_SIZE 2048 -+#endif +-#define DP_RXDMA_REFILL_RING_SIZE 2048 ++#define DP_RXDMA_REFILL_RING_SIZE ATH11K_DP_RXDMA_REFILL_RING_SIZE ++#define DP_RXDMA_NSS_REFILL_RING_SIZE ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE #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 -@@ -672,7 +677,7 @@ enum htt_stats_internal_ppdu_frametype { +@@ -672,7 +673,7 @@ enum htt_stats_internal_ppdu_frametype { * * |31 26|25|24|23 16|15 8|7 0| * |-----------------+----------------+----------------+---------------| @@ -885,16 +883,38 @@ Signed-off-by: Ramya Gnanasekar const struct ath11k_hw_ops wcn6855_ops = { --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h -@@ -128,6 +128,8 @@ enum ath11k_bus { - +@@ -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 + #else + /* Num VDEVS per radio */ + #define TARGET_NUM_VDEVS(ab) (ab->hw_params.num_vdevs_peers[ab->qmi.target_mem_mode].num_vdevs) +@@ -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 ++#define ATH11K_DP_RXDMA_REFILL_RING_SIZE 2048 ++#define ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE 2048 + #endif + + /* Num of peers for Single Radio mode */ +@@ -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]; -@@ -287,6 +289,16 @@ struct ath11k_hw_ops { + 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); From d69605496b639f631cb699693961faeb1b081bff Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 18 Mar 2024 04:32:56 -0400 Subject: [PATCH 145/225] ath11k_nss: Remove SFE related code Cleanup SFE (shortcut fe) related code as we're not using it on NSS --- ...se-HW-checksum-offload-only-for-ethm.patch | 31 +------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index 6b5cf7f3e24660..50466d46c37880 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 @@ -67,15 +67,7 @@ Signed-off-by: Tamizh Chelvam Raja if (!skb) { len = 0; goto out; -@@ -4571,7 +4573,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; -@@ -4715,7 +4716,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4714,7 +4716,7 @@ static void ieee80211_8023_xmit(struct i } } @@ -84,27 +76,6 @@ Signed-off-by: Tamizh Chelvam Raja if (!skb) return; -@@ -4835,6 +4836,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 = {}; -@@ -4869,9 +4871,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 @@ -2267,6 +2267,10 @@ int ieee80211_if_add(struct ieee80211_lo From ca17b3938dfe298669dc51a0bc843d5b5c698970 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 18 Mar 2024 04:36:52 -0400 Subject: [PATCH 146/225] ath11k_nss: idr, ampdu, and skb headroom check optimizations --- ...d-ampdu-id-in-802.11-radiotap-header.patch | 279 ++++++++++++++++++ ...999-336-0001-ath11k-idr-optimization.patch | 132 +++++++++ .../999-336-0002-ath11k-Use-idr_replace.patch | 28 +- ...k-skb_headroom-before-using-skb_push.patch | 253 ++++++++++++++++ 4 files changed, 686 insertions(+), 6 deletions(-) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/999-312-ath11k-add-ampdu-id-in-802.11-radiotap-header.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/999-336-0001-ath11k-idr-optimization.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/999-374-ath11k-Check-skb_headroom-before-using-skb_push.patch 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 00000000000000..1f554ae95ccc69 --- /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 +@@ -5994,6 +5994,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; +@@ -6001,6 +6002,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 +@@ -306,6 +306,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 00000000000000..499f720caba8cb --- /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 +@@ -3336,18 +3336,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); +@@ -4574,17 +4572,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), +@@ -5005,18 +5000,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); +@@ -5131,16 +5124,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, +@@ -6399,16 +6390,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 index c2cc4f2f89f43e..c5134fca93a867 100644 --- 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 @@ -130,25 +130,24 @@ Signed-off-by: Tamizh Chelvam srng = &ab->hal.srng_list[dp->reo_dst_ring[ring_id].ring_id]; -@@ -3383,8 +3405,16 @@ try_again: +@@ -3385,8 +3407,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_find(&rx_ring->bufs_idr, buf_id); +- 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); + spin_unlock_bh(&rx_ring->idr_lock); if (unlikely(!msdu)) { ath11k_warn(ab, "frame rx with invalid buf_id %d\n", - buf_id); -@@ -3464,9 +3494,12 @@ try_again: +@@ -3464,9 +3493,12 @@ try_again: rx_ring = &ar->dp.rx_refill_buf_ring; ath11k_dp_rxbufs_replenish(ab, i, rx_ring, num_buffs_reaped[i], @@ -190,7 +189,24 @@ Signed-off-by: Tamizh Chelvam srng = &ab->hal.srng_list[dp->rx_rel_ring.ring_id]; -@@ -5129,7 +5165,7 @@ int ath11k_dp_rx_process_wbm_err(struct +@@ -5077,9 +5112,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", +@@ -5124,7 +5165,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], diff --git a/package/kernel/mac80211/patches/nss/ath11k/999-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 new file mode 100644 index 00000000000000..b58b13eebe1d40 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/999-374-ath11k-Check-skb_headroom-before-using-skb_push.patch @@ -0,0 +1,253 @@ +From efecc6e8355d02aeac7bf1a43397551440a8d0d8 Mon Sep 17 00:00:00 2001 +From: Tamizh Chelvam Raja +Date: Thu, 30 Mar 2023 22:12:56 +0530 +Subject: [PATCH] ath11k: Check skb_headroom before using skb_push + +Below kernel panic may occur if there is no +skb_headroom available for performing skb_push. + +<4>[67506.565072] CPU: 1 PID: 1741 Comm: ap-wireless-opt Not tainted 5.4.89+ #0 +<4>[67506.578860] Hardware name: Generic DT based system +<4>[67506.585728] PC is at fortify_panic+0x10/0x18 +<4>[67506.590406] LR is at fortify_panic+0x10/0x18 + +(fortify_panic) from [<7f2cd3cc>] (ath11k_dp_rx_crypto_icv_len+0x1e0/0x161c [ath11k]) +(ath11k_dp_rx_crypto_icv_len [ath11k]) from [<7f2cdbac>] (ath11k_dp_rx_crypto_icv_len+0x9c0/0x161c [ath11k]) +(ath11k_dp_rx_crypto_icv_len [ath11k]) from [<7f2ce0e8>] (ath11k_dp_rx_crypto_icv_len+0xefc/0x161c [ath11k]) +(ath11k_dp_rx_crypto_icv_len [ath11k]) from [<7f2cedb0>] (ath11k_dp_process_rx+0x4ec/0x544 [ath11k]) +(ath11k_dp_process_rx [ath11k]) from [<7f2c417c>] (ath11k_dp_service_srng+0xdc/0x2a0 [ath11k]) +(ath11k_dp_service_srng [ath11k]) from [<7f0d78c8>] (ath11k_pci_ext_grp_napi_poll+0x20/0x50 [ath11k_pci]) +(ath11k_pci_ext_grp_napi_poll [ath11k_pci]) from [<806a6a74>] (__napi_poll+0x28/0xb8) +(__napi_poll) from [<806a6c9c>] (net_rx_action+0xec/0x280) +(net_rx_action) from [<8010226c>] (__do_softirq+0xc4/0x248) +(__do_softirq) from [<8011f230>] (irq_exit+0x6c/0xcc) +(irq_exit) from [<80162a08>] (__handle_domain_irq+0x8c/0xb0) +(__handle_domain_irq) from [<803f0188>] (gic_handle_irq+0x54/0x8c) +(gic_handle_irq) from [<80101a8c>] (__irq_svc+0x6c/0xa8) + +Fix this by checking skb_headroom and expand the +headroom if required size is not available. + +Signed-off-by: Tamizh Chelvam Raja +--- + drivers/net/wireless/ath/ath11k/dp_rx.c | 70 +++++++++++++++++++++++++ + 1 file changed, 70 insertions(+) + +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -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; ++ int expand_by; + u8 *crypto_hdr; + + if (!(status->flag & RX_FLAG_IV_STRIPPED)) { + crypto_len = ath11k_dp_rx_crypto_param_len(ar, enctype); ++ if (skb_headroom(msdu) < crypto_len) { ++ expand_by = crypto_len - skb_headroom(msdu); ++ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) ++ return; ++ } + crypto_hdr = skb_push(msdu, crypto_len); + ath11k_dp_rx_desc_get_crypto_header(ab, rx_desc, crypto_hdr, enctype); + } + + fc = ath11k_dp_rxdesc_get_mpdu_frame_ctrl(ab, rx_desc); + hdr_len = ieee80211_hdrlen(fc); ++ 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; ++ } + skb_push(msdu, hdr_len); + hdr = (struct ieee80211_hdr *)msdu->data; + hdr->frame_control = fc; +@@ -2499,6 +2510,7 @@ static void ath11k_dp_rx_h_undecap_nwifi + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + u16 qos_ctl = 0; ++ int expand_by = 0; + u8 *qos, *crypto_hdr; + bool add_qos_ctrl = false; + +@@ -2543,26 +2555,46 @@ static void ath11k_dp_rx_h_undecap_nwifi + } + + if (!(status->flag & RX_FLAG_IV_STRIPPED)) { ++ 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; ++ } + if (first_hdr) { +- memcpy(skb_push(msdu, +- ath11k_dp_rx_crypto_param_len(ar, enctype)), +- (void *)hdr + hdr_len, +- ath11k_dp_rx_crypto_param_len(ar, enctype)); ++ memcpy(skb_push(msdu, crypto_param_len), ++ (void *)hdr + hdr_len, crypto_param_len); + } else { +- crypto_hdr = skb_push(msdu, ath11k_dp_rx_crypto_param_len(ar, enctype)); ++ crypto_hdr = skb_push(msdu, crypto_param_len); + ath11k_dp_rx_desc_get_crypto_header(ar->ab, + rxcb->rx_desc, crypto_hdr, enctype); + } + } + + if (!rxcb->is_first_msdu || add_qos_ctrl) { ++ if (skb_headroom(msdu) < IEEE80211_QOS_CTL_LEN) { ++ expand_by = IEEE80211_QOS_CTL_LEN - skb_headroom(msdu); ++ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) ++ return; ++ } + memcpy(skb_push(msdu, + IEEE80211_QOS_CTL_LEN), &qos_ctl, + IEEE80211_QOS_CTL_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), decap_hdr, hdr_len); + return; + } + ++ 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); + + /* original 802.11 header has a different DA and in +@@ -2671,6 +2703,7 @@ static void ath11k_dp_rx_h_undecap_eth(s + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + void *rfc1042; ++ int expand_by; + struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); + struct ath11k_dp_rfc1042_hdr rfc = {0xaa, 0xaa, 0x03, {0x00, 0x00, 0x00}}; + +@@ -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)); ++ if (skb_headroom(msdu) < sizeof(struct ath11k_dp_rfc1042_hdr)) { ++ expand_by = sizeof(struct ath11k_dp_rfc1042_hdr) - skb_headroom(msdu); ++ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) ++ return; ++ } + 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); +@@ -2697,6 +2735,11 @@ static void ath11k_dp_rx_h_undecap_eth(s + skb_pull(msdu, sizeof(struct ethhdr)); + + /* push rfc1042/llc/snap */ ++ if (skb_headroom(msdu) < sizeof(struct ath11k_dp_rfc1042_hdr)) { ++ expand_by = sizeof(struct ath11k_dp_rfc1042_hdr) - skb_headroom(msdu); ++ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) ++ return; ++ } + memcpy(skb_push(msdu, sizeof(struct ath11k_dp_rfc1042_hdr)), rfc1042, + sizeof(struct ath11k_dp_rfc1042_hdr)); + +@@ -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)) { +- 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); + + exit: +@@ -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); + } + +@@ -2890,7 +2954,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; +@@ -3123,10 +3187,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; ++ int expand_by; + + if (status->encoding == RX_ENC_HE && + !(status->flag & RX_FLAG_RADIOTAP_HE) && + !(status->flag & RX_FLAG_SKIP_MONITOR)) { ++ if (skb_headroom(msdu) < sizeof(known)) { ++ expand_by = sizeof(known) - skb_headroom(msdu); ++ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) ++ goto exit; ++ } + he = skb_push(msdu, sizeof(known)); + memcpy(he, &known, sizeof(known)); + status->flag |= RX_FLAG_RADIOTAP_HE; +@@ -3182,6 +3252,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); + } + From 2735ec711f8adb37d77256971444c3076678b333 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 18 Mar 2024 04:38:40 -0400 Subject: [PATCH 147/225] ath11k_nss: get valid last_rate for rx_bitrate from cpu stats --- ...id-last_rate-for-rx_bitrate-from-cpu.patch | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 package/kernel/mac80211/patches/nss/subsys/751-mac80211-Get-valid-last_rate-for-rx_bitrate-from-cpu.patch 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 00000000000000..098767aa3f36db --- /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 +@@ -2396,7 +2396,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; +@@ -2409,8 +2409,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; +@@ -2480,7 +2485,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; +@@ -2680,7 +2685,7 @@ void sta_set_sinfo(struct sta_info *sta, + struct ieee80211_sta_rx_stats *last_rxstats; + struct link_sta_info *link_sta = NULL; + +- last_rxstats = sta_get_last_rx_stats(sta); ++ last_rxstats = sta_get_last_rx_stats(sta, false); + + sinfo->generation = sdata->local->sta_generation; + +@@ -2924,7 +2929,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)) From 0ea0296679aaa8388f72a263623d7211941f34c6 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 18 Mar 2024 04:39:17 -0400 Subject: [PATCH 148/225] ath11k_nss: 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. --- ...wifi-ath11k-Fix-BCCA-counter-for-EMA.patch | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/999-783-001-wifi-ath11k-Fix-BCCA-counter-for-EMA.patch 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 00000000000000..cf712593cc15b8 --- /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(); + } From ef31c2c68701d15a92b83d7318d15d7cc3c1056f Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 18 Mar 2024 11:36:18 -0400 Subject: [PATCH 149/225] qualcommax: refactor and reorg patches to match QSDK * Reordered code logic to match up with QSDK's patches-6.1 feed Consolidated. * Merged Add-IFF_EXT_HW_NO_OFFLOAD into PPPOE patch * Merged Fix-NSS-ECM-BRK-kernel-panic into CORE ecm patch. * Remove unnecessary `ipv6_dev_find_and_hold' ECM function as it's not needed in linux-6.1+ and recent NHSS.QSDK 12.4.5.r5 release * Fix DSCPREMARK extenstion not marking packets in ECM for being disabled. Added `qca-nf-conntrack` depends to notmodules. --- package/kernel/linux/modules/netfilter.mk | 1 + .../0600-1-qca-nss-ecm-support-CORE.patch | 267 ++++++++---------- ...-2-qca-nss-ecm-support-PPPOE-offload.patch | 24 +- ...00-3-qca-nss-ecm-support-net-bonding.patch | 72 ++--- ...pport-net-bonding-over-LAG-interface.patch | 171 +++++------ ...nss-ecm-support-netfilter-DSCPREMARK.patch | 154 ++++++++++ ...-nss-ecm-netfilter-tcp_window_check.patch} | 19 +- ...nss-ecm-support-netfilter-DSCPREMARK.patch | 69 ----- ...x-IPv6-user-route-change-event-calls.patch | 89 ++++++ ...01-1-qca-add-nss-bridge-mgr-support.patch} | 42 ++- ...602-1-qca-nss-drv-add-qdisc-support.patch} | 0 ...-1-qca-nss-clients-add-qdisc-support.patch | 4 +- ...ca-nss-clients-add-iptunnel-support.patch} | 2 +- ...3-qca-nss-clients-add-vxlan-support.patch} | 14 +- ...-nss-clients-iptunnel-lock-this-cpu.patch} | 2 +- ...patch => 0604-1-qca-add-mcs-support.patch} | 223 ++++++--------- ..._ecache-Fix-NSS-ECM-BRK-kernel-panic.patch | 10 - ...l-pointer-dereference-in-ipv6-output.patch | 2 +- ...-netdevice-Add-IFF_EXT_HW_NO_OFFLOAD.patch | 11 - 19 files changed, 624 insertions(+), 552 deletions(-) create mode 100644 target/linux/qualcommax/patches-6.1/0600-5-qca-nss-ecm-support-netfilter-DSCPREMARK.patch rename target/linux/qualcommax/patches-6.1/{0613-netfilter_optional_tcp_window_check.patc.patch => 0600-6-qca-nss-ecm-netfilter-tcp_window_check.patch} (80%) delete mode 100644 target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch create mode 100644 target/linux/qualcommax/patches-6.1/0600-7-qca-nss-ecm-fix-IPv6-user-route-change-event-calls.patch rename target/linux/qualcommax/patches-6.1/{0601-qca-add-nss-bridge-mgr-support.patch => 0601-1-qca-add-nss-bridge-mgr-support.patch} (82%) rename target/linux/qualcommax/patches-6.1/{0602-qca-nss-drv-add-qdisc-support.patch => 0602-1-qca-nss-drv-add-qdisc-support.patch} (100%) rename target/linux/qualcommax/patches-6.1/{0603-4-qca-nss-clients-add-iptunnel-support.patch => 0603-2-qca-nss-clients-add-iptunnel-support.patch} (98%) rename target/linux/qualcommax/patches-6.1/{0603-5-qca-nss-clients-add-vxlan-support.patch => 0603-3-qca-nss-clients-add-vxlan-support.patch} (87%) rename target/linux/qualcommax/patches-6.1/{0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch => 0603-4-qca-nss-clients-iptunnel-lock-this-cpu.patch} (95%) rename target/linux/qualcommax/patches-6.1/{0604-qca-add-mcs-support.patch => 0604-1-qca-add-mcs-support.patch} (83%) delete mode 100644 target/linux/qualcommax/patches-6.1/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch delete mode 100644 target/linux/qualcommax/patches-6.1/0614-netdevice-Add-IFF_EXT_HW_NO_OFFLOAD.patch diff --git a/package/kernel/linux/modules/netfilter.mk b/package/kernel/linux/modules/netfilter.mk index da3e69e49ac6f1..42d29d485a3915 100644 --- a/package/kernel/linux/modules/netfilter.mk +++ b/package/kernel/linux/modules/netfilter.mk @@ -312,6 +312,7 @@ $(eval $(call KernelPackage,ipt-offload)) define KernelPackage/ipt-ipopt TITLE:=Modules for matching/changing IP packet options KCONFIG:=$(KCONFIG_IPT_IPOPT) + DEPENDS:=+PACKAGE_kmod-nf-conntrack:kmod-nf-conntrack FILES:=$(foreach mod,$(IPT_IPOPT-m),$(LINUX_DIR)/net/$(mod).ko) AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_IPOPT-m))) $(call AddDepends/ipt) diff --git a/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch b/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch index 32f7c70d4e3409..8621227ab8c574 100644 --- a/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch +++ b/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch @@ -55,31 +55,26 @@ #endif --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h -@@ -235,7 +235,28 @@ extern void vlan_vids_del_by_dev(struct +@@ -143,7 +143,10 @@ extern struct net_device *__vlan_find_de + extern int vlan_for_each(struct net_device *dev, + int (*action)(struct net_device *dev, int vid, + void *arg), void *arg); ++extern void __vlan_dev_update_accel_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *stats); /* QCA NSS ECM support */ + extern struct net_device *vlan_dev_real_dev(const struct net_device *dev); ++extern struct net_device *vlan_dev_next_dev(const struct net_device *dev); /* QCA NSS ECM support */ + extern u16 vlan_dev_vlan_id(const struct net_device *dev); + extern __be16 vlan_dev_vlan_proto(const struct net_device *dev); +@@ -236,6 +239,12 @@ extern void vlan_vids_del_by_dev(struct extern bool vlan_uses_dev(const struct net_device *dev); -+/* QCA NSS ECM support - Start */ -+extern void __vlan_dev_update_accel_stats(struct net_device *dev, -+ struct rtnl_link_stats64 *stats); -+extern u16 vlan_dev_get_egress_prio(struct net_device *dev, u32 skb_prio); -+extern struct net_device *vlan_dev_next_dev(const struct net_device *dev); -+/* QCA NSS ECM support - End */ -+ #else -+/* QCA NSS ECM support - Start */ +static inline void __vlan_dev_update_accel_stats(struct net_device *dev, + struct rtnl_link_stats64 *stats) +{ + -+} -+ -+static inline u16 vlan_dev_get_egress_prio(struct net_device *dev, -+ u32 skb_prio) -+{ -+ return 0; -+} -+/* QCA NSS ECM support - End */ ++} /* QCA NSS ECM support - End */ + static inline struct net_device * __vlan_find_dev_deep_rcu(struct net_device *real_dev, @@ -90,25 +85,13 @@ NETDEV_OFFLOAD_XSTATS_DISABLE, NETDEV_OFFLOAD_XSTATS_REPORT_USED, NETDEV_OFFLOAD_XSTATS_REPORT_DELTA, -+ /* QCA NSS ECM Support - Start */ -+ NETDEV_BR_JOIN, -+ NETDEV_BR_LEAVE, -+ /* QCA NSS ECM Support - End */ ++ /* QCA NSS ECM Support - Start */ ++ NETDEV_BR_JOIN, ++ NETDEV_BR_LEAVE, ++ /* QCA NSS ECM Support - End */ }; const char *netdev_cmd_to_name(enum netdev_cmd cmd); ---- a/include/net/addrconf.h -+++ b/include/net/addrconf.h -@@ -514,4 +514,9 @@ int if6_proc_init(void); - void if6_proc_exit(void); - #endif - -+/* QCA NSS ECM support - Start */ -+struct net_device *ipv6_dev_find_and_hold(struct net *net, struct in6_addr *addr, -+ int strict); -+/* QCA NSS ECM support - End */ -+ - #endif --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -211,6 +211,11 @@ void rt6_multipath_rebalance(struct fib6 @@ -125,20 +108,36 @@ const struct dst_entry *dst = skb_dst(skb); --- a/include/net/neighbour.h +++ b/include/net/neighbour.h -@@ -602,4 +602,15 @@ static inline void neigh_update_is_route - *notify = 1; - } +@@ -249,6 +249,13 @@ static inline int neigh_parms_family(str + return p->tbl->family; } -+ + +/* QCA NSS ECM support - Start */ +struct neigh_mac_update { + unsigned char old_mac[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; + unsigned char update_mac[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; +}; ++/* QCA NSS ECM support - End */ + + #define NEIGH_PRIV_ALIGN sizeof(long long) + #define NEIGH_ENTRY_SIZE(size) ALIGN((size), NEIGH_PRIV_ALIGN) + +@@ -397,6 +404,11 @@ int neigh_xmit(int fam, struct net_devic + void pneigh_for_each(struct neigh_table *tbl, + void (*cb)(struct pneigh_entry *)); + ++/* QCA NSS ECM support - Start */ +extern void neigh_mac_update_register_notify(struct notifier_block *nb); +extern void neigh_mac_update_unregister_notify(struct notifier_block *nb); +/* QCA NSS ECM support - End */ ++ + struct neigh_seq_state { + struct seq_net_private p; + struct neigh_table *tbl; +@@ -602,4 +614,5 @@ static inline void neigh_update_is_route + *notify = 1; + } + } + #endif --- a/include/net/route.h @@ -169,8 +168,8 @@ #endif --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c -@@ -555,4 +555,52 @@ static int __init vlan_offload_init(void - return 0; +@@ -72,6 +72,28 @@ bool vlan_do_receive(struct sk_buff **sk + return true; } +/* QCA NSS ECM support - Start */ @@ -193,27 +192,17 @@ + u64_stats_update_end(&stats->syncp); +} +EXPORT_SYMBOL(__vlan_dev_update_accel_stats); ++/* QCA NSS ECM support - End */ + -+/* Lookup the 802.1p egress_map table and return the 802.1p value */ -+u16 vlan_dev_get_egress_prio(struct net_device *dev, u32 skb_prio) -+{ -+ struct vlan_priority_tci_mapping *mp; -+ -+ mp = vlan_dev_priv(dev)->egress_priority_map[(skb_prio & 0xf)]; -+ while (mp) { -+ if (mp->priority == skb_prio) { -+ /* This should already be shifted -+ * to mask correctly with the -+ * VLAN's TCI -+ */ -+ return mp->vlan_qos; -+ } -+ mp = mp->next; -+ } -+ return 0; -+} -+EXPORT_SYMBOL(vlan_dev_get_egress_prio); -+ + /* Must be invoked with rcu_read_lock. */ + struct net_device *__vlan_find_dev_deep_rcu(struct net_device *dev, + __be16 vlan_proto, u16 vlan_id) +@@ -110,6 +132,15 @@ struct net_device *vlan_dev_real_dev(con + } + EXPORT_SYMBOL(vlan_dev_real_dev); + ++/* QCA NSS ECM support - Start */ ++/* Caller is responsible to hold the reference of the returned device */ +struct net_device *vlan_dev_next_dev(const struct net_device *dev) +{ + return vlan_dev_priv(dev)->real_dev; @@ -221,16 +210,16 @@ +EXPORT_SYMBOL(vlan_dev_next_dev); +/* QCA NSS ECM support - End */ + - fs_initcall(vlan_offload_init); + u16 vlan_dev_vlan_id(const struct net_device *dev) + { + return vlan_dev_priv(dev)->vlan_id; --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c -@@ -33,6 +33,35 @@ static const struct rhashtable_params br +@@ -33,6 +33,20 @@ static const struct rhashtable_params br static struct kmem_cache *br_fdb_cache __read_mostly; -+/* QCA NSS ECM support - Start */ +ATOMIC_NOTIFIER_HEAD(br_fdb_notifier_list); -+ATOMIC_NOTIFIER_HEAD(br_fdb_update_notifier_list); + +void br_fdb_register_notify(struct notifier_block *nb) +{ @@ -243,28 +232,14 @@ + atomic_notifier_chain_unregister(&br_fdb_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(br_fdb_unregister_notify); -+ -+void br_fdb_update_register_notify(struct notifier_block *nb) -+{ -+ atomic_notifier_chain_register(&br_fdb_update_notifier_list, nb); -+} -+EXPORT_SYMBOL_GPL(br_fdb_update_register_notify); -+ -+void br_fdb_update_unregister_notify(struct notifier_block *nb) -+{ -+ atomic_notifier_chain_unregister(&br_fdb_update_notifier_list, nb); -+} -+EXPORT_SYMBOL_GPL(br_fdb_update_unregister_notify); -+/* QCA NSS ECM support - End */ + int __init br_fdb_init(void) { br_fdb_cache = kmem_cache_create("bridge_fdb_cache", -@@ -185,7 +214,26 @@ static void fdb_notify(struct net_bridge - struct sk_buff *skb; - int err = -ENOBUFS; +@@ -188,6 +202,25 @@ static void fdb_notify(struct net_bridge + if (swdev_notify) + br_switchdev_fdb_notify(br, fdb, type); -- if (swdev_notify) + /* QCA NSS ECM support - Start */ + if (fdb->dst) { + int event; @@ -284,11 +259,33 @@ + } + /* QCA NSS ECM support - End */ + -+ if (swdev_notify) - br_switchdev_fdb_notify(br, fdb, type); - skb = nlmsg_new(fdb_nlmsg_size(), GFP_ATOMIC); -@@ -520,6 +568,7 @@ void br_fdb_cleanup(struct work_struct * + if (skb == NULL) + goto errout; +@@ -512,6 +545,22 @@ out: + spin_unlock_bh(&br->hash_lock); + } + ++/* QCA NSS ECM support - Start */ ++ATOMIC_NOTIFIER_HEAD(br_fdb_update_notifier_list); ++ ++void br_fdb_update_register_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_register(&br_fdb_update_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(br_fdb_update_register_notify); ++ ++void br_fdb_update_unregister_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_unregister(&br_fdb_update_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(br_fdb_update_unregister_notify); ++/* QCA NSS ECM support - End */ ++ + void br_fdb_cleanup(struct work_struct *work) + { + struct net_bridge *br = container_of(work, struct net_bridge, +@@ -520,6 +569,7 @@ void br_fdb_cleanup(struct work_struct * unsigned long delay = hold_time(br); unsigned long work_delay = delay; unsigned long now = jiffies; @@ -296,7 +293,7 @@ /* this part is tricky, in order to avoid blocking learning and * consequently forwarding, we rely on rcu to delete objects with -@@ -546,8 +595,15 @@ void br_fdb_cleanup(struct work_struct * +@@ -546,8 +596,15 @@ void br_fdb_cleanup(struct work_struct * work_delay = min(work_delay, this_timer - now); } else { spin_lock_bh(&br->hash_lock); @@ -313,7 +310,7 @@ spin_unlock_bh(&br->hash_lock); } } -@@ -879,6 +935,12 @@ void br_fdb_update(struct net_bridge *br +@@ -879,6 +936,12 @@ void br_fdb_update(struct net_bridge *br &fdb->flags))) clear_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags); @@ -326,11 +323,10 @@ } if (unlikely(test_bit(BR_FDB_ADDED_BY_USER, &flags))) -@@ -1466,3 +1528,62 @@ void br_fdb_clear_offload(const struct n - spin_unlock_bh(&p->br->hash_lock); +@@ -902,6 +965,64 @@ void br_fdb_update(struct net_bridge *br + } } - EXPORT_SYMBOL_GPL(br_fdb_clear_offload); -+ + +/* QCA NSS ECM support - Start */ +/* Refresh FDB entries for bridge packets being forwarded by offload engines */ +void br_refresh_fdb_entry(struct net_device *dev, const char *addr) @@ -387,8 +383,11 @@ + return fdb; +} +EXPORT_SYMBOL_GPL(br_fdb_has_entry); -+/* QCA NSS ECM support - End */ + ++/* QCA NSS ECM support - End */ + /* Dump information about entries, in response to GETNEIGH */ + int br_fdb_dump(struct sk_buff *skb, + struct netlink_callback *cb, --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -26,6 +26,12 @@ @@ -422,23 +421,11 @@ /* Since more than one interface can be attached to a bridge, * there still maybe an alternate path for netconsole to use; * therefore there is no reason for a NETDEV_RELEASE event. -@@ -775,3 +785,96 @@ bool br_port_flag_is_set(const struct ne +@@ -775,3 +785,97 @@ bool br_port_flag_is_set(const struct ne return p->flags & flag; } EXPORT_SYMBOL_GPL(br_port_flag_is_set); + -+/* QCA NSS ECM support - Start */ -+/* API to know if hairpin feature is enabled/disabled on this bridge port */ -+bool br_is_hairpin_enabled(struct net_device *dev) -+{ -+ struct net_bridge_port *port = br_port_get_check_rcu(dev); -+ -+ if (likely(port)) -+ return port->flags & BR_HAIRPIN_MODE; -+ return false; -+} -+EXPORT_SYMBOL_GPL(br_is_hairpin_enabled); -+ +/* br_port_dev_get() + * If a skb is provided, and the br_port_dev_get_hook_t hook exists, + * use that to try and determine the egress port for that skb. @@ -518,6 +505,19 @@ + u64_stats_update_end(&tstats->syncp); +} +EXPORT_SYMBOL_GPL(br_dev_update_stats); ++ ++/* QCA NSS ECM support - Start */ ++/* API to know if hairpin feature is enabled/disabled on this bridge port */ ++bool br_is_hairpin_enabled(struct net_device *dev) ++{ ++ struct net_bridge_port *port = br_port_get_check_rcu(dev); ++ ++ if (likely(port)) ++ return port->flags & BR_HAIRPIN_MODE; ++ return false; ++} ++EXPORT_SYMBOL_GPL(br_is_hairpin_enabled); ++ +/* QCA NSS ECM support - End */ --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -656,16 +656,16 @@ const struct in6_addr *daddr) --- a/net/ipv6/route.c +++ b/net/ipv6/route.c -@@ -3854,6 +3854,9 @@ out_free: - return ERR_PTR(err); +@@ -197,6 +197,9 @@ static void rt6_uncached_list_flush_dev( + } } +/* Define route change notification chain. */ +ATOMIC_NOTIFIER_HEAD(ip6route_chain); /* QCA NSS ECM support */ + - int ip6_route_add(struct fib6_config *cfg, gfp_t gfp_flags, - struct netlink_ext_ack *extack) - { + static inline const void *choose_neigh_daddr(const struct in6_addr *p, + struct sk_buff *skb, + const void *daddr) @@ -3865,6 +3868,10 @@ int ip6_route_add(struct fib6_config *cf return PTR_ERR(rt); @@ -714,7 +714,7 @@ N(SVLAN_FILTER_PUSH_INFO) N(SVLAN_FILTER_DROP_INFO) N(PRE_CHANGEADDR) N(OFFLOAD_XSTATS_ENABLE) N(OFFLOAD_XSTATS_DISABLE) N(OFFLOAD_XSTATS_REPORT_USED) N(OFFLOAD_XSTATS_REPORT_DELTA) -+ N(BR_JOIN) N(BR_LEAVE) ++ N(BR_JOIN) N(BR_LEAVE) } #undef N return "UNKNOWN_NETDEV_EVENT"; @@ -728,43 +728,6 @@ static void ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) -@@ -2060,6 +2061,36 @@ struct inet6_ifaddr *ipv6_get_ifaddr(str - - return result; - } -+EXPORT_SYMBOL(ipv6_get_ifaddr); -+ -+/* ipv6_dev_find_and_hold() -+ * Find (and hold) net device that has the given address. -+ * Or NULL on failure. -+ */ -+struct net_device *ipv6_dev_find_and_hold(struct net *net, struct in6_addr *addr, -+ int strict) -+{ -+ struct inet6_ifaddr *ifp; -+ struct net_device *dev; -+ -+ ifp = ipv6_get_ifaddr(net, addr, NULL, strict); -+ if (!ifp) -+ return NULL; -+ -+ if (!ifp->idev) { -+ in6_ifa_put(ifp); -+ return NULL; -+ } -+ -+ dev = ifp->idev->dev; -+ if (dev) -+ dev_hold(dev); -+ -+ in6_ifa_put(ifp); -+ -+ return dev; -+} -+EXPORT_SYMBOL(ipv6_dev_find_and_hold); - - /* Gets referenced address, destroys ifaddr */ - --- a/include/net/vxlan.h +++ b/include/net/vxlan.h @@ -432,6 +432,15 @@ static inline __be32 vxlan_compute_rco(u @@ -783,3 +746,13 @@ static inline unsigned short vxlan_get_sk_family(struct vxlan_sock *vs) { return vs->sock->sk->sk_family; +--- a/net/netfilter/nf_conntrack_ecache.c ++++ b/net/netfilter/nf_conntrack_ecache.c +@@ -266,7 +266,6 @@ void nf_conntrack_register_notifier(stru + mutex_lock(&nf_ct_ecache_mutex); + notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb, + lockdep_is_held(&nf_ct_ecache_mutex)); +- WARN_ON_ONCE(notify); + rcu_assign_pointer(net->ct.nf_conntrack_event_cb, new); + mutex_unlock(&nf_ct_ecache_mutex); + } diff --git a/target/linux/qualcommax/patches-6.1/0600-2-qca-nss-ecm-support-PPPOE-offload.patch b/target/linux/qualcommax/patches-6.1/0600-2-qca-nss-ecm-support-PPPOE-offload.patch index 6d6119e8bf2836..01c13a341f7029 100644 --- a/target/linux/qualcommax/patches-6.1/0600-2-qca-nss-ecm-support-PPPOE-offload.patch +++ b/target/linux/qualcommax/patches-6.1/0600-2-qca-nss-ecm-support-PPPOE-offload.patch @@ -466,17 +466,26 @@ #endif /* !(__LINUX_IF_PPPOX_H) */ --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h -@@ -1733,6 +1733,24 @@ enum netdev_priv_flags { - IFF_NO_IP_ALIGN = BIT_ULL(33), +@@ -1762,6 +1762,36 @@ enum netdev_priv_flags { + IFF_NO_IP_ALIGN = BIT_ULL(34), }; -+ +/** + * enum netdev_priv_flags_ext - &struct net_device priv_flags_ext + * + * These flags are used to check for device type and can be + * set and used by the drivers + * ++ * @IFF_EXT_TUN_TAP: device is a TUN/TAP device ++ * @IFF_EXT_PPP_L2TPV2: device is a L2TPV2 device ++ * @IFF_EXT_PPP_L2TPV3: device is a L2TPV3 device ++ * @IFF_EXT_PPP_PPTP: device is a PPTP device ++ * @IFF_EXT_GRE_V4_TAP: device is a GRE IPv4 TAP device ++ * @IFF_EXT_GRE_V6_TAP: device is a GRE IPv6 TAP device ++ * @IFF_EXT_IFB: device is an IFB device ++ * @IFF_EXT_MAPT: device is an MAPT device ++ * @IFF_EXT_HW_NO_OFFLOAD: device is an NON Offload device ++ * @IFF_EXT_L2TPV3: device is a L2TPV3 Ethernet device + */ +enum netdev_priv_flags_ext { + IFF_EXT_TUN_TAP = 1<<0, @@ -486,21 +495,22 @@ + IFF_EXT_GRE_V4_TAP = 1<<4, + IFF_EXT_GRE_V6_TAP = 1<<5, + IFF_EXT_IFB = 1<<6, ++ IFF_EXT_MAPT = 1<<7, ++ IFF_EXT_HW_NO_OFFLOAD = 1<<8, ++ IFF_EXT_ETH_L2TPV3 = 1<<9, +}; + #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN #define IFF_EBRIDGE IFF_EBRIDGE #define IFF_BONDING IFF_BONDING -@@ -2075,7 +2093,8 @@ struct net_device { +@@ -2075,6 +2103,7 @@ struct net_device { /* Read-mostly cache-line for fast-path access */ unsigned int flags; unsigned long long priv_flags; -- const struct net_device_ops *netdev_ops; + unsigned int priv_flags_ext; -+ const struct net_device_ops *netdev_ops; + const struct net_device_ops *netdev_ops; int ifindex; unsigned short gflags; - unsigned short hard_header_len; --- a/include/linux/ppp_channel.h +++ b/include/linux/ppp_channel.h @@ -19,6 +19,10 @@ diff --git a/target/linux/qualcommax/patches-6.1/0600-3-qca-nss-ecm-support-net-bonding.patch b/target/linux/qualcommax/patches-6.1/0600-3-qca-nss-ecm-support-net-bonding.patch index 508ad0ff585076..f2cb4f3a91fd23 100644 --- a/target/linux/qualcommax/patches-6.1/0600-3-qca-nss-ecm-support-net-bonding.patch +++ b/target/linux/qualcommax/patches-6.1/0600-3-qca-nss-ecm-support-net-bonding.patch @@ -1,63 +1,39 @@ --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c -@@ -252,6 +252,8 @@ static const struct flow_dissector_key f - }, - }; +@@ -208,6 +208,7 @@ atomic_t netpoll_block_tx = ATOMIC_INIT( + #endif + unsigned int bond_net_id __read_mostly; +static unsigned long bond_id_mask = 0xFFFFFFF0; /* QCA NSS ECM bonding support */ -+ - static struct flow_dissector flow_keys_bonding __read_mostly; - /*-------------------------- Forward declarations ---------------------------*/ -@@ -4383,6 +4385,24 @@ static int bond_get_lowest_level_rcu(str - } - #endif + static const struct flow_dissector_key flow_keys_bonding_keys[] = { + { +@@ -5793,8 +5794,14 @@ static void bond_destructor(struct net_d + if (bond->wq) + destroy_workqueue(bond->wq); -+/* QCA NSS ECM bonding support */ -+int bond_get_id(struct net_device *bond_dev) -+{ -+ struct bonding *bond; -+ int bond_id = 0; -+ -+ if (!((bond_dev->priv_flags & IFF_BONDING) && -+ (bond_dev->flags & IFF_MASTER))) -+ return -EINVAL; -+ -+ bond = netdev_priv(bond_dev); -+ bond_id = bond->id; -+ -+ return bond_id; -+} -+EXPORT_SYMBOL(bond_get_id); -+/* QCA NSS ECM bonding support */ ++ /* QCA NSS ECM bonding support - Start */ ++ if (bond->id != (~0U)) ++ clear_bit(bond->id, &bond_id_mask); ++ /* QCA NSS ECM bonding support - End */ + - static void bond_get_stats(struct net_device *bond_dev, - struct rtnl_link_stats64 *stats) - { -@@ -5795,6 +5815,11 @@ static void bond_destructor(struct net_d - if (bond->rr_tx_counter) free_percpu(bond->rr_tx_counter); + -+ /* QCA NSS ECM bonding support */ -+ if (bond->id != (~0U)) -+ clear_bit(bond->id, &bond_id_mask); -+ /* QCA NSS ECM bonding support */ } void bond_setup(struct net_device *bond_dev) -@@ -6358,6 +6383,14 @@ int bond_create(struct net *net, const c +@@ -6358,6 +6365,13 @@ int bond_create(struct net *net, const c bond_work_init_all(bond); -+ /* QCA NSS ECM bonding support - Start */ -+ bond->id = ~0U; -+ if (bond_id_mask != (~0UL)) { -+ bond->id = (u32)ffz(bond_id_mask); -+ set_bit(bond->id, &bond_id_mask); -+ } ++ /* QCA NSS ECM bonding support - Start */ ++ bond->id = ~0U; ++ if (bond_id_mask != (~0UL)) { ++ bond->id = (u32)ffz(bond_id_mask); ++ set_bit(bond->id, &bond_id_mask); ++ } + /* QCA NSS ECM bonding support - End */ -+ out: rtnl_unlock(); return res; @@ -67,15 +43,7 @@ spinlock_t ipsec_lock; #endif /* CONFIG_XFRM_OFFLOAD */ struct bpf_prog *xdp_prog; -+ u32 id; /* QCA NSS ECM bonding support */ ++ u32 id;/* QCA NSS ECM bonding support */ }; #define bond_slave_get_rcu(dev) \ -@@ -658,6 +659,7 @@ struct bond_net { - - int bond_rcv_validate(const struct sk_buff *skb, struct bonding *bond, struct slave *slave); - netdev_tx_t bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); -+int bond_get_id(struct net_device *bond_dev); /* QCA NSS ECM bonding support */ - int bond_create(struct net *net, const char *name); - int bond_create_sysfs(struct bond_net *net); - void bond_destroy_sysfs(struct bond_net *net); diff --git a/target/linux/qualcommax/patches-6.1/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch b/target/linux/qualcommax/patches-6.1/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch index 27d55711fac142..0548b17c8eb52a 100644 --- a/target/linux/qualcommax/patches-6.1/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch +++ b/target/linux/qualcommax/patches-6.1/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch @@ -1,12 +1,12 @@ --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c -@@ -114,7 +114,40 @@ static void ad_marker_info_received(stru - static void ad_marker_response_received(struct bond_marker *marker, +@@ -115,6 +115,40 @@ static void ad_marker_response_received( struct port *port); static void ad_update_actor_keys(struct port *port, bool reset); + +/* QCA NSS ECM bonding support - Start */ +struct bond_cb __rcu *bond_cb; - ++ +int bond_register_cb(struct bond_cb *cb) +{ + struct bond_cb *lag_cb; @@ -41,22 +41,13 @@ /* ================= api to bonding and kernel code ================== */ -@@ -424,7 +457,6 @@ static u16 __ad_timer_to_ticks(u16 timer - return retval; - } - -- - /* ================= ad_rx_machine helper functions ================== */ - - /** -@@ -1064,7 +1096,30 @@ static void ad_mux_machine(struct port * +@@ -1064,7 +1098,31 @@ static void ad_mux_machine(struct port * ad_disable_collecting_distributing(port, update_slave_arr); port->ntt = true; -- break; + -+ /* QCA NSS ECM bonding support - Start */ -+ /* Send a notificaton about change in state of this ++ /* QCA NSS ECM bonding support - Start */ ++ /* Send a notificaton about change in state of this + * port. We only want to handle case where port moves + * from AD_MUX_COLLECTING_DISTRIBUTING -> + * AD_MUX_ATTACHED. @@ -77,25 +68,25 @@ + rcu_read_unlock(); + } + -+ break; /* QCA NSS ECM bonding support - End */ + break; ++ /* QCA NSS ECM bonding support - End */ case AD_MUX_COLLECTING_DISTRIBUTING: port->actor_oper_port_state |= LACP_STATE_COLLECTING; port->actor_oper_port_state |= LACP_STATE_DISTRIBUTING; -@@ -1908,13 +1963,24 @@ static void ad_enable_collecting_distrib +@@ -1908,6 +1966,7 @@ static void ad_enable_collecting_distrib bool *update_slave_arr) { if (port->aggregator->is_active) { -- slave_dbg(port->slave->bond->dev, port->slave->dev, + struct bond_cb *lag_cb_main; /* QCA NSS ECM bonding support */ -+ slave_dbg(port->slave->bond->dev, port->slave->dev, + slave_dbg(port->slave->bond->dev, port->slave->dev, "Enabling port %d (LAG %d)\n", port->actor_port_number, - port->aggregator->aggregator_identifier); +@@ -1915,6 +1974,16 @@ static void ad_enable_collecting_distrib __enable_port(port); /* Slave array needs update */ *update_slave_arr = true; + -+ /* QCA NSS ECM bonding support - Start */ ++ /* QCA NSS ECM bonding support - Start */ + rcu_read_lock(); + lag_cb_main = rcu_dereference(bond_cb); + @@ -103,11 +94,11 @@ + lag_cb_main->bond_cb_link_up(port->slave->dev); + + rcu_read_unlock(); -+ /* QCA NSS ECM bonding support - End */ ++ /* QCA NSS ECM bonding support - End */ } } -@@ -2674,6 +2740,104 @@ int bond_3ad_get_active_agg_info(struct +@@ -2674,6 +2743,104 @@ int bond_3ad_get_active_agg_info(struct return ret; } @@ -214,7 +205,29 @@ { --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c -@@ -1186,6 +1186,23 @@ void bond_change_active_slave(struct bon +@@ -286,6 +286,21 @@ const char *bond_mode_name(int mode) + return names[mode]; + } + ++/* QCA NSS ECM bonding support */ ++int bond_get_id(struct net_device *bond_dev) ++{ ++ struct bonding *bond; ++ ++ if (!((bond_dev->priv_flags & IFF_BONDING) && ++ (bond_dev->flags & IFF_MASTER))) ++ return -EINVAL; ++ ++ bond = netdev_priv(bond_dev); ++ return bond->id; ++} ++EXPORT_SYMBOL(bond_get_id); ++/* QCA NSS ECM bonding support */ ++ + /** + * bond_dev_queue_xmit - Prepare skb for xmit. + * +@@ -1185,6 +1200,23 @@ void bond_change_active_slave(struct bon if (BOND_MODE(bond) == BOND_MODE_8023AD) bond_3ad_handle_link_change(new_active, BOND_LINK_UP); @@ -238,101 +251,97 @@ if (bond_is_lb(bond)) bond_alb_handle_link_change(bond, new_active, BOND_LINK_UP); } else { -@@ -1809,7 +1826,8 @@ int bond_enslave(struct net_device *bond +@@ -1808,6 +1840,7 @@ int bond_enslave(struct net_device *bond const struct net_device_ops *slave_ops = slave_dev->netdev_ops; struct slave *new_slave = NULL, *prev_slave; struct sockaddr_storage ss; -- int link_reporting; + struct bond_cb *lag_cb_main; /* QCA NSS ECM bonding support */ -+ int link_reporting; + int link_reporting; int res = 0, i; - if (slave_dev->flags & IFF_MASTER && -@@ -2252,6 +2270,15 @@ int bond_enslave(struct net_device *bond +@@ -2251,6 +2284,15 @@ int bond_enslave(struct net_device *bond bond_is_active_slave(new_slave) ? "an active" : "a backup", new_slave->link != BOND_LINK_DOWN ? "an up" : "a down"); -+ /* QCA NSS ECM bonding support - Start */ ++ /* QCA NSS ECM bonding support - Start */ + rcu_read_lock(); + lag_cb_main = rcu_dereference(bond_cb); + if (lag_cb_main && lag_cb_main->bond_cb_enslave) + lag_cb_main->bond_cb_enslave(slave_dev); + + rcu_read_unlock(); -+ /* QCA NSS ECM bonding support - End */ ++ /* QCA NSS ECM bonding support - End */ + /* enslave is successful */ bond_queue_slave_event(new_slave); return 0; -@@ -2317,6 +2344,15 @@ err_undo_flags: +@@ -2316,6 +2358,15 @@ err_undo_flags: } } -+ /* QCA NSS ECM bonding support - Start */ ++ /* QCA NSS ECM bonding support - Start */ + rcu_read_lock(); + lag_cb_main = rcu_dereference(bond_cb); + if (lag_cb_main && lag_cb_main->bond_cb_enslave) + lag_cb_main->bond_cb_enslave(slave_dev); + + rcu_read_unlock(); -+ /* QCA NSS ECM bonding support - End */ ++ /* QCA NSS ECM bonding support - End */ + return res; } -@@ -2339,7 +2375,8 @@ static int __bond_release_one(struct net +@@ -2337,6 +2388,7 @@ static int __bond_release_one(struct net + struct bonding *bond = netdev_priv(bond_dev); struct slave *slave, *oldcurrent; struct sockaddr_storage ss; - int old_flags = bond_dev->flags; -- netdev_features_t old_features = bond_dev->features; + struct bond_cb *lag_cb_main; /* QCA NSS ECM bonding support */ -+ netdev_features_t old_features = bond_dev->features; + int old_flags = bond_dev->flags; + netdev_features_t old_features = bond_dev->features; - /* slave is not a slave or master is not master of this slave */ - if (!(slave_dev->flags & IFF_SLAVE) || -@@ -2360,6 +2397,15 @@ static int __bond_release_one(struct net +@@ -2359,6 +2411,15 @@ static int __bond_release_one(struct net bond_set_slave_inactive_flags(slave, BOND_SLAVE_NOTIFY_NOW); -+ /* QCA NSS ECM bonding support - Start */ ++ /* QCA NSS ECM bonding support - Start */ + rcu_read_lock(); + lag_cb_main = rcu_dereference(bond_cb); + if (lag_cb_main && lag_cb_main->bond_cb_release) + lag_cb_main->bond_cb_release(slave_dev); + + rcu_read_unlock(); -+ /* QCA NSS ECM bonding support - End */ ++ /* QCA NSS ECM bonding support - End */ + bond_sysfs_slave_del(slave); /* recompute stats just before removing the slave */ -@@ -2679,6 +2725,8 @@ static void bond_miimon_commit(struct bo +@@ -2678,6 +2739,8 @@ static void bond_miimon_commit(struct bo struct slave *slave, *primary, *active; bool do_failover = false; struct list_head *iter; + struct net_device *slave_dev = NULL; /* QCA NSS ECM bonding support */ -+ struct bond_cb *lag_cb_main; /* QCA NSS ECM bonding support */ ++ struct bond_cb *lag_cb_main; /* QCA NSS ECM bonding support */ ASSERT_RTNL(); -@@ -2718,6 +2766,12 @@ static void bond_miimon_commit(struct bo +@@ -2717,6 +2780,12 @@ static void bond_miimon_commit(struct bo bond_set_active_slave(slave); } -+ /* QCA NSS ECM bonding support - Start */ ++ /* QCA NSS ECM bonding support - Start */ + if ((bond->params.mode == BOND_MODE_XOR) && + (!slave_dev)) + slave_dev = slave->dev; -+ /* QCA NSS ECM bonding support - End */ ++ /* QCA NSS ECM bonding support - End */ + slave_info(bond->dev, slave->dev, "link status definitely up, %u Mbps %s duplex\n", slave->speed == SPEED_UNKNOWN ? 0 : slave->speed, slave->duplex ? "full" : "half"); -@@ -2766,6 +2820,16 @@ static void bond_miimon_commit(struct bo +@@ -2765,6 +2834,16 @@ static void bond_miimon_commit(struct bo unblock_netpoll_tx(); } -+ /* QCA NSS ECM bonding support - Start */ ++ /* QCA NSS ECM bonding support - Start */ + rcu_read_lock(); + lag_cb_main = rcu_dereference(bond_cb); + @@ -340,12 +349,12 @@ + lag_cb_main->bond_cb_link_up(slave_dev); + + rcu_read_unlock(); -+ /* QCA NSS ECM bonding support - End */ ++ /* QCA NSS ECM bonding support - End */ + bond_set_carrier(bond); } -@@ -4013,8 +4077,219 @@ static inline u32 bond_eth_hash(struct s +@@ -4012,8 +4091,219 @@ static inline u32 bond_eth_hash(struct s return 0; ep = (struct ethhdr *)(data + mhoff); @@ -566,45 +575,40 @@ static bool bond_flow_ip(struct sk_buff *skb, struct flow_keys *fk, const void *data, int hlen, __be16 l2_proto, int *nhoff, int *ip_proto, bool l34) -@@ -5211,15 +5486,23 @@ static netdev_tx_t bond_3ad_xor_xmit(str +@@ -5192,15 +5482,18 @@ static netdev_tx_t bond_3ad_xor_xmit(str struct net_device *dev) { struct bonding *bond = netdev_priv(dev); - struct bond_up_slave *slaves; - struct slave *slave; -+ /* QCA NSS ECM bonding support - Start */ -+ struct net_device *outdev = NULL; -+ outdev = bond_3ad_get_tx_dev(skb, NULL, NULL, NULL, -+ NULL, 0, dev, NULL); ++ /* QCA NSS ECM bonding support - Start */ ++ struct net_device *outdev = NULL; - slaves = rcu_dereference(bond->usable_slaves); - slave = bond_xmit_3ad_xor_slave_get(bond, skb, slaves); - if (likely(slave)) - return bond_dev_queue_xmit(bond, skb, slave->dev); -+ if (!outdev) -+ goto out; ++ outdev = bond_3ad_get_tx_dev(skb, NULL, NULL, NULL, ++ NULL, 0, dev, NULL); ++ if (!outdev) { ++ dev_kfree_skb(skb); ++ return NETDEV_TX_OK; ++ } - return bond_tx_drop(dev, skb); -+ bond_dev_queue_xmit(bond, skb, outdev); -+ goto final; -+ -+out: -+ dev_kfree_skb(skb); -+ -+final: -+ return NETDEV_TX_OK; -+/* QCA NSS ECM bonding support - End */ ++ return bond_dev_queue_xmit(bond, skb, outdev); ++ /* QCA NSS ECM bonding support - End */ } /* in broadcast mode, we send everything to all usable interfaces. */ -@@ -5469,8 +5752,9 @@ static netdev_tx_t __bond_start_xmit(str +@@ -5450,8 +5743,9 @@ static netdev_tx_t __bond_start_xmit(str return bond_xmit_roundrobin(skb, dev); case BOND_MODE_ACTIVEBACKUP: return bond_xmit_activebackup(skb, dev); - case BOND_MODE_8023AD: case BOND_MODE_XOR: -+ return bond_xmit_xor(skb, dev); /* QCA NSS ECM bonding support */ -+ case BOND_MODE_8023AD: ++ return bond_xmit_xor(skb, dev); /* QCA NSS ECM bonding support */ ++ case BOND_MODE_8023AD: return bond_3ad_xor_xmit(skb, dev); case BOND_MODE_BROADCAST: return bond_xmit_broadcast(skb, dev); @@ -629,16 +633,24 @@ - --- a/include/net/bonding.h +++ b/include/net/bonding.h -@@ -85,6 +85,8 @@ - #define bond_for_each_slave(bond, pos, iter) \ - netdev_for_each_lower_private((bond)->dev, pos, iter) +@@ -94,6 +94,8 @@ + + #define BOND_TLS_FEATURES (NETIF_F_HW_TLS_TX | NETIF_F_HW_TLS_RX) +extern struct bond_cb __rcu *bond_cb; /* QCA NSS ECM bonding support */ + - /* Caller must have rcu_read_lock */ - #define bond_for_each_slave_rcu(bond, pos, iter) \ - netdev_for_each_lower_private_rcu((bond)->dev, pos, iter) -@@ -690,6 +692,12 @@ struct bond_vlan_tag *bond_verify_device + #ifdef CONFIG_NET_POLL_CONTROLLER + extern atomic_t netpoll_block_tx; + +@@ -659,6 +661,7 @@ struct bond_net { + + int bond_rcv_validate(const struct sk_buff *skb, struct bonding *bond, struct slave *slave); + netdev_tx_t bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); ++int bond_get_id(struct net_device *bond_dev); /* QCA NSS ECM bonding support */ + int bond_create(struct net *net, const char *name); + int bond_create_sysfs(struct bond_net *net); + void bond_destroy_sysfs(struct bond_net *net); +@@ -689,6 +692,13 @@ struct bond_vlan_tag *bond_verify_device int level); int bond_update_slave_arr(struct bonding *bond, struct slave *skipslave); void bond_slave_arr_work_rearm(struct bonding *bond, unsigned long delay); @@ -648,10 +660,11 @@ + struct net_device *bond_dev, + __be16 *layer4hdr); +/* QCA NSS ECM bonding support - End */ ++ void bond_work_init_all(struct bonding *bond); #ifdef CONFIG_PROC_FS -@@ -794,4 +802,18 @@ static inline netdev_tx_t bond_tx_drop(s +@@ -793,4 +803,18 @@ static inline netdev_tx_t bond_tx_drop(s return NET_XMIT_DROP; } diff --git a/target/linux/qualcommax/patches-6.1/0600-5-qca-nss-ecm-support-netfilter-DSCPREMARK.patch b/target/linux/qualcommax/patches-6.1/0600-5-qca-nss-ecm-support-netfilter-DSCPREMARK.patch new file mode 100644 index 00000000000000..f9480406c6f6bf --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0600-5-qca-nss-ecm-support-netfilter-DSCPREMARK.patch @@ -0,0 +1,154 @@ +--- a/net/netfilter/Kconfig ++++ b/net/netfilter/Kconfig +@@ -175,6 +175,13 @@ config NF_CONNTRACK_TIMEOUT + + If unsure, say `N'. + ++config NF_CONNTRACK_DSCPREMARK_EXT ++ bool 'Connection tracking extension for dscp remark target' ++ depends on NETFILTER_ADVANCED ++ help ++ This option enables support for connection tracking extension ++ for dscp remark. ++ + config NF_CONNTRACK_TIMESTAMP + bool 'Connection tracking timestamping' + depends on NETFILTER_ADVANCED +--- a/include/net/netfilter/nf_conntrack_extend.h ++++ b/include/net/netfilter/nf_conntrack_extend.h +@@ -31,6 +31,10 @@ enum nf_ct_ext_id { + #if IS_ENABLED(CONFIG_NET_ACT_CT) + NF_CT_EXT_ACT_CT, + #endif ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ NF_CT_EXT_DSCPREMARK, /* QCA NSS ECM support */ ++#endif ++ + NF_CT_EXT_NUM, + }; + +--- a/net/netfilter/nf_conntrack_extend.c ++++ b/net/netfilter/nf_conntrack_extend.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + + #define NF_CT_EXT_PREALLOC 128u /* conntrack events are on by default */ +@@ -54,6 +55,9 @@ static const u8 nf_ct_ext_type_len[NF_CT + #if IS_ENABLED(CONFIG_NET_ACT_CT) + [NF_CT_EXT_ACT_CT] = sizeof(struct nf_conn_act_ct_ext), + #endif ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ [NF_CT_EXT_DSCPREMARK] = sizeof(struct nf_ct_dscpremark_ext), ++#endif + }; + + static __always_inline unsigned int total_extension_size(void) +@@ -86,6 +90,9 @@ static __always_inline unsigned int tota + #if IS_ENABLED(CONFIG_NET_ACT_CT) + + sizeof(struct nf_conn_act_ct_ext) + #endif ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ + sizeof(struct nf_ct_dscpremark_ext) ++#endif + ; + } + +--- a/net/netfilter/Makefile ++++ b/net/netfilter/Makefile +@@ -14,6 +14,7 @@ nf_conntrack-$(CONFIG_NF_CONNTRACK_LABEL + nf_conntrack-$(CONFIG_NF_CT_PROTO_DCCP) += nf_conntrack_proto_dccp.o + nf_conntrack-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o + nf_conntrack-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o ++nf_conntrack-$(CONFIG_NF_CONNTRACK_DSCPREMARK_EXT) += nf_conntrack_dscpremark_ext.o + ifeq ($(CONFIG_NF_CONNTRACK),m) + nf_conntrack-$(CONFIG_DEBUG_INFO_BTF_MODULES) += nf_conntrack_bpf.o + else ifeq ($(CONFIG_NF_CONNTRACK),y) +--- a/net/netfilter/nf_conntrack_core.c ++++ b/net/netfilter/nf_conntrack_core.c +@@ -45,6 +45,9 @@ + #include + #include + #include ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++#include ++#endif + #include + #include + #include +@@ -1781,6 +1784,9 @@ init_conntrack(struct net *net, struct n + nf_ct_acct_ext_add(ct, GFP_ATOMIC); + nf_ct_tstamp_ext_add(ct, GFP_ATOMIC); + nf_ct_labels_ext_add(ct); ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ nf_ct_dscpremark_ext_add(ct, GFP_ATOMIC); ++#endif + + #ifdef CONFIG_NF_CONNTRACK_EVENTS + ecache = tmpl ? nf_ct_ecache_find(tmpl) : NULL; +--- a/net/netfilter/xt_DSCP.c ++++ b/net/netfilter/xt_DSCP.c +@@ -15,6 +15,9 @@ + + #include + #include ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++#include ++#endif + + MODULE_AUTHOR("Harald Welte "); + MODULE_DESCRIPTION("Xtables: DSCP/TOS field modification"); +@@ -31,6 +34,10 @@ dscp_tg(struct sk_buff *skb, const struc + { + const struct xt_DSCP_info *dinfo = par->targinfo; + u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT; ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ struct nf_conn *ct; ++ enum ip_conntrack_info ctinfo; ++#endif + + if (dscp != dinfo->dscp) { + if (skb_ensure_writable(skb, sizeof(struct iphdr))) +@@ -39,6 +46,13 @@ dscp_tg(struct sk_buff *skb, const struc + ipv4_change_dsfield(ip_hdr(skb), XT_DSCP_ECN_MASK, + dinfo->dscp << XT_DSCP_SHIFT); + ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ ct = nf_ct_get(skb, &ctinfo); ++ if (!ct) ++ return XT_CONTINUE; ++ ++ nf_conntrack_dscpremark_ext_set_dscp_rule_valid(ct); ++#endif + } + return XT_CONTINUE; + } +@@ -48,13 +62,24 @@ dscp_tg6(struct sk_buff *skb, const stru + { + const struct xt_DSCP_info *dinfo = par->targinfo; + u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT; +- ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ struct nf_conn *ct; ++ enum ip_conntrack_info ctinfo; ++#endif + if (dscp != dinfo->dscp) { + if (skb_ensure_writable(skb, sizeof(struct ipv6hdr))) + return NF_DROP; + + ipv6_change_dsfield(ipv6_hdr(skb), XT_DSCP_ECN_MASK, + dinfo->dscp << XT_DSCP_SHIFT); ++ ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ ct = nf_ct_get(skb, &ctinfo); ++ if (!ct) ++ return XT_CONTINUE; ++ ++ nf_conntrack_dscpremark_ext_set_dscp_rule_valid(ct); ++#endif + } + return XT_CONTINUE; + } diff --git a/target/linux/qualcommax/patches-6.1/0613-netfilter_optional_tcp_window_check.patc.patch b/target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-netfilter-tcp_window_check.patch similarity index 80% rename from target/linux/qualcommax/patches-6.1/0613-netfilter_optional_tcp_window_check.patc.patch rename to target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-netfilter-tcp_window_check.patch index a130ec999f0dc7..150853573d0116 100644 --- a/target/linux/qualcommax/patches-6.1/0613-netfilter_optional_tcp_window_check.patc.patch +++ b/target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-netfilter-tcp_window_check.patch @@ -17,6 +17,8 @@ Signed-off-by: Ram Chandra Jangir net/netfilter/nf_conntrack_standalone.c | 10 ++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) +diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h +index 1f463b3957c7..2af4f8d24282 100644 --- a/include/net/netns/conntrack.h +++ b/include/net/netns/conntrack.h @@ -26,6 +26,7 @@ struct nf_tcp_net { @@ -27,9 +29,11 @@ Signed-off-by: Ram Chandra Jangir u8 tcp_max_retrans; u8 tcp_ignore_invalid_rst; #if IS_ENABLED(CONFIG_NF_FLOW_TABLE) +diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c +index 3ac1af6f59fc..0a2badd52b54 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c -@@ -515,11 +515,15 @@ tcp_in_window(struct nf_conn *ct, enum i +@@ -513,11 +513,15 @@ tcp_in_window(struct nf_conn *ct, enum ip_conntrack_dir dir, struct ip_ct_tcp *state = &ct->proto.tcp; struct ip_ct_tcp_state *sender = &state->seen[dir]; struct ip_ct_tcp_state *receiver = &state->seen[!dir]; @@ -45,7 +49,7 @@ Signed-off-by: Ram Chandra Jangir /* * Get the required data from the packet. */ -@@ -1294,7 +1298,7 @@ int nf_conntrack_tcp_packet(struct nf_co +@@ -1257,7 +1261,7 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct, IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED && timeouts[new_state] > timeouts[TCP_CONNTRACK_UNACK]) timeout = timeouts[TCP_CONNTRACK_UNACK]; @@ -54,7 +58,7 @@ Signed-off-by: Ram Chandra Jangir timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS]) timeout = timeouts[TCP_CONNTRACK_RETRANS]; else -@@ -1610,6 +1614,9 @@ void nf_conntrack_tcp_init_net(struct ne +@@ -1573,6 +1577,9 @@ void nf_conntrack_tcp_init_net(struct net *net) */ tn->tcp_be_liberal = 0; @@ -64,6 +68,8 @@ Signed-off-by: Ram Chandra Jangir /* If it's non-zero, we turn off RST sequence number check */ tn->tcp_ignore_invalid_rst = 0; +diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c +index e9654169b005..84b8e28f0782 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -637,6 +637,7 @@ enum nf_ct_sysctl_index { @@ -74,7 +80,7 @@ Signed-off-by: Ram Chandra Jangir NF_SYSCTL_CT_PROTO_TCP_IGNORE_INVALID_RST, NF_SYSCTL_CT_PROTO_TCP_MAX_RETRANS, NF_SYSCTL_CT_PROTO_TIMEOUT_UDP, -@@ -844,6 +845,14 @@ static struct ctl_table nf_ct_sysctl_tab +@@ -844,6 +845,14 @@ static struct ctl_table nf_ct_sysctl_table[] = { .extra1 = SYSCTL_ZERO, .extra2 = SYSCTL_ONE, }, @@ -89,7 +95,7 @@ Signed-off-by: Ram Chandra Jangir [NF_SYSCTL_CT_PROTO_TCP_IGNORE_INVALID_RST] = { .procname = "nf_conntrack_tcp_ignore_invalid_rst", .maxlen = sizeof(u8), -@@ -1054,6 +1063,7 @@ static void nf_conntrack_standalone_init +@@ -1054,6 +1063,7 @@ static void nf_conntrack_standalone_init_tcp_sysctl(struct net *net, XASSIGN(LOOSE, &tn->tcp_loose); XASSIGN(LIBERAL, &tn->tcp_be_liberal); @@ -97,3 +103,6 @@ Signed-off-by: Ram Chandra Jangir XASSIGN(MAX_RETRANS, &tn->tcp_max_retrans); XASSIGN(IGNORE_INVALID_RST, &tn->tcp_ignore_invalid_rst); #undef XASSIGN +-- +2.17.1 + diff --git a/target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch b/target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch deleted file mode 100644 index 110b22606fd517..00000000000000 --- a/target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch +++ /dev/null @@ -1,69 +0,0 @@ ---- a/net/netfilter/Kconfig -+++ b/net/netfilter/Kconfig -@@ -171,6 +171,13 @@ config NF_CONNTRACK_TIMEOUT - - If unsure, say `N'. - -+config NF_CONNTRACK_DSCPREMARK_EXT -+ bool 'Connection tracking extension for dscp remark target' -+ depends on NETFILTER_ADVANCED -+ help -+ This option enables support for connection tracking extension -+ for dscp remark. -+ - config NF_CONNTRACK_TIMESTAMP - bool 'Connection tracking timestamping' - depends on NETFILTER_ADVANCED ---- a/include/net/netfilter/nf_conntrack_extend.h -+++ b/include/net/netfilter/nf_conntrack_extend.h -@@ -31,6 +31,10 @@ enum nf_ct_ext_id { - #if IS_ENABLED(CONFIG_NET_ACT_CT) - NF_CT_EXT_ACT_CT, - #endif -+#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT -+ NF_CT_EXT_DSCPREMARK, /* QCA NSS ECM support */ -+#endif -+ - NF_CT_EXT_NUM, - }; - ---- a/net/netfilter/nf_conntrack_extend.c -+++ b/net/netfilter/nf_conntrack_extend.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - #include - - #define NF_CT_EXT_PREALLOC 128u /* conntrack events are on by default */ -@@ -54,6 +55,9 @@ static const u8 nf_ct_ext_type_len[NF_CT - #if IS_ENABLED(CONFIG_NET_ACT_CT) - [NF_CT_EXT_ACT_CT] = sizeof(struct nf_conn_act_ct_ext), - #endif -+#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT -+ [NF_CT_EXT_DSCPREMARK] = sizeof(struct nf_ct_dscpremark_ext), -+#endif - }; - - static __always_inline unsigned int total_extension_size(void) -@@ -86,6 +90,9 @@ static __always_inline unsigned int tota - #if IS_ENABLED(CONFIG_NET_ACT_CT) - + sizeof(struct nf_conn_act_ct_ext) - #endif -+#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT -+ + sizeof(struct nf_ct_dscpremark_ext) -+#endif - ; - } - ---- a/net/netfilter/Makefile -+++ b/net/netfilter/Makefile -@@ -14,6 +14,7 @@ nf_conntrack-$(CONFIG_NF_CONNTRACK_LABEL - nf_conntrack-$(CONFIG_NF_CT_PROTO_DCCP) += nf_conntrack_proto_dccp.o - nf_conntrack-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o - nf_conntrack-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o -+nf_conntrack-$(CONFIG_NF_CONNTRACK_DSCPREMARK_EXT) += nf_conntrack_dscpremark_ext.o - ifeq ($(CONFIG_NF_CONNTRACK),m) - nf_conntrack-$(CONFIG_DEBUG_INFO_BTF_MODULES) += nf_conntrack_bpf.o - else ifeq ($(CONFIG_NF_CONNTRACK),y) diff --git a/target/linux/qualcommax/patches-6.1/0600-7-qca-nss-ecm-fix-IPv6-user-route-change-event-calls.patch b/target/linux/qualcommax/patches-6.1/0600-7-qca-nss-ecm-fix-IPv6-user-route-change-event-calls.patch new file mode 100644 index 00000000000000..4fd75771c5a6ac --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0600-7-qca-nss-ecm-fix-IPv6-user-route-change-event-calls.patch @@ -0,0 +1,89 @@ +From ce18a6fdff6a39a01111d74f513d2ef66142047c Mon Sep 17 00:00:00 2001 +From: Murat Sezgin +Date: Wed, 5 Aug 2020 13:21:27 -0700 +Subject: [PATCH 246/281] net:ipv6: Fix IPv6 user route change event calls + +These events should be called only when the route table is +changed by the userspace. So, we should call them in the +ioctl and the netlink message handler function. + +Change-Id: If7ec615014cfc79d5fa72878e49eaf99c2560c32 +Signed-off-by: Murat Sezgin +--- + net/ipv6/route.c | 31 +++++++++++++++++++++---------- + 1 file changed, 21 insertions(+), 10 deletions(-) + +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index df82117..4fb8247 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -3868,10 +3868,6 @@ int ip6_route_add(struct fib6_config *cfg, gfp_t gfp_flags, + return PTR_ERR(rt); + + err = __ip6_ins_rt(rt, &cfg->fc_nlinfo, extack); +- if (!err) +- atomic_notifier_call_chain(&ip6route_chain, +- RTM_NEWROUTE, rt); +- + fib6_info_release(rt); + + return err; +@@ -3893,9 +3889,6 @@ static int __ip6_del_rt(struct fib6_info *rt, struct nl_info *info) + err = fib6_del(rt, info); + spin_unlock_bh(&table->tb6_lock); + +- if (!err) +- atomic_notifier_call_chain(&ip6route_chain, +- RTM_DELROUTE, rt); + out: + fib6_info_release(rt); + return err; +@@ -4501,6 +4494,10 @@ int ipv6_route_ioctl(struct net *net, unsigned int cmd, struct in6_rtmsg *rtmsg) + break; + } + rtnl_unlock(); ++ if (!err) ++ atomic_notifier_call_chain(&ip6route_chain, ++ (cmd == SIOCADDRT) ? RTM_NEWROUTE : RTM_DELROUTE, &cfg); ++ + return err; + } + +@@ -5528,11 +5525,17 @@ static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, + } + + if (cfg.fc_mp) +- return ip6_route_multipath_del(&cfg, extack); ++ err = ip6_route_multipath_del(&cfg, extack); + else { + cfg.fc_delete_all_nh = 1; +- return ip6_route_del(&cfg, extack); ++ err = ip6_route_del(&cfg, extack); + } ++ ++ if (!err) ++ atomic_notifier_call_chain(&ip6route_chain, ++ RTM_DELROUTE, &cfg); ++ ++ return err; + } + + static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, +@@ -5549,9 +5552,15 @@ static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, + cfg.fc_metric = IP6_RT_PRIO_USER; + + if (cfg.fc_mp) +- return ip6_route_multipath_add(&cfg, extack); ++ err = ip6_route_multipath_add(&cfg, extack); + else +- return ip6_route_add(&cfg, GFP_KERNEL, extack); ++ err = ip6_route_add(&cfg, GFP_KERNEL, extack); ++ ++ if (!err) ++ atomic_notifier_call_chain(&ip6route_chain, ++ RTM_NEWROUTE, &cfg); ++ ++ return err; + } + + /* add the overhead of this fib6_nh to nexthop_len */ diff --git a/target/linux/qualcommax/patches-6.1/0601-qca-add-nss-bridge-mgr-support.patch b/target/linux/qualcommax/patches-6.1/0601-1-qca-add-nss-bridge-mgr-support.patch similarity index 82% rename from target/linux/qualcommax/patches-6.1/0601-qca-add-nss-bridge-mgr-support.patch rename to target/linux/qualcommax/patches-6.1/0601-1-qca-add-nss-bridge-mgr-support.patch index fbc76edef3cbf0..86e2f4fa562a29 100644 --- a/target/linux/qualcommax/patches-6.1/0601-qca-add-nss-bridge-mgr-support.patch +++ b/target/linux/qualcommax/patches-6.1/0601-1-qca-add-nss-bridge-mgr-support.patch @@ -21,23 +21,7 @@ Subject: [PATCH] Update 607-qca-add-add-nss-bridge-mgr-support.patch for kernel #endif --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c -@@ -62,6 +62,15 @@ void br_fdb_update_unregister_notify(str - EXPORT_SYMBOL_GPL(br_fdb_update_unregister_notify); - /* QCA NSS ECM support - End */ - -+/* QCA NSS bridge-mgr support - Start */ -+struct net_device *br_fdb_bridge_dev_get_and_hold(struct net_bridge *br) -+{ -+ dev_hold(br->dev); -+ return br->dev; -+} -+EXPORT_SYMBOL_GPL(br_fdb_bridge_dev_get_and_hold); -+/* QCA NSS bridge-mgr support - End */ -+ - int __init br_fdb_init(void) - { - br_fdb_cache = kmem_cache_create("bridge_fdb_cache", -@@ -568,7 +577,7 @@ void br_fdb_cleanup(struct work_struct * +@@ -569,7 +569,7 @@ void br_fdb_cleanup(struct work_struct * unsigned long delay = hold_time(br); unsigned long work_delay = delay; unsigned long now = jiffies; @@ -46,7 +30,7 @@ Subject: [PATCH] Update 607-qca-add-add-nss-bridge-mgr-support.patch for kernel /* this part is tricky, in order to avoid blocking learning and * consequently forwarding, we rely on rcu to delete objects with -@@ -596,12 +605,13 @@ void br_fdb_cleanup(struct work_struct * +@@ -597,12 +597,13 @@ void br_fdb_cleanup(struct work_struct * } else { spin_lock_bh(&br->hash_lock); if (!hlist_unhashed(&f->fdb_node)) { @@ -62,7 +46,21 @@ Subject: [PATCH] Update 607-qca-add-add-nss-bridge-mgr-support.patch for kernel /* QCA NSS ECM support - End */ } spin_unlock_bh(&br->hash_lock); -@@ -903,6 +913,7 @@ void br_fdb_update(struct net_bridge *br +@@ -900,10 +901,21 @@ static bool __fdb_mark_active(struct net + test_and_clear_bit(BR_FDB_NOTIFY_INACTIVE, &fdb->flags)); + } + ++/* QCA NSS bridge-mgr support - Start */ ++/* Get the bridge device */ ++struct net_device *br_fdb_bridge_dev_get_and_hold(struct net_bridge *br) ++{ ++ dev_hold(br->dev); ++ return br->dev; ++} ++EXPORT_SYMBOL_GPL(br_fdb_bridge_dev_get_and_hold); ++/* QCA NSS bridge-mgr support - End */ ++ + void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, const unsigned char *addr, u16 vid, unsigned long flags) { struct net_bridge_fdb_entry *fdb; @@ -70,20 +68,20 @@ Subject: [PATCH] Update 607-qca-add-add-nss-bridge-mgr-support.patch for kernel /* some users want to always flood. */ if (hold_time(br) == 0) -@@ -928,6 +939,12 @@ void br_fdb_update(struct net_bridge *br +@@ -929,6 +941,12 @@ void br_fdb_update(struct net_bridge *br if (unlikely(source != READ_ONCE(fdb->dst) && !test_bit(BR_FDB_STICKY, &fdb->flags))) { br_switchdev_fdb_notify(br, fdb, RTM_DELNEIGH); + /* QCA NSS bridge-mgr support - Start */ + ether_addr_copy(fdb_event.addr, addr); + fdb_event.br = br; -+ fdb_event.orig_dev = READ_ONCE(fdb->dst->dev); ++ fdb_event.orig_dev = fdb->dst->dev; + fdb_event.dev = source->dev; + /* QCA NSS bridge-mgr support - End */ WRITE_ONCE(fdb->dst, source); fdb_modified = true; /* Take over HW learned entry */ -@@ -939,7 +956,7 @@ void br_fdb_update(struct net_bridge *br +@@ -940,7 +958,7 @@ void br_fdb_update(struct net_bridge *br /* QCA NSS ECM support - Start */ atomic_notifier_call_chain( &br_fdb_update_notifier_list, diff --git a/target/linux/qualcommax/patches-6.1/0602-qca-nss-drv-add-qdisc-support.patch b/target/linux/qualcommax/patches-6.1/0602-1-qca-nss-drv-add-qdisc-support.patch similarity index 100% rename from target/linux/qualcommax/patches-6.1/0602-qca-nss-drv-add-qdisc-support.patch rename to target/linux/qualcommax/patches-6.1/0602-1-qca-nss-drv-add-qdisc-support.patch diff --git a/target/linux/qualcommax/patches-6.1/0603-1-qca-nss-clients-add-qdisc-support.patch b/target/linux/qualcommax/patches-6.1/0603-1-qca-nss-clients-add-qdisc-support.patch index 78a22e59fd1959..671516cfcdde9e 100644 --- a/target/linux/qualcommax/patches-6.1/0603-1-qca-nss-clients-add-qdisc-support.patch +++ b/target/linux/qualcommax/patches-6.1/0603-1-qca-nss-clients-add-qdisc-support.patch @@ -52,7 +52,7 @@ dev->needs_free_netdev = true; --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h -@@ -4612,6 +4612,15 @@ void dev_uc_flush(struct net_device *dev +@@ -4588,6 +4588,15 @@ void dev_uc_flush(struct net_device *dev void dev_uc_init(struct net_device *dev); /** @@ -68,7 +68,7 @@ * __dev_uc_sync - Synchonize device's unicast list * @dev: device to sync * @sync: function to call if address should be added -@@ -5157,6 +5166,11 @@ static inline bool netif_is_failover_sla +@@ -5133,6 +5142,11 @@ static inline bool netif_is_failover_sla return dev->priv_flags & IFF_FAILOVER_SLAVE; } diff --git a/target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-add-iptunnel-support.patch b/target/linux/qualcommax/patches-6.1/0603-2-qca-nss-clients-add-iptunnel-support.patch similarity index 98% rename from target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-add-iptunnel-support.patch rename to target/linux/qualcommax/patches-6.1/0603-2-qca-nss-clients-add-iptunnel-support.patch index 6b48489367faa9..928510087da42a 100644 --- a/target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-add-iptunnel-support.patch +++ b/target/linux/qualcommax/patches-6.1/0603-2-qca-nss-clients-add-iptunnel-support.patch @@ -22,7 +22,7 @@ #endif /* __NET_IP_TUNNELS_H */ --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c -@@ -2413,6 +2413,26 @@ nla_put_failure: +@@ -2398,6 +2398,26 @@ nla_put_failure: return -EMSGSIZE; } diff --git a/target/linux/qualcommax/patches-6.1/0603-5-qca-nss-clients-add-vxlan-support.patch b/target/linux/qualcommax/patches-6.1/0603-3-qca-nss-clients-add-vxlan-support.patch similarity index 87% rename from target/linux/qualcommax/patches-6.1/0603-5-qca-nss-clients-add-vxlan-support.patch rename to target/linux/qualcommax/patches-6.1/0603-3-qca-nss-clients-add-vxlan-support.patch index 68674783dc1519..4704b7d24895e9 100644 --- a/target/linux/qualcommax/patches-6.1/0603-5-qca-nss-clients-add-vxlan-support.patch +++ b/target/linux/qualcommax/patches-6.1/0603-3-qca-nss-clients-add-vxlan-support.patch @@ -29,19 +29,17 @@ int err = -ENOBUFS; skb = nlmsg_new(vxlan_nlmsg_size(), GFP_ATOMIC); -@@ -322,7 +337,11 @@ static void __vxlan_fdb_notify(struct vx +@@ -322,6 +337,10 @@ static void __vxlan_fdb_notify(struct vx } rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); -- return; + vfe.dev = vxlan->dev; + vfe.rdst = rd; + ether_addr_copy(vfe.eth_addr, fdb->eth_addr); + atomic_notifier_call_chain(&vxlan_fdb_notifier_list, type, (void *)&vfe); -+ return; + return; errout: if (err < 0) - rtnl_set_sk_err(net, RTNLGRP_NEIGH, err); @@ -488,6 +507,18 @@ static struct vxlan_fdb *vxlan_find_mac( return f; } @@ -65,24 +63,22 @@ goto out_unlock; } -+ /* Reset the skb_iif to Tunnels interface index */ ++ /* Reset the skb_iif to Tunnels interface index */ + skb->skb_iif = dev->ifindex; + tos = ip_tunnel_ecn_encap(tos, old_iph, skb); ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr), -@@ -2729,7 +2763,10 @@ static void vxlan_xmit_one(struct sk_buf +@@ -2729,6 +2763,9 @@ static void vxlan_xmit_one(struct sk_buf if (err < 0) goto tx_error; -- udp_tunnel6_xmit_skb(ndst, sock6->sock->sk, skb, dev, + /* Reset the skb_iif to Tunnels interface index */ + skb->skb_iif = dev->ifindex; + -+ udp_tunnel6_xmit_skb(ndst, sock6->sock->sk, skb, dev, + udp_tunnel6_xmit_skb(ndst, sock6->sock->sk, skb, dev, &local_ip.sin6.sin6_addr, &dst->sin6.sin6_addr, tos, ttl, - label, src_port, dst_port, !udp_sum); --- a/include/net/vxlan.h +++ b/include/net/vxlan.h @@ -344,6 +344,19 @@ struct vxlan_dev { diff --git a/target/linux/qualcommax/patches-6.1/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch b/target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-iptunnel-lock-this-cpu.patch similarity index 95% rename from target/linux/qualcommax/patches-6.1/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch rename to target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-iptunnel-lock-this-cpu.patch index 17c0fe3c971daf..faba23d8630d8c 100644 --- a/target/linux/qualcommax/patches-6.1/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch +++ b/target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-iptunnel-lock-this-cpu.patch @@ -1,6 +1,6 @@ --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c -@@ -2419,7 +2419,7 @@ nla_put_failure: +@@ -2404,7 +2404,7 @@ nla_put_failure: */ void ip6_update_offload_stats(struct net_device *dev, void *ptr) { diff --git a/target/linux/qualcommax/patches-6.1/0604-qca-add-mcs-support.patch b/target/linux/qualcommax/patches-6.1/0604-1-qca-add-mcs-support.patch similarity index 83% rename from target/linux/qualcommax/patches-6.1/0604-qca-add-mcs-support.patch rename to target/linux/qualcommax/patches-6.1/0604-1-qca-add-mcs-support.patch index 835ca83e91deb0..7035383acd67c1 100644 --- a/target/linux/qualcommax/patches-6.1/0604-qca-add-mcs-support.patch +++ b/target/linux/qualcommax/patches-6.1/0604-1-qca-add-mcs-support.patch @@ -1,6 +1,6 @@ --- a/include/linux/if_bridge.h +++ b/include/linux/if_bridge.h -@@ -256,4 +256,17 @@ extern br_get_dst_hook_t __rcu *br_get_d +@@ -281,4 +281,17 @@ extern br_get_dst_hook_t __rcu *br_get_d extern struct net_device *br_fdb_bridge_dev_get_and_hold(struct net_bridge *br); /* QCA NSS bridge-mgr support - End */ @@ -20,17 +20,16 @@ #endif --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c -@@ -256,7 +256,8 @@ static void fdb_notify(struct net_bridge +@@ -232,6 +232,8 @@ static void fdb_notify(struct net_bridge kfree_skb(skb); goto errout; } -- rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); -+ __br_notify(RTNLGRP_NEIGH, type, fdb); /* QCA qca-mcs support */ -+ rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); ++ ++ __br_notify(RTNLGRP_NEIGH, type, fdb); /* QCA qca-mcs support */ + rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); return; errout: - rtnl_set_sk_err(net, RTNLGRP_NEIGH, err); -@@ -322,6 +323,7 @@ struct net_bridge_fdb_entry *br_fdb_find +@@ -298,6 +300,7 @@ struct net_bridge_fdb_entry *br_fdb_find { return fdb_find_rcu(&br->fdb_hash_tbl, addr, vid); } @@ -48,7 +47,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb); rx_handler_func_t *br_get_rx_handler(const struct net_device *dev); -@@ -2177,4 +2178,14 @@ struct nd_msg *br_is_nd_neigh_msg(struct +@@ -2178,4 +2179,14 @@ struct nd_msg *br_is_nd_neigh_msg(struct #define __br_get(__hook, __default, __args ...) \ (__hook ? (__hook(__args)) : (__default)) /* QCA NSS ECM support - End */ @@ -75,7 +74,7 @@ errout: --- a/net/bridge/br.c +++ b/net/bridge/br.c -@@ -463,6 +463,12 @@ static void __exit br_deinit(void) +@@ -467,6 +467,12 @@ static void __exit br_deinit(void) br_fdb_fini(); } @@ -90,12 +89,13 @@ MODULE_LICENSE("GPL"); --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c -@@ -82,6 +82,12 @@ netdev_tx_t br_dev_xmit(struct sk_buff * +@@ -82,6 +82,13 @@ netdev_tx_t br_dev_xmit(struct sk_buff * if (is_broadcast_ether_addr(dest)) { br_flood(br, skb, BR_PKT_BROADCAST, false, true); } else if (is_multicast_ether_addr(dest)) { + /* QCA qca-mcs support - Start */ -+ br_multicast_handle_hook_t *multicast_handle_hook = rcu_dereference(br_multicast_handle_hook); ++ br_multicast_handle_hook_t *multicast_handle_hook = ++ rcu_dereference(br_multicast_handle_hook); + if (!__br_get(multicast_handle_hook, true, NULL, skb)) + goto out; + /* QCA qca-mcs support - End */ @@ -105,10 +105,11 @@ goto out; --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c -@@ -23,6 +23,16 @@ - #include "br_private.h" - #include "br_private_tunnel.h" +@@ -30,7 +30,17 @@ br_netif_receive_skb(struct net *net, st + return netif_receive_skb(skb); + } +-static int br_pass_frame_up(struct sk_buff *skb) +/* QCA qca-mcs support - Start */ +/* Hook for external Multicast handler */ +br_multicast_handle_hook_t __rcu *br_multicast_handle_hook __read_mostly; @@ -119,14 +120,6 @@ +EXPORT_SYMBOL_GPL(br_get_dst_hook); +/* QCA qca-mcs support - End */ + - static int - br_netif_receive_skb(struct net *net, struct sock *sk, struct sk_buff *skb) - { -@@ -30,7 +40,7 @@ br_netif_receive_skb(struct net *net, st - return netif_receive_skb(skb); - } - --static int br_pass_frame_up(struct sk_buff *skb) +int br_pass_frame_up(struct sk_buff *skb) { struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev; @@ -139,19 +132,19 @@ /* note: already called with rcu_read_lock */ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb) -@@ -84,6 +95,11 @@ int br_handle_frame_finish(struct net *n +@@ -82,6 +93,11 @@ int br_handle_frame_finish(struct net *n + struct net_bridge_mcast *brmctx; + struct net_bridge_vlan *vlan; struct net_bridge *br; - u16 vid = 0; - u8 state; + /* QCA qca-mcs support - Start */ + br_multicast_handle_hook_t *multicast_handle_hook; + struct net_bridge_port *pdst = NULL; + br_get_dst_hook_t *get_dst_hook = rcu_dereference(br_get_dst_hook); + /* QCA qca-mcs support - End */ + u16 vid = 0; + u8 state; - if (!p) - goto drop; -@@ -158,6 +174,11 @@ int br_handle_frame_finish(struct net *n +@@ -158,6 +174,12 @@ int br_handle_frame_finish(struct net *n switch (pkt_type) { case BR_PKT_MULTICAST: @@ -160,10 +153,11 @@ + if (!__br_get(multicast_handle_hook, true, p, skb)) + goto out; + /* QCA qca-mcs support - End */ ++ mdst = br_mdb_get(brmctx, skb, vid); if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) && br_multicast_querier_exists(brmctx, eth_hdr(skb), mdst)) { -@@ -173,8 +194,15 @@ int br_handle_frame_finish(struct net *n +@@ -173,8 +195,15 @@ int br_handle_frame_finish(struct net *n } break; case BR_PKT_UNICAST: @@ -181,16 +175,17 @@ default: break; } -@@ -189,6 +217,12 @@ int br_handle_frame_finish(struct net *n +@@ -189,6 +218,13 @@ int br_handle_frame_finish(struct net *n dst->used = now; br_forward(dst->dst, skb, local_rcv, false); } else { -+ /* QCA qca-mcs support - Start */ ++ /* QCA qca-mcs support - Start */ + if (pdst) { + br_forward(pdst, skb, local_rcv, false); + goto out; + } + /* QCA qca-mcs support - End */ ++ if (!mcast_hit) br_flood(br, skb, pkt_type, local_rcv, false); else @@ -293,23 +288,27 @@ #endif --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c -@@ -113,6 +113,15 @@ static void igmpmsg_netlink_event(const - static void mroute_clean_tables(struct mr_table *mrt, int flags); - static void ipmr_expire_process(struct timer_list *t); +@@ -89,6 +89,9 @@ static struct net_device *vif_dev_read(c + /* Special spinlock for queue of unresolved entries */ + static DEFINE_SPINLOCK(mfc_unres_lock); -+/* QCA ECM qca-mcs support - Start */ +/* spinlock for offload */ -+static DEFINE_SPINLOCK(lock); ++static DEFINE_SPINLOCK(lock); /* QCA ECM qca-mcs support */ + + /* We return to original Alan's scheme. Hash table of resolved + * entries is changed only in process context and protected + * with weak lock mrt_lock. Queue of unresolved entries is protected +@@ -112,6 +115,9 @@ static void mroute_netlink_event(struct + static void igmpmsg_netlink_event(const struct mr_table *mrt, struct sk_buff *pkt); + static void mroute_clean_tables(struct mr_table *mrt, int flags); + static void ipmr_expire_process(struct timer_list *t); +static struct mfc_cache *ipmr_cache_find(struct mr_table *mrt, __be32 origin, + __be32 mcastgrp); -+static ipmr_mfc_event_offload_callback_t __rcu ipmr_mfc_event_offload_callback; -+/* QCA ECM qca-mcs support - End */ -+ ++static ipmr_mfc_event_offload_callback_t __rcu ipmr_mfc_event_offload_callback; /* QCA ECM qca-mcs support */ + #ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES #define ipmr_for_each_table(mrt, net) \ - list_for_each_entry_rcu(mrt, &net->ipv4.mr_tables, list, \ -@@ -223,6 +232,228 @@ static int ipmr_rule_fill(struct fib_rul +@@ -223,6 +229,80 @@ static int ipmr_rule_fill(struct fib_rul return 0; } @@ -385,7 +384,16 @@ + offload_update_cb_f(group, origin, 0, NULL, IPMR_MFC_EVENT_DELETE); + rcu_read_unlock(); +} ++/* QCA ECM qca-mcs support - End */ + + static const struct fib_rules_ops __net_initconst ipmr_rules_ops_template = { + .family = RTNL_FAMILY_IPMR, + .rule_size = sizeof(struct ipmr_rule), +@@ -236,6 +316,156 @@ static const struct fib_rules_ops __net_ + .owner = THIS_MODULE, + }; + ++/* QCA ECM qca-mcs support - Start */ +/* ipmr_register_mfc_event_offload_callback() + * Register the IPv4 Multicast update offload callback with IPMR + */ @@ -535,84 +543,59 @@ +EXPORT_SYMBOL(ipmr_mfc_stats_update); +/* QCA ECM qca-mcs support - End */ + - static const struct fib_rules_ops __net_initconst ipmr_rules_ops_template = { - .family = RTNL_FAMILY_IPMR, - .rule_size = sizeof(struct ipmr_rule), -@@ -1192,6 +1423,11 @@ static int ipmr_mfc_delete(struct mr_tab + static int __net_init ipmr_rules_init(struct net *net) + { + struct fib_rules_ops *ops; +@@ -1191,6 +1421,10 @@ static int ipmr_mfc_delete(struct mr_tab + call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, c, mrt->id); mroute_netlink_event(mrt, c, RTM_DELROUTE); mr_cache_put(&c->_c); - + /* QCA ECM qca-mcs support - Start */ + /* Inform offload modules of the delete event */ + ipmr_sync_entry_delete(c->mfc_origin, c->mfc_mcastgrp); + /* QCA ECM qca-mcs support - End */ -+ + return 0; } - -@@ -1221,6 +1457,12 @@ static int ipmr_mfc_add(struct net *net, +@@ -1221,6 +1455,10 @@ static int ipmr_mfc_add(struct net *net, call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_REPLACE, c, mrt->id); mroute_netlink_event(mrt, c, RTM_NEWROUTE); -+ + /* QCA ECM qca-mcs support - Start */ + /* Inform offload modules of the update event */ + ipmr_sync_entry_update(mrt, c); + /* QCA ECM qca-mcs support - End */ -+ return 0; } -@@ -1281,6 +1523,7 @@ static void mroute_clean_tables(struct m - struct net *net = read_pnet(&mrt->net); - struct mr_mfc *c, *tmp; - struct mfc_cache *cache; -+ u32 origin, group; /* QCA ECM qca-mcs support */ - LIST_HEAD(list); - int i; - -@@ -1305,10 +1548,19 @@ static void mroute_clean_tables(struct m - rhltable_remove(&mrt->mfc_hash, &c->mnode, ipmr_rht_params); - list_del_rcu(&c->list); - cache = (struct mfc_cache *)c; -+ /* QCA ECM qca-mcs support - Start */ -+ origin = cache->mfc_origin; -+ group = cache->mfc_mcastgrp; -+ /* QCA ECM qca-mcs support - End */ - call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, cache, - mrt->id); - mroute_netlink_event(mrt, cache, RTM_DELROUTE); - mr_cache_put(c); -+ -+ /* QCA ECM qca-mcs support - Start */ -+ /* Inform offload modules of the delete event */ -+ ipmr_sync_entry_delete(origin, group); -+ /* QCA ECM qca-mcs support - End */ - } - } - --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c -@@ -102,6 +102,17 @@ static int ip6mr_rtm_dumproute(struct sk - static void mroute_clean_tables(struct mr_table *mrt, int flags); - static void ipmr_expire_process(struct timer_list *t); +@@ -74,6 +74,9 @@ static struct net_device *vif_dev_read(c + /* Special spinlock for queue of unresolved entries */ + static DEFINE_SPINLOCK(mfc_unres_lock); -+/* QCA qca-mcs support - Start */ +/* Spinlock for offload */ -+static DEFINE_SPINLOCK(lock); ++static DEFINE_SPINLOCK(lock); /* QCA qca-mcs support */ + + /* We return to original Alan's scheme. Hash table of resolved + entries is changed only in process context and protected + with weak lock mrt_lock. Queue of unresolved entries is protected +@@ -101,6 +104,13 @@ static int ip6mr_rtm_dumproute(struct sk + struct netlink_callback *cb); + static void mroute_clean_tables(struct mr_table *mrt, int flags); + static void ipmr_expire_process(struct timer_list *t); ++/* QCA qca-mcs support - Start */ +static struct mfc6_cache *ip6mr_cache_find(struct mr_table *mrt, + const struct in6_addr *origin, + const struct in6_addr *mcastgrp); +static ip6mr_mfc_event_offload_callback_t __rcu + ip6mr_mfc_event_offload_callback; +/* QCA qca-mcs support - End */ -+ + #ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES #define ip6mr_for_each_table(mrt, net) \ - list_for_each_entry_rcu(mrt, &net->ipv6.mr6_tables, list, \ -@@ -380,6 +391,227 @@ static struct mr_table_ops ip6mr_mr_tabl - .cmparg_any = &ip6mr_mr_table_ops_cmparg_any, +@@ -375,6 +385,84 @@ static struct mfc6_cache_cmp_arg ip6mr_m + .mf6c_mcastgrp = IN6ADDR_ANY_INIT, }; +/* QCA qca-mcs support - Start */ @@ -691,7 +674,16 @@ + IP6MR_MFC_EVENT_DELETE); + rcu_read_unlock(); +} ++/* QCA qca-mcs support - End */ + + static struct mr_table_ops ip6mr_mr_table_ops = { + .rht_params = &ip6mr_rht_params, + .cmparg_any = &ip6mr_mr_table_ops_cmparg_any, +@@ -697,6 +785,151 @@ static int call_ip6mr_mfc_entry_notifier + &mfc->_c, tb_id, &net->ipv6.ipmr_seq); + } + ++/* QCA qca-mcs support - Start */ +/* ip6mr_register_mfc_event_offload_callback() + * Register the IPv6 multicast update callback for offload modules + */ @@ -836,10 +828,10 @@ +EXPORT_SYMBOL(ip6mr_mfc_stats_update); +/* QCA qca-mcs support - End */ + - static struct mr_table *ip6mr_new_table(struct net *net, u32 id) - { - struct mr_table *mrt; -@@ -1221,6 +1453,7 @@ static int ip6mr_mfc_delete(struct mr_ta + /* Delete a VIF entry */ + static int mif6_delete(struct mr_table *mrt, int vifi, int notify, + struct list_head *head) +@@ -1221,6 +1454,7 @@ static int ip6mr_mfc_delete(struct mr_ta int parent) { struct mfc6_cache *c; @@ -847,7 +839,7 @@ /* The entries are added/deleted only under RTNL */ rcu_read_lock(); -@@ -1229,6 +1462,12 @@ static int ip6mr_mfc_delete(struct mr_ta +@@ -1229,6 +1463,11 @@ static int ip6mr_mfc_delete(struct mr_ta rcu_read_unlock(); if (!c) return -ENOENT; @@ -856,15 +848,13 @@ + memcpy(&mc_origin, &c->mf6c_origin, sizeof(struct in6_addr)); + memcpy(&mc_group, &c->mf6c_mcastgrp, sizeof(struct in6_addr)); + /* QCA qca-mcs support - End */ -+ rhltable_remove(&mrt->mfc_hash, &c->_c.mnode, ip6mr_rht_params); list_del_rcu(&c->_c.list); -@@ -1236,6 +1475,12 @@ static int ip6mr_mfc_delete(struct mr_ta +@@ -1236,6 +1475,11 @@ static int ip6mr_mfc_delete(struct mr_ta FIB_EVENT_ENTRY_DEL, c, mrt->id); mr6_netlink_event(mrt, c, RTM_DELROUTE); mr_cache_put(&c->_c); -+ + /* QCA qca-mcs support - Start */ + /* Inform offload modules of the delete event */ + ip6mr_sync_entry_delete(&mc_origin, &mc_group); @@ -873,53 +863,14 @@ return 0; } -@@ -1457,6 +1702,12 @@ static int ip6mr_mfc_add(struct net *net +@@ -1457,6 +1701,10 @@ static int ip6mr_mfc_add(struct net *net call_ip6mr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_REPLACE, c, mrt->id); mr6_netlink_event(mrt, c, RTM_NEWROUTE); -+ + /* QCA qca-mcs support - Start */ + /* Inform offload modules of the update event */ + ip6mr_sync_entry_update(mrt, c); + /* QCA qca-mcs support - End */ -+ return 0; } -@@ -1519,6 +1770,10 @@ static int ip6mr_mfc_add(struct net *net - - static void mroute_clean_tables(struct mr_table *mrt, int flags) - { -+ /* QCA qca-mcs support - Start */ -+ struct mfc6_cache *cache; -+ struct in6_addr mc_origin, mc_group; -+ /* QCA qca-mcs support - End */ - struct mr_mfc *c, *tmp; - LIST_HEAD(list); - int i; -@@ -1541,13 +1796,23 @@ static void mroute_clean_tables(struct m - if (((c->mfc_flags & MFC_STATIC) && !(flags & MRT6_FLUSH_MFC_STATIC)) || - (!(c->mfc_flags & MFC_STATIC) && !(flags & MRT6_FLUSH_MFC))) - continue; -+ /* QCA qca-mcs support - Start */ -+ cache = (struct mfc6_cache *)c; -+ memcpy(&mc_origin, &cache->mf6c_origin, sizeof(struct in6_addr)); -+ memcpy(&mc_group, &cache->mf6c_mcastgrp, sizeof(struct in6_addr)); -+ /* QCA qca-mcs support - End */ - rhltable_remove(&mrt->mfc_hash, &c->mnode, ip6mr_rht_params); - list_del_rcu(&c->list); - call_ip6mr_mfc_entry_notifiers(read_pnet(&mrt->net), - FIB_EVENT_ENTRY_DEL, -- (struct mfc6_cache *)c, mrt->id); -- mr6_netlink_event(mrt, (struct mfc6_cache *)c, RTM_DELROUTE); -+ cache, mrt->id); -+ mr6_netlink_event(mrt, cache, RTM_DELROUTE); - mr_cache_put(c); -+ -+ /* QCA qca-mcs support - Start */ -+ /* Inform offload modules of the delete event */ -+ ip6mr_sync_entry_delete(&mc_origin, &mc_group); -+ /* QCA qca-mcs support - End */ - } - } - diff --git a/target/linux/qualcommax/patches-6.1/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch b/target/linux/qualcommax/patches-6.1/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch deleted file mode 100644 index 4b9ee21f2f8545..00000000000000 --- a/target/linux/qualcommax/patches-6.1/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/net/netfilter/nf_conntrack_ecache.c -+++ b/net/netfilter/nf_conntrack_ecache.c -@@ -266,7 +266,6 @@ void nf_conntrack_register_notifier(stru - mutex_lock(&nf_ct_ecache_mutex); - notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb, - lockdep_is_held(&nf_ct_ecache_mutex)); -- WARN_ON_ONCE(notify); - rcu_assign_pointer(net->ct.nf_conntrack_event_cb, new); - mutex_unlock(&nf_ct_ecache_mutex); - } diff --git a/target/linux/qualcommax/patches-6.1/0611-ipv6-Fix-null-pointer-dereference-in-ipv6-output.patch b/target/linux/qualcommax/patches-6.1/0611-ipv6-Fix-null-pointer-dereference-in-ipv6-output.patch index 25f99fc4adef3c..608ab7f2b33675 100644 --- a/target/linux/qualcommax/patches-6.1/0611-ipv6-Fix-null-pointer-dereference-in-ipv6-output.patch +++ b/target/linux/qualcommax/patches-6.1/0611-ipv6-Fix-null-pointer-dereference-in-ipv6-output.patch @@ -68,7 +68,7 @@ Signed-off-by: Andrea Righi --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c -@@ -498,6 +498,9 @@ int ip6_forward(struct sk_buff *skb) +@@ -492,6 +492,9 @@ int ip6_forward(struct sk_buff *skb) u32 mtu; idev = __in6_dev_get_safely(dev_get_by_index_rcu(net, IP6CB(skb)->iif)); diff --git a/target/linux/qualcommax/patches-6.1/0614-netdevice-Add-IFF_EXT_HW_NO_OFFLOAD.patch b/target/linux/qualcommax/patches-6.1/0614-netdevice-Add-IFF_EXT_HW_NO_OFFLOAD.patch deleted file mode 100644 index d969adf3636033..00000000000000 --- a/target/linux/qualcommax/patches-6.1/0614-netdevice-Add-IFF_EXT_HW_NO_OFFLOAD.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -1749,6 +1749,8 @@ enum netdev_priv_flags_ext { - IFF_EXT_GRE_V4_TAP = 1<<4, - IFF_EXT_GRE_V6_TAP = 1<<5, - IFF_EXT_IFB = 1<<6, -+ IFF_EXT_MAPT = 1<<7, -+ IFF_EXT_HW_NO_OFFLOAD = 1<<8, - }; - - #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN From 1093c5c65f993fa91c4287188d38542f1816b809 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 24 Mar 2024 19:22:35 -0400 Subject: [PATCH 150/225] ath11k_nss: Fix compile for TRACE feature --- .../patches/nss/subsys/199-001-mac80211-add-nss-support.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/kernel/mac80211/patches/nss/subsys/199-001-mac80211-add-nss-support.patch b/package/kernel/mac80211/patches/nss/subsys/199-001-mac80211-add-nss-support.patch index 2943f6b04bad5c..fc8fec0660f352 100644 --- a/package/kernel/mac80211/patches/nss/subsys/199-001-mac80211-add-nss-support.patch +++ b/package/kernel/mac80211/patches/nss/subsys/199-001-mac80211-add-nss-support.patch @@ -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( From a2ac3da3285f1138698b4e46e33c5223044f2234 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 24 Mar 2024 20:23:06 -0400 Subject: [PATCH 151/225] treewide: fix up Makefile to comply with APK compatible schema This fixes makefile to comply with the recent commit 'e8725a932e16eaf6ec51add8c084d959cbe32ff2' Author: Paul Spooren AuthorDate: Sun Mar 17 18:43:10 2024 +0100 Commit: Paul Spooren CommitDate: Fri Mar 22 22:14:22 2024 +0100 treewide: use APK compatible version schema Different from OPKG, APK uses a deterministic version schema which chips the version into chunks and compares them individually. This enforces a certain schema which was previously entirely flexible. - Releases are added at the very and end prefixed with an `r` like `1.2.3-r3`. - Hashes are prefixed with a `~` like `1.2.3~abc123`. - Dates become semantic versions, like `2024.04.01` - Extra tags are possible like `_git`, `_alpha` and more. For full details see the APK test list: https://gitlab.alpinelinux.org/alpine/apk-tools/-/blob/master/test/version.data Signed-off-by: Paul Spooren --- package/firmware/ipq-wifi/Makefile | 2 +- package/kernel/nat46/Makefile | 2 +- package/kernel/qca-nss-dp/Makefile | 6 +++--- package/kernel/qca-ssdk/Makefile | 2 +- package/network/utils/fullconenat-nft/Makefile | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package/firmware/ipq-wifi/Makefile b/package/firmware/ipq-wifi/Makefile index ed4b26af3a20e4..a34e368a5db760 100644 --- a/package/firmware/ipq-wifi/Makefile +++ b/package/firmware/ipq-wifi/Makefile @@ -8,7 +8,7 @@ PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/firmware/qca-wireless.git PKG_SOURCE_DATE:=2024-03-04 PKG_SOURCE_VERSION:=38c02ae4302f9cb73f6914574239fe84799caa84 -PKG_MIRROR_HASH:=0f6a2dea8466ea0e8df3262bff643d60b1725f2218589c41d9f87fb37843c362 +PKG_MIRROR_HASH:=1e84f576d4161ea932b45a651abebdc05ff3c261ef25fc13d3d68cf9b624abb3 PKG_FLAGS:=nonshared diff --git a/package/kernel/nat46/Makefile b/package/kernel/nat46/Makefile index 98fb6f33865c29..91cb4d8327e340 100644 --- a/package/kernel/nat46/Makefile +++ b/package/kernel/nat46/Makefile @@ -7,7 +7,7 @@ PKG_MIRROR_HASH:=fc3ce43f8680bba6ada7d793479c5961e609138304198b250609b968d1833bb PKG_SOURCE_URL:=https://github.com/ayourtch/nat46.git PKG_SOURCE_DATE:=2022-09-19 PKG_SOURCE_PROTO:=git -PKG_SOURCE_VERSION:=1182f30785e4274913f01a8c3d7e1b5437ae3819 +PKG_SOURCE_VERSION:=4c5beee236841724219598fabb1edc93d4f08ce5 PKG_MAINTAINER:=Hans Dedecker PKG_LICENSE:=GPL-2.0 diff --git a/package/kernel/qca-nss-dp/Makefile b/package/kernel/qca-nss-dp/Makefile index f794d63b6deaf8..8acdc918aaac56 100644 --- a/package/kernel/qca-nss-dp/Makefile +++ b/package/kernel/qca-nss-dp/Makefile @@ -5,9 +5,9 @@ PKG_RELEASE:=3 PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-dp.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2023-10-16 -PKG_SOURCE_VERSION:=dfeb7d33ca22216a8172d5dd966e4c0db7715b69 -PKG_MIRROR_HASH:=6e0f2d85855acccc791ff041f3b049db4014d561df00bda2f5b102af50496591 +PKG_SOURCE_DATE:=2024-02-12 +PKG_SOURCE_VERSION:=bfdd78a8570dc14e1c91d312c5d775cecf49149c +PKG_MIRROR_HASH:=2a546657b6bdf810f7bf5bb94ac50fd1cfcb117fa17bb7aa84ce8119ed7d2be8 PKG_BUILD_PARALLEL:=1 PKG_FLAGS:=nonshared diff --git a/package/kernel/qca-ssdk/Makefile b/package/kernel/qca-ssdk/Makefile index 58daf929ee284e..33349d95819640 100644 --- a/package/kernel/qca-ssdk/Makefile +++ b/package/kernel/qca-ssdk/Makefile @@ -7,7 +7,7 @@ PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/qca-ssdk.git PKG_SOURCE_PROTO:=git PKG_SOURCE_DATE:=2023-10-04 PKG_SOURCE_VERSION:=23a5aa4a4d5834da7a07efb58baebfbee91786b0 -PKG_MIRROR_HASH:=9d169ce924a46a4e530031061d3183b92f23c7f46b3106f0b9ba3587846a73ee +PKG_MIRROR_HASH:=2310cdad1ebc424c534aa3a2c71e72e0ab3635295653a88d17dfc64c402cd151 PKG_FLAGS:=nonshared PKG_BUILD_PARALLEL:=1 diff --git a/package/network/utils/fullconenat-nft/Makefile b/package/network/utils/fullconenat-nft/Makefile index 76f36038d26a18..7f9276de8c100d 100644 --- a/package/network/utils/fullconenat-nft/Makefile +++ b/package/network/utils/fullconenat-nft/Makefile @@ -17,7 +17,7 @@ PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/fullcone-nat-nftables/nft-fullcone.git PKG_SOURCE_DATE:=2023-01-10 PKG_SOURCE_VERSION:=95ad79bc6d15c64b2770fe8b7092a64d5c2a293c -PKG_MIRROR_HASH:=56440d912625a26f1a6412c5399fccf89432d1cd35d2e6c9cc4d3a445e98b223 +PKG_MIRROR_HASH:=37ff8a27ce5e2e38820fba366de30c930d33cf20030e28086778aef62961d335 PKG_LICENSE:=GPL-2.0-only PKG_LICENSE_FILES:=LICENSE From 2c626a3b7357ca500fff93959d7a4419937509e0 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 24 Mar 2024 20:37:52 -0400 Subject: [PATCH 152/225] nat46: synchronize patches from QSDK 12.4.5.r5 --- .../kernel/nat46/patches/101-skb-reset.patch | 4 +- package/kernel/nat46/patches/102-mapt.patch | 38 +- package/kernel/nat46/patches/103-tos.patch | 25 +- package/kernel/nat46/patches/104-icmp.patch | 73 ++- .../patches/105-longest-prefix-match.patch | 69 +-- .../nat46/patches/106-dummy_header.patch | 62 +-- package/kernel/nat46/patches/107-stats.patch | 34 +- .../kernel/nat46/patches/108-ce_port.patch | 8 +- ...agment_if_not_df_and_larger_than_mtu.patch | 6 +- .../patches/110-icmp_error_not_handled.patch | 25 +- .../111-fix_null_point_reference.patch | 12 +- .../nat46/patches/112-fix_icmp_crash.patch | 4 +- .../patches/116-rate-limit-the-print.patch | 4 +- .../patches/117-fix-icmp-no-payload-bug.patch | 2 +- .../nat46/patches/118-performance_fix.patch | 415 ++++++++++++++++++ .../patches/120-sleeping_backtrace.patch | 57 +++ .../kernel/nat46/patches/121-tos-fix.patch | 27 ++ 17 files changed, 682 insertions(+), 183 deletions(-) create mode 100644 package/kernel/nat46/patches/118-performance_fix.patch create mode 100644 package/kernel/nat46/patches/120-sleeping_backtrace.patch create mode 100644 package/kernel/nat46/patches/121-tos-fix.patch diff --git a/package/kernel/nat46/patches/101-skb-reset.patch b/package/kernel/nat46/patches/101-skb-reset.patch index 928b048bb19da5..14cf2d75a07d88 100644 --- a/package/kernel/nat46/patches/101-skb-reset.patch +++ b/package/kernel/nat46/patches/101-skb-reset.patch @@ -12,7 +12,7 @@ Signed-off-by: Pavithra R --- a/nat46/modules/nat46-core.c +++ b/nat46/modules/nat46-core.c -@@ -1605,6 +1605,7 @@ void nat46_ipv6_input(struct sk_buff *ol +@@ -1710,6 +1710,7 @@ int nat46_ipv6_input(struct sk_buff *old #if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) nf_reset(new_skb); #else @@ -20,7 +20,7 @@ Signed-off-by: Pavithra R nf_reset_ct(new_skb); #endif -@@ -1814,6 +1815,7 @@ void nat46_ipv4_input(struct sk_buff *ol +@@ -1936,6 +1937,7 @@ int nat46_ipv4_input(struct sk_buff *old #if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) nf_reset(new_skb); #else diff --git a/package/kernel/nat46/patches/102-mapt.patch b/package/kernel/nat46/patches/102-mapt.patch index 979ea56da0c86d..1e83481c967f8b 100644 --- a/package/kernel/nat46/patches/102-mapt.patch +++ b/package/kernel/nat46/patches/102-mapt.patch @@ -13,7 +13,15 @@ Signed-off-by: Pavithra R --- a/nat46/modules/nat46-core.c +++ b/nat46/modules/nat46-core.c -@@ -1491,6 +1491,10 @@ int pairs_xlate_v6_to_v4_outer(nat46_ins +@@ -1497,7 +1497,6 @@ static uint16_t nat46_fixup_icmp_dest_un + return 0; + } + +- + /* Fixup ICMP->ICMP6 before IP header translation, according to http://tools.ietf.org/html/rfc6145 */ + + static uint16_t nat46_fixup_icmp(nat46_instance_t *nat46, struct iphdr *iph, struct sk_buff *old_skb) { +@@ -1579,6 +1578,10 @@ int pairs_xlate_v6_to_v4_outer(nat46_ins return ( (xlate_src >= 0) && (xlate_dst >= 0) ); } @@ -22,9 +30,9 @@ Signed-off-by: Pavithra R +} +EXPORT_SYMBOL(xlate_6_to_4); - void nat46_ipv6_input(struct sk_buff *old_skb) { + int nat46_ipv6_input(struct sk_buff *old_skb) { struct ipv6hdr *ip6h = ipv6_hdr(old_skb); -@@ -1628,6 +1632,10 @@ void nat46_ipv6_input(struct sk_buff *ol +@@ -1733,6 +1736,10 @@ int nat46_ipv6_input(struct sk_buff *old nat46debug(5, "about to send v4 packet, flags: %02x", IPCB(new_skb)->flags); nat46_netdev_count_xmit(new_skb, old_skb->dev); @@ -35,7 +43,7 @@ Signed-off-by: Pavithra R netif_rx(new_skb); /* TBD: should copy be released here? */ -@@ -1732,6 +1740,10 @@ int pairs_xlate_v4_to_v6_outer(nat46_ins +@@ -1841,6 +1848,10 @@ int pairs_xlate_v4_to_v6_outer(nat46_ins return 0; } @@ -44,11 +52,11 @@ Signed-off-by: Pavithra R +} +EXPORT_SYMBOL(xlate_4_to_6); - void nat46_ipv4_input(struct sk_buff *old_skb) { + int nat46_ipv4_input(struct sk_buff *old_skb) { nat46_instance_t *nat46 = get_nat46_instance(old_skb); -@@ -1859,10 +1871,32 @@ void nat46_ipv4_input(struct sk_buff *ol +@@ -1981,6 +1992,10 @@ int nat46_ipv4_input(struct sk_buff *old - nat46debug(5, "about to send v6 packet, flags: %02x", IPCB(new_skb)->flags); + nat46debug(5, "about to send v6 packet, flags: %02x", IP6CB(new_skb)->flags); nat46_netdev_count_xmit(new_skb, old_skb->dev); + + /* set skb->iif */ @@ -57,7 +65,8 @@ Signed-off-by: Pavithra R netif_rx(new_skb); done: - release_nat46_instance(nat46); +@@ -1988,4 +2003,22 @@ done: + return err; } +int nat46_get_npairs(struct net_device *dev) { @@ -109,7 +118,7 @@ Signed-off-by: Pavithra R nat46_xlate_rule_t remote; } nat46_xlate_rulepair_t; @@ -82,4 +82,9 @@ nat46_instance_t *get_nat46_instance(str - nat46_instance_t *alloc_nat46_instance(int npairs, nat46_instance_t *old, int from_ipair, int to_ipair); + nat46_instance_t *alloc_nat46_instance(int npairs, nat46_instance_t *old, int from_ipair, int to_ipair, int remove_ipair); void release_nat46_instance(nat46_instance_t *nat46); +int xlate_6_to_4(struct net_device *dev, struct ipv6hdr *ip6h, uint16_t proto, __u32 *pv4saddr, __u32 *pv4daddr); @@ -133,7 +142,7 @@ Signed-off-by: Pavithra R typedef struct { u32 sig; -@@ -79,6 +81,18 @@ void nat46_netdev_count_xmit(struct sk_b +@@ -83,6 +85,18 @@ void nat46_netdev_count_xmit(struct sk_b dev->stats.tx_bytes += skb->len; } @@ -152,7 +161,7 @@ Signed-off-by: Pavithra R void *netdev_nat46_instance(struct net_device *dev) { nat46_netdev_priv_t *priv = netdev_priv(dev); return priv->nat46; -@@ -155,6 +169,11 @@ int nat46_netdev_create(char *basename, +@@ -159,6 +173,11 @@ int nat46_netdev_create(char *basename, printk("nat46: netdevice nat46 '%s' created successfully.\n", devname); kfree(devname); @@ -164,11 +173,12 @@ Signed-off-by: Pavithra R return 0; err_register_dev: -@@ -169,9 +188,23 @@ void nat46_netdev_destroy(struct net_dev - { +@@ -175,10 +194,24 @@ void nat46_netdev_destroy(struct net_dev + netif_stop_queue(dev); netdev_nat46_set_instance(dev, NULL); unregister_netdev(dev); + radix_tree_delete(&netdev_tree, dev->ifindex); + free_netdev(dev); printk("nat46: Destroying nat46 device.\n"); } @@ -190,7 +200,7 @@ Signed-off-by: Pavithra R return (priv && (NAT46_DEVICE_SIGNATURE == priv->sig)); --- a/nat46/modules/nat46-netdev.h +++ b/nat46/modules/nat46-netdev.h -@@ -24,3 +24,6 @@ void nat64_show_all_configs(struct seq_f +@@ -26,3 +26,6 @@ void nat64_show_all_configs(struct seq_f void nat46_netdev_count_xmit(struct sk_buff *skb, struct net_device *dev); void *netdev_nat46_instance(struct net_device *dev); diff --git a/package/kernel/nat46/patches/103-tos.patch b/package/kernel/nat46/patches/103-tos.patch index 253da044a7ae81..60ffcb2fae802a 100644 --- a/package/kernel/nat46/patches/103-tos.patch +++ b/package/kernel/nat46/patches/103-tos.patch @@ -14,7 +14,7 @@ Signed-off-by: Pavithra R --- a/nat46/modules/nat46-core.c +++ b/nat46/modules/nat46-core.c -@@ -807,11 +807,12 @@ void *get_next_header_ptr6(void *pv6, in +@@ -886,11 +886,12 @@ void *get_next_header_ptr6(void *pv6, in } void fill_v4hdr_from_v6hdr(struct iphdr * iph, struct ipv6hdr *ip6h, __u32 v4saddr, __u32 v4daddr, __u16 id, __u16 frag_off, __u16 proto, int l3_payload_len) { @@ -28,29 +28,12 @@ Signed-off-by: Pavithra R iph->frag_off = frag_off; iph->id = id; iph->tot_len = htons( l3_payload_len + IPV4HDRSIZE ); -@@ -1750,7 +1751,7 @@ void nat46_ipv4_input(struct sk_buff *ol - struct sk_buff *new_skb; +@@ -1859,7 +1860,7 @@ int nat46_ipv4_input(struct sk_buff *old uint16_t sport = 0, dport = 0; + int err = 0; - int tclass = 0; -+ uint8_t tclass; ++ uint8_t tclass = 0; int flowlabel = 0; int check_for_l4 = 0; int having_l4 = 0; -@@ -1761,6 +1762,8 @@ void nat46_ipv4_input(struct sk_buff *ol - - char v6saddr[16], v6daddr[16]; - -+ tclass = hdr4->tos; -+ - memset(v6saddr, 1, 16); - memset(v6daddr, 2, 16); - -@@ -1843,7 +1846,6 @@ void nat46_ipv4_input(struct sk_buff *ol - memset(hdr6, 0, sizeof(*hdr6) + (add_frag_header?8:0)); - - /* build IPv6 header */ -- tclass = 0; /* traffic class */ - *(__be32 *)hdr6 = htonl(0x60000000 | (tclass << 20)) | flowlabel; /* version, priority, flowlabel */ - - /* IPv6 length is a payload length, IPv4 is hdr+payload */ diff --git a/package/kernel/nat46/patches/104-icmp.patch b/package/kernel/nat46/patches/104-icmp.patch index 3733fd0ab1941b..7907a66726005b 100644 --- a/package/kernel/nat46/patches/104-icmp.patch +++ b/package/kernel/nat46/patches/104-icmp.patch @@ -20,9 +20,9 @@ Signed-off-by: Pavithra R --- a/nat46/modules/nat46-core.c +++ b/nat46/modules/nat46-core.c -@@ -22,6 +22,9 @@ - #include "nat46-glue.h" +@@ -29,6 +29,9 @@ #include "nat46-core.h" + #include "nat46-module.h" +static uint16_t xlate_pkt_in_err_v4_to_v6(nat46_instance_t *nat46, struct iphdr *iph, + struct sk_buff *old_skb, uint16_t *sport, uint16_t *dport); @@ -30,7 +30,7 @@ Signed-off-by: Pavithra R void nat46debug_dump(nat46_instance_t *nat46, int level, void *addr, int len) { -@@ -806,6 +809,14 @@ void *get_next_header_ptr6(void *pv6, in +@@ -885,6 +888,14 @@ void *get_next_header_ptr6(void *pv6, in return ret; } @@ -45,54 +45,58 @@ Signed-off-by: Pavithra R void fill_v4hdr_from_v6hdr(struct iphdr * iph, struct ipv6hdr *ip6h, __u32 v4saddr, __u32 v4daddr, __u16 id, __u16 frag_off, __u16 proto, int l3_payload_len) { uint32_t ver_class_flow = ntohl(*(__be32 *)ip6h); iph->ttl = ip6h->hop_limit; -@@ -1128,34 +1139,34 @@ static void nat46_fixup_icmp6_paramprob( +@@ -1212,10 +1223,14 @@ static void nat46_fixup_icmp6_paramprob( 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -1 }; u32 *pptr6 = icmp6_parameter_ptr(icmp6h); u8 *pptr4 = icmp_parameter_ptr((struct icmphdr *)icmp6h); - int new_pptr = -1; -+ int8_t new_pptr = -1; ++ u8 new_pptr = -1; int len = ntohs(ip6h->payload_len)-sizeof(*icmp6h); switch(icmp6h->icmp6_code) { + case 1: + update_icmp6_type_code(nat46, icmp6h, 3, 2); + break; ++ case 0: if(*pptr6 < sizeof(ptr6_4)/sizeof(ptr6_4[0])) { new_pptr = ptr6_4[*pptr6]; - if (new_pptr >= 0) { - icmp6h->icmp6_cksum = csum16_upd(icmp6h->icmp6_cksum, (*pptr6 & 0xffff), (new_pptr << 8)); +@@ -1224,27 +1239,21 @@ static void nat46_fixup_icmp6_paramprob( *pptr4 = 0xff & new_pptr; + update_icmp6_type_code(nat46, icmp6h, 12, 0); + len = xlate_payload6_to4(nat46, (icmp6h + 1), get_next_header_ptr6((icmp6h + 1), len), len, &icmp6h->icmp6_cksum, ptailTruncSize); - } else { - ip6h->nexthdr = NEXTHDR_NONE; + update_icmp6_type_code(nat46, icmp6h, 12, 0); -+ break; ++ break; } - } else { - ip6h->nexthdr = NEXTHDR_NONE; } - break; - case 1: +- icmp6h->icmp6_cksum = csum16_upd(icmp6h->icmp6_cksum, ((*pptr6 >> 16) & 0xffff), 0); +- icmp6h->icmp6_cksum = csum16_upd(icmp6h->icmp6_cksum, (*pptr6 & 0xffff), 0); - *pptr6 = 0; - update_icmp6_type_code(nat46, icmp6h, 3, 2); - len = xlate_payload6_to4(nat46, (icmp6h + 1), get_next_header_ptr6((icmp6h + 1), len), len, &icmp6h->icmp6_cksum, ptailTruncSize); - break; +#if __has_attribute(__fallthrough__) -+ __attribute__((__fallthrough__)); ++ __attribute__((__fallthrough__)); +#endif case 2: /* fallthrough to default */ default: ip6h->nexthdr = NEXTHDR_NONE; + return; } --} - + len = xlate_payload6_to4(nat46, (icmp6h + 1), get_next_header_ptr6((icmp6h + 1), len), len, &icmp6h->icmp6_cksum, ptailTruncSize); -+} + } +- /* Fixup ICMP6->ICMP before IP header translation, according to http://tools.ietf.org/html/rfc6145 */ -@@ -1211,17 +1222,19 @@ int ip6_input_not_interested(nat46_insta + static void nat46_fixup_icmp6(nat46_instance_t *nat46, struct ipv6hdr *ip6h, struct icmp6hdr *icmp6h, struct sk_buff *old_skb, int *ptailTruncSize) { +@@ -1299,17 +1308,19 @@ int ip6_input_not_interested(nat46_insta return 0; } @@ -115,7 +119,7 @@ Signed-off-by: Pavithra R /* * Set the Type to 4, and adjust the * ICMP checksum both to take the type/code change into account -@@ -1264,27 +1277,33 @@ static uint16_t nat46_fixup_icmp_paramet +@@ -1352,27 +1363,33 @@ static uint16_t nat46_fixup_icmp_paramet */ static int ptr4_6[] = { 0, 1, 4, 4, -1, -1, -1, -1, 7, 6, -1, -1, 8, 8, 8, 8, 24, 24, 24, 24, -1 }; u8 *icmp_pptr = icmp_parameter_ptr(icmph); @@ -156,7 +160,7 @@ Signed-off-by: Pavithra R /* * Translate the Code as * described below, set the Type to 1, and adjust the ICMP -@@ -1347,16 +1366,21 @@ static uint16_t nat46_fixup_icmp_dest_un +@@ -1435,16 +1452,21 @@ static uint16_t nat46_fixup_icmp_dest_un u16 *pmtu = ((u16 *)icmph) + 3; /* IPv4-compatible MTU value is 16 bit */ @@ -180,7 +184,7 @@ Signed-off-by: Pavithra R case 3: icmph->code = 4; break; -@@ -1406,14 +1430,15 @@ static uint16_t nat46_fixup_icmp_dest_un +@@ -1494,13 +1516,15 @@ static uint16_t nat46_fixup_icmp_dest_un break; default: iph->protocol = NEXTHDR_NONE; @@ -190,16 +194,16 @@ Signed-off-by: Pavithra R + return xlate_pkt_in_err_v4_to_v6(nat46, iph, old_skb, sport, dport); } -- /* Fixup ICMP->ICMP6 before IP header translation, according to http://tools.ietf.org/html/rfc6145 */ - +- -static uint16_t nat46_fixup_icmp(nat46_instance_t *nat46, struct iphdr *iph, struct sk_buff *old_skb) { +static uint16_t nat46_fixup_icmp(nat46_instance_t *nat46, struct iphdr *iph, -+ struct sk_buff *old_skb, uint16_t *sport, uint16_t *dport) { ++ struct sk_buff *old_skb, uint16_t *sport, uint16_t *dport) ++{ struct icmphdr *icmph = (struct icmphdr *)(iph+1); uint16_t ret = 0; -@@ -1422,22 +1447,22 @@ static uint16_t nat46_fixup_icmp(nat46_i +@@ -1509,22 +1533,22 @@ static uint16_t nat46_fixup_icmp(nat46_i switch(icmph->type) { case ICMP_ECHO: icmph->type = ICMPV6_ECHO_REQUEST; @@ -227,7 +231,7 @@ Signed-off-by: Pavithra R break; default: /* Silently drop. */ -@@ -1457,11 +1482,13 @@ int pairs_xlate_v6_to_v4_outer(nat46_ins +@@ -1544,11 +1568,13 @@ int pairs_xlate_v6_to_v4_outer(nat46_ins if(-1 == xlate_dst) { if (xlate_v6_to_v4(nat46, &apair->local, &ip6h->daddr, pv4daddr)) { @@ -241,7 +245,7 @@ Signed-off-by: Pavithra R xlate_src = ipair; } } -@@ -1560,6 +1587,7 @@ void nat46_ipv6_input(struct sk_buff *ol +@@ -1659,6 +1685,7 @@ int nat46_ipv6_input(struct sk_buff *old } if(!pairs_xlate_v6_to_v4_outer(nat46, ip6h, proto, &v4saddr, &v4daddr)) { @@ -249,7 +253,7 @@ Signed-off-by: Pavithra R goto done; } -@@ -1713,11 +1741,13 @@ int pairs_xlate_v4_to_v6_outer(nat46_ins +@@ -1821,11 +1848,13 @@ int pairs_xlate_v4_to_v6_outer(nat46_ins if(-1 == xlate_src) { if(xlate_v4_to_v6(nat46, &apair->local, &hdr4->saddr, v6saddr, sport)) { @@ -263,7 +267,7 @@ Signed-off-by: Pavithra R xlate_dst = ipair; } } -@@ -1746,10 +1776,145 @@ int xlate_4_to_6(struct net_device *dev, +@@ -1854,10 +1883,145 @@ int xlate_4_to_6(struct net_device *dev, } EXPORT_SYMBOL(xlate_4_to_6); @@ -402,29 +406,24 @@ Signed-off-by: Pavithra R + return 1; +} + - void nat46_ipv4_input(struct sk_buff *old_skb) { + int nat46_ipv4_input(struct sk_buff *old_skb) { nat46_instance_t *nat46 = get_nat46_instance(old_skb); struct sk_buff *new_skb; - uint16_t sport = 0, dport = 0; + uint16_t sport = 0, dport = 0, ret = 0; - uint8_t tclass; - int flowlabel = 0; -@@ -1772,11 +1937,11 @@ void nat46_ipv4_input(struct sk_buff *ol + int err = 0; + uint8_t tclass = 0; +@@ -1879,7 +2043,7 @@ int nat46_ipv4_input(struct sk_buff *old } nat46debug(1, "nat46_ipv4_input packet"); nat46debug(5, "nat46_ipv4_input protocol: %d, len: %d, flags: %02x", hdr4->protocol, old_skb->len, IPCB(old_skb)->flags); - if(0 == (ntohs(hdr4->frag_off) & 0x3FFF) ) { -+ if(0 == (ntohs(hdr4->frag_off) & 0x3FFF) ) { /* Checking for MF */ ++ if (0 == (ntohs(hdr4->frag_off) & 0x3FFF)) { check_for_l4 = 1; - } else { - add_frag_header = 1; -- if (0 == (ntohs(hdr4->frag_off) & 0x1FFF)) { -+ if (0 == (ntohs(hdr4->frag_off) & 0x1FFF)) { /* Checking for Frag Offset */ - check_for_l4 = 1; - } - } -@@ -1798,9 +1963,10 @@ void nat46_ipv4_input(struct sk_buff *ol + } else if (IPPROTO_ICMP == hdr4->protocol) { + /* +@@ -1916,9 +2080,10 @@ int nat46_ipv4_input(struct sk_buff *old break; } case IPPROTO_ICMP: diff --git a/package/kernel/nat46/patches/105-longest-prefix-match.patch b/package/kernel/nat46/patches/105-longest-prefix-match.patch index beef42d646cab3..95fe6af973f45b 100644 --- a/package/kernel/nat46/patches/105-longest-prefix-match.patch +++ b/package/kernel/nat46/patches/105-longest-prefix-match.patch @@ -16,7 +16,7 @@ Signed-off-by: Pavithra R --- a/nat46/modules/nat46-core.c +++ b/nat46/modules/nat46-core.c -@@ -121,6 +121,13 @@ int try_parse_ipv6_prefix(struct in6_add +@@ -128,6 +128,13 @@ int try_parse_ipv6_prefix(struct in6_add *arg_plen++ = 0; if (pref_len) { *pref_len = simple_strtol(arg_plen, NULL, 10); @@ -30,7 +30,7 @@ Signed-off-by: Pavithra R } } err = (1 != in6_pton(arg, -1, (u8 *)pref, '\0', NULL)); -@@ -134,6 +141,13 @@ int try_parse_ipv4_prefix(u32 *v4addr, i +@@ -141,6 +148,13 @@ int try_parse_ipv4_prefix(u32 *v4addr, i *arg_plen++ = 0; if (pref_len) { *pref_len = simple_strtol(arg_plen, NULL, 10); @@ -44,7 +44,7 @@ Signed-off-by: Pavithra R } } err = (1 != in4_pton(arg, -1, (u8 *)v4addr, '/', NULL)); -@@ -176,11 +190,127 @@ int try_parse_rule_arg(nat46_xlate_rule_ +@@ -183,11 +197,127 @@ int try_parse_rule_arg(nat46_xlate_rule_ return err; } @@ -175,7 +175,7 @@ Signed-off-by: Pavithra R int nat46_set_ipair_config(nat46_instance_t *nat46, int ipair, char *buf, int count) { char *tail = buf; char *arg_name; -@@ -210,7 +340,18 @@ int nat46_set_ipair_config(nat46_instanc +@@ -217,7 +347,18 @@ int nat46_set_ipair_config(nat46_instanc err = try_parse_rule_arg(&apair->remote, arg_name, &tail); } } @@ -195,7 +195,7 @@ Signed-off-by: Pavithra R } int nat46_set_config(nat46_instance_t *nat46, char *buf, int count) { -@@ -854,37 +995,120 @@ int is_last_pair_in_group(nat46_xlate_ru +@@ -933,37 +1074,120 @@ int is_last_pair_in_group(nat46_xlate_ru return ( (apair->local.style != NAT46_XLATE_NONE) && (apair->remote.style != NAT46_XLATE_NONE) ); } @@ -339,7 +339,7 @@ Signed-off-by: Pavithra R } /* -@@ -1471,40 +1695,28 @@ static uint16_t nat46_fixup_icmp(nat46_i +@@ -1557,40 +1781,31 @@ static uint16_t nat46_fixup_icmp(nat46_i return ret; } @@ -351,25 +351,28 @@ Signed-off-by: Pavithra R int xlate_src = -1; int xlate_dst = -1; -- for(ipair = 0; ipair < nat46->npairs; ipair++) { + for(ipair = 0; ipair < nat46->npairs; ipair++) { - apair = &nat46->pairs[ipair]; -+ apair = nat46_lpm(nat46, NAT46_IPV6_REMOTE, &ip6h->saddr); -+ if (!apair) { -+ return 0; -+ } - +- - if(-1 == xlate_dst) { - if (xlate_v6_to_v4(nat46, &apair->local, &ip6h->daddr, pv4daddr)) { - nat46debug(5, "Dst addr %pI6 to %pI4 \n", &ip6h->daddr, pv4daddr); - xlate_dst = ipair; - } -- } ++ apair = nat46_lpm(nat46, NAT46_IPV6_REMOTE, &ip6h->saddr); ++ if (!apair) { ++ return 0; + } - if(-1 == xlate_src) { - if (xlate_v6_to_v4(nat46, &apair->remote, &ip6h->saddr, pv4saddr)) { - nat46debug(5, "Src addr %pI6 to %pI4 \n", &ip6h->saddr, pv4saddr); - xlate_src = ipair; - } -- } ++ ++ if (xlate_v6_to_v4(nat46, &apair->local, &ip6h->daddr, pv4daddr)) { ++ nat46debug(5, "Dst addr %pI6 to %pI4 \n", &ip6h->daddr, pv4daddr); ++ xlate_dst = ipair; + } - if( (xlate_src >= 0) && (xlate_dst >= 0) ) { - break; - } else { @@ -378,14 +381,11 @@ Signed-off-by: Pavithra R - xlate_src = -1; - xlate_dst = -1; - } -- } -+ if (xlate_v6_to_v4(nat46, &apair->local, &ip6h->daddr, pv4daddr)) { -+ nat46debug(5, "Dst addr %pI6 to %pI4 \n", &ip6h->daddr, pv4daddr); -+ xlate_dst = ipair; -+ } -+ if (xlate_v6_to_v4(nat46, &apair->remote, &ip6h->saddr, pv4saddr)) { -+ nat46debug(5, "Src addr %pI6 to %pI4 \n", &ip6h->saddr, pv4saddr); -+ xlate_src = ipair; ++ ++ if (xlate_v6_to_v4(nat46, &apair->remote, &ip6h->saddr, pv4saddr)) { ++ nat46debug(5, "Src addr %pI6 to %pI4 \n", &ip6h->saddr, pv4saddr); ++ xlate_src = ipair; + } } if (xlate_dst >= 0) { if (xlate_src < 0) { @@ -394,7 +394,7 @@ Signed-off-by: Pavithra R nat46debug(1, "[nat46] Could not translate remote address v6->v4, ipair %d, for ICMP6 use dest addr", ipair); *pv4saddr = *pv4daddr; xlate_src = xlate_dst; -@@ -1520,12 +1732,14 @@ int pairs_xlate_v6_to_v4_outer(nat46_ins +@@ -1606,12 +1821,14 @@ int pairs_xlate_v6_to_v4_outer(nat46_ins } int xlate_6_to_4(struct net_device *dev, struct ipv6hdr *ip6h, uint16_t proto, __u32 *pv4saddr, __u32 *pv4daddr) { @@ -404,13 +404,13 @@ Signed-off-by: Pavithra R } EXPORT_SYMBOL(xlate_6_to_4); - void nat46_ipv6_input(struct sk_buff *old_skb) { + int nat46_ipv6_input(struct sk_buff *old_skb) { struct ipv6hdr *ip6h = ipv6_hdr(old_skb); + nat46_xlate_rulepair_t apair; nat46_instance_t *nat46 = get_nat46_instance(old_skb); uint16_t proto; uint16_t frag_off; -@@ -1586,7 +1800,7 @@ void nat46_ipv6_input(struct sk_buff *ol +@@ -1684,7 +1901,7 @@ int nat46_ipv6_input(struct sk_buff *old check_for_l4 = 1; } @@ -419,7 +419,7 @@ Signed-off-by: Pavithra R nat46debug(0, "[nat46] Could not translate v6->v4"); goto done; } -@@ -1730,56 +1944,44 @@ int ip4_input_not_interested(nat46_insta +@@ -1837,56 +2054,44 @@ int ip4_input_not_interested(nat46_insta return 0; } @@ -499,7 +499,7 @@ Signed-off-by: Pavithra R */ int pairs_xlate_v4_to_v6_inner(nat46_instance_t *nat46, struct iphdr *iph, uint16_t sport, uint16_t dport, void *v6saddr, void *v6daddr) { -@@ -1788,35 +1990,27 @@ int pairs_xlate_v4_to_v6_inner(nat46_ins +@@ -1895,35 +2100,27 @@ int pairs_xlate_v4_to_v6_inner(nat46_ins int xlate_src = -1; int xlate_dst = -1; @@ -554,15 +554,15 @@ Signed-off-by: Pavithra R return 0; } -@@ -1913,6 +2107,7 @@ static uint16_t xlate_pkt_in_err_v4_to_v +@@ -2020,6 +2217,7 @@ static uint16_t xlate_pkt_in_err_v4_to_v - void nat46_ipv4_input(struct sk_buff *old_skb) { + int nat46_ipv4_input(struct sk_buff *old_skb) { nat46_instance_t *nat46 = get_nat46_instance(old_skb); + nat46_xlate_rulepair_t apair; struct sk_buff *new_skb; uint16_t sport = 0, dport = 0, ret = 0; -@@ -1979,7 +2174,7 @@ void nat46_ipv4_input(struct sk_buff *ol +@@ -2097,7 +2295,7 @@ int nat46_ipv4_input(struct sk_buff *old having_l4 = 1; } @@ -619,21 +619,22 @@ Signed-off-by: Pavithra R + nat46_xlate_rulepair_t sorted_ipv6_remote_pairs[NUM_RULE_PAIRS_MAX]; /* npairs */ } nat46_instance_t; - void nat46_ipv6_input(struct sk_buff *old_skb); + int nat46_ipv6_input(struct sk_buff *old_skb); --- a/nat46/modules/nat46-netdev.c +++ b/nat46/modules/nat46-netdev.c -@@ -263,7 +263,13 @@ int nat46_insert(char *devname, char *bu +@@ -270,7 +270,14 @@ int nat46_insert(char *devname, char *bu int ret = -1; if(dev) { nat46_instance_t *nat46 = netdev_nat46_instance(dev); -- nat46_instance_t *nat46_new = alloc_nat46_instance(nat46->npairs+1, nat46, 0, 1); +- nat46_instance_t *nat46_new = alloc_nat46_instance(nat46->npairs+1, nat46, 0, 1, -1); + nat46_instance_t *nat46_new; ++ + if(nat46->npairs == NUM_RULE_PAIRS_MAX) { + printk("Could not insert a new rule on device %s\n", devname); + return ret; + } + -+ nat46_new = alloc_nat46_instance(nat46->npairs+1, nat46, 0, 1); ++ nat46_new = alloc_nat46_instance(nat46->npairs+1, nat46, 0, 1, -1); if(nat46_new) { netdev_nat46_set_instance(dev, nat46_new); ret = nat46_set_ipair_config(nat46_new, 0, buf, strlen(buf)); diff --git a/package/kernel/nat46/patches/106-dummy_header.patch b/package/kernel/nat46/patches/106-dummy_header.patch index 66754fd6378d18..1d4351166fb963 100644 --- a/package/kernel/nat46/patches/106-dummy_header.patch +++ b/package/kernel/nat46/patches/106-dummy_header.patch @@ -14,31 +14,10 @@ Signed-off-by: Pavithra R --- a/nat46/modules/nat46-core.c +++ b/nat46/modules/nat46-core.c -@@ -21,6 +21,7 @@ +@@ -1996,6 +1996,27 @@ done: + - #include "nat46-glue.h" - #include "nat46-core.h" -+#include "nat46-module.h" - static uint16_t xlate_pkt_in_err_v4_to_v6(nat46_instance_t *nat46, struct iphdr *iph, - struct sk_buff *old_skb, uint16_t *sport, uint16_t *dport); -@@ -2134,6 +2135,11 @@ void nat46_ipv4_input(struct sk_buff *ol - nat46debug(5, "nat46_ipv4_input protocol: %d, len: %d, flags: %02x", hdr4->protocol, old_skb->len, IPCB(old_skb)->flags); - if(0 == (ntohs(hdr4->frag_off) & 0x3FFF) ) { /* Checking for MF */ - check_for_l4 = 1; -+ if (add_dummy_header) { -+ if (0 == (ntohs(hdr4->frag_off) & IP_DF)) { -+ add_frag_header = 1; -+ } -+ } - } else { - add_frag_header = 1; - if (0 == (ntohs(hdr4->frag_off) & 0x1FFF)) { /* Checking for Frag Offset */ -@@ -2263,3 +2269,24 @@ bool nat46_get_rule_config(struct net_de - return true; - } - EXPORT_SYMBOL(nat46_get_rule_config); -+ +/* + * Function to get MAP-T rules and flags. + */ @@ -59,6 +38,22 @@ Signed-off-by: Pavithra R + return true; +} +EXPORT_SYMBOL(nat46_get_info); ++ + void ip6_update_csum(struct sk_buff * skb, struct ipv6hdr * ip6hdr, int do_atomic_frag) + { + u32 sum1=0; +@@ -2254,6 +2275,11 @@ int nat46_ipv4_input(struct sk_buff *old + } + hdr4 = ip_hdr(old_skb); + check_for_l4 = 1; ++ if (add_dummy_header) { ++ if (0 == (ntohs(hdr4->frag_off) & IP_DF)) { ++ add_frag_header = 1; ++ } ++ } + } else { + add_frag_header = 1; + if (0 == (ntohs(hdr4->frag_off) & 0x1FFF)) { --- a/nat46/modules/nat46-core.h +++ b/nat46/modules/nat46-core.h @@ -32,6 +32,9 @@ @@ -81,20 +76,29 @@ Signed-off-by: Pavithra R #endif --- a/nat46/modules/nat46-module.c +++ b/nat46/modules/nat46-module.c -@@ -57,6 +57,9 @@ MODULE_DESCRIPTION("NAT46 stateless tran +@@ -56,12 +56,16 @@ MODULE_AUTHOR("Andrew Yourtchenko static int nat46_netdev_up(struct net_device *dev) { netif_start_queue(dev); -@@ -64,8 +89,13 @@ static int nat46_netdev_down(struct net_ - +@@ -65,9 +90,14 @@ static int nat46_netdev_down(struct net_ static netdev_tx_t nat46_netdev_xmit(struct sk_buff *skb, struct net_device *dev) { -- dev->stats.rx_packets++; -- dev->stats.rx_bytes += skb->len; + int ret = 0; + struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats); + + u64_stats_update_begin(&tstats->syncp); -+ tstats->rx_packets++; -+ tstats->rx_bytes += skb->len; ++ u64_stats_inc(&tstats->rx_packets); ++ u64_stats_add(&tstats->rx_bytes, skb->len); + u64_stats_update_end(&tstats->syncp); + put_cpu_ptr(tstats); + +- dev->stats.rx_packets++; +- dev->stats.rx_bytes += skb->len; if(ETH_P_IP == ntohs(skb->protocol)) { - nat46_ipv4_input(skb); + ret = nat46_ipv4_input(skb); } -@@ -77,22 +107,38 @@ static netdev_tx_t nat46_netdev_xmit(str +@@ -81,22 +111,39 @@ static netdev_tx_t nat46_netdev_xmit(str } void nat46_netdev_count_xmit(struct sk_buff *skb, struct net_device *dev) { @@ -88,8 +89,8 @@ Signed-off-by: Pavithra R + struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats); + + u64_stats_update_begin(&tstats->syncp); -+ tstats->tx_packets++; -+ tstats->tx_bytes += skb->len; ++ u64_stats_inc(&tstats->tx_packets); ++ u64_stats_add(&tstats->tx_bytes, skb->len); + u64_stats_update_end(&tstats->syncp); + put_cpu_ptr(tstats); } @@ -104,10 +105,10 @@ Signed-off-by: Pavithra R + struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats); + + u64_stats_update_begin(&tstats->syncp); -+ tstats->rx_packets += rx_packets; -+ tstats->rx_bytes += rx_bytes; -+ tstats->tx_packets += tx_packets; -+ tstats->tx_bytes += tx_bytes; ++ u64_stats_add(&tstats->rx_packets, rx_packets); ++ u64_stats_add(&tstats->rx_bytes, rx_bytes); ++ u64_stats_add(&tstats->tx_packets, tx_packets); ++ u64_stats_add(&tstats->tx_bytes, tx_bytes); dev->stats.rx_dropped += rx_dropped; dev->stats.tx_dropped += tx_dropped; + u64_stats_update_end(&tstats->syncp); @@ -118,13 +119,14 @@ Signed-off-by: Pavithra R +static void nat46_get_stats64(struct net_device *dev, + struct rtnl_link_stats64 *tot) +{ -+ dev_get_tstats64(dev, tot); ++ netdev_stats_to_stats64(tot, &dev->stats); ++ dev_fetch_sw_netstats(tot, dev->tstats); +} + void *netdev_nat46_instance(struct net_device *dev) { nat46_netdev_priv_t *priv = netdev_priv(dev); return priv->nat46; -@@ -116,6 +162,7 @@ static void nat46_netdev_setup(struct ne +@@ -120,6 +167,7 @@ static void nat46_netdev_setup(struct ne priv->nat46 = nat46; dev->netdev_ops = &nat46_netdev_ops; diff --git a/package/kernel/nat46/patches/108-ce_port.patch b/package/kernel/nat46/patches/108-ce_port.patch index 18d33089f4cd66..ab6ab37b986e07 100644 --- a/package/kernel/nat46/patches/108-ce_port.patch +++ b/package/kernel/nat46/patches/108-ce_port.patch @@ -14,7 +14,7 @@ Signed-off-by: Pavithra R --- a/nat46/modules/nat46-core.c +++ b/nat46/modules/nat46-core.c -@@ -25,6 +25,7 @@ +@@ -31,6 +31,7 @@ static uint16_t xlate_pkt_in_err_v4_to_v6(nat46_instance_t *nat46, struct iphdr *iph, struct sk_buff *old_skb, uint16_t *sport, uint16_t *dport); @@ -22,7 +22,7 @@ Signed-off-by: Pavithra R void nat46debug_dump(nat46_instance_t *nat46, int level, void *addr, int len) -@@ -2106,6 +2107,73 @@ static uint16_t xlate_pkt_in_err_v4_to_v +@@ -2236,6 +2237,73 @@ static uint16_t xlate_pkt_in_err_v4_to_v return 1; } @@ -93,10 +93,10 @@ Signed-off-by: Pavithra R + return value; +} + - void nat46_ipv4_input(struct sk_buff *old_skb) { + int nat46_ipv4_input(struct sk_buff *old_skb) { nat46_instance_t *nat46 = get_nat46_instance(old_skb); nat46_xlate_rulepair_t apair; -@@ -2226,9 +2294,34 @@ void nat46_ipv4_input(struct sk_buff *ol +@@ -2368,9 +2436,34 @@ int nat46_ipv4_input(struct sk_buff *old if (add_frag_header) { struct frag_hdr *fh = (struct frag_hdr*)(hdr6 + 1); diff --git a/package/kernel/nat46/patches/109-fragment_if_not_df_and_larger_than_mtu.patch b/package/kernel/nat46/patches/109-fragment_if_not_df_and_larger_than_mtu.patch index 3bb07f0396a9ad..333228a97496c3 100644 --- a/package/kernel/nat46/patches/109-fragment_if_not_df_and_larger_than_mtu.patch +++ b/package/kernel/nat46/patches/109-fragment_if_not_df_and_larger_than_mtu.patch @@ -14,9 +14,9 @@ Signed-off-by: Pavithra R --- a/nat46/modules/nat46-core.c +++ b/nat46/modules/nat46-core.c -@@ -2203,10 +2203,11 @@ void nat46_ipv4_input(struct sk_buff *ol - nat46debug(5, "nat46_ipv4_input protocol: %d, len: %d, flags: %02x", hdr4->protocol, old_skb->len, IPCB(old_skb)->flags); - if(0 == (ntohs(hdr4->frag_off) & 0x3FFF) ) { /* Checking for MF */ +@@ -2343,10 +2343,11 @@ int nat46_ipv4_input(struct sk_buff *old + } + hdr4 = ip_hdr(old_skb); check_for_l4 = 1; - if (add_dummy_header) { - if (0 == (ntohs(hdr4->frag_off) & IP_DF)) { diff --git a/package/kernel/nat46/patches/110-icmp_error_not_handled.patch b/package/kernel/nat46/patches/110-icmp_error_not_handled.patch index 7f0ead0773e5aa..5697c609732ccf 100644 --- a/package/kernel/nat46/patches/110-icmp_error_not_handled.patch +++ b/package/kernel/nat46/patches/110-icmp_error_not_handled.patch @@ -19,7 +19,7 @@ Signed-off-by: Pavithra R --- a/nat46/modules/nat46-core.c +++ b/nat46/modules/nat46-core.c -@@ -1697,17 +1697,19 @@ static uint16_t nat46_fixup_icmp(nat46_i +@@ -1782,11 +1782,12 @@ static uint16_t nat46_fixup_icmp(nat46_i return ret; } @@ -31,16 +31,17 @@ Signed-off-by: Pavithra R int xlate_dst = -1; + nat46_xlate_rulepair_t *apair; - apair = nat46_lpm(nat46, NAT46_IPV6_REMOTE, &ip6h->saddr); - if (!apair) { - return 0; - } + for(ipair = 0; ipair < nat46->npairs; ipair++) { + apair = nat46_lpm(nat46, NAT46_IPV6_REMOTE, &ip6h->saddr); +@@ -1794,6 +1795,7 @@ int pairs_xlate_v6_to_v4_outer(nat46_ins + return 0; + } -+ *papair = apair; - if (xlate_v6_to_v4(nat46, &apair->local, &ip6h->daddr, pv4daddr)) { - nat46debug(5, "Dst addr %pI6 to %pI4 \n", &ip6h->daddr, pv4daddr); - xlate_dst = ipair; -@@ -1734,14 +1736,14 @@ int pairs_xlate_v6_to_v4_outer(nat46_ins ++ *papair = apair; + if (xlate_v6_to_v4(nat46, &apair->local, &ip6h->daddr, pv4daddr)) { + nat46debug(5, "Dst addr %pI6 to %pI4 \n", &ip6h->daddr, pv4daddr); + xlate_dst = ipair; +@@ -1822,14 +1824,14 @@ int pairs_xlate_v6_to_v4_outer(nat46_ins } int xlate_6_to_4(struct net_device *dev, struct ipv6hdr *ip6h, uint16_t proto, __u32 *pv4saddr, __u32 *pv4daddr) { @@ -50,14 +51,14 @@ Signed-off-by: Pavithra R } EXPORT_SYMBOL(xlate_6_to_4); - void nat46_ipv6_input(struct sk_buff *old_skb) { + int nat46_ipv6_input(struct sk_buff *old_skb) { struct ipv6hdr *ip6h = ipv6_hdr(old_skb); - nat46_xlate_rulepair_t apair; + nat46_xlate_rulepair_t *apair; nat46_instance_t *nat46 = get_nat46_instance(old_skb); uint16_t proto; uint16_t frag_off; -@@ -1803,8 +1805,37 @@ void nat46_ipv6_input(struct sk_buff *ol +@@ -1903,8 +1905,37 @@ int nat46_ipv6_input(struct sk_buff *old } if (!pairs_xlate_v6_to_v4_outer(nat46, &apair, ip6h, proto, &v4saddr, &v4daddr)) { diff --git a/package/kernel/nat46/patches/111-fix_null_point_reference.patch b/package/kernel/nat46/patches/111-fix_null_point_reference.patch index 4386c41e9a8ed9..4cef9db199d639 100644 --- a/package/kernel/nat46/patches/111-fix_null_point_reference.patch +++ b/package/kernel/nat46/patches/111-fix_null_point_reference.patch @@ -14,27 +14,27 @@ Signed-off-by: Pavithra R --- a/nat46/modules/nat46-core.c +++ b/nat46/modules/nat46-core.c -@@ -1758,6 +1758,11 @@ void nat46_ipv6_input(struct sk_buff *ol +@@ -1847,6 +1847,11 @@ int nat46_ipv6_input(struct sk_buff *old int l3_infrag_payload_len = ntohs(ip6h->payload_len); int check_for_l4 = 0; + if (nat46 == NULL) { + printk("nat46:%p skb is dropped for no valid instance found\n", old_skb); -+ return; ++ return err; + } + nat46debug(4, "nat46_ipv6_input packet"); if(ip6_input_not_interested(nat46, ip6h, old_skb)) { -@@ -2222,6 +2227,11 @@ void nat46_ipv4_input(struct sk_buff *ol +@@ -2353,6 +2358,11 @@ int nat46_ipv4_input(struct sk_buff *old char v6saddr[16], v6daddr[16]; + if (nat46 == NULL) { + printk("nat46:%p skb is dropped for no valid instance found\n", old_skb); -+ return; ++ return err; + } + - tclass = hdr4->tos; - memset(v6saddr, 1, 16); + memset(v6daddr, 2, 16); + diff --git a/package/kernel/nat46/patches/112-fix_icmp_crash.patch b/package/kernel/nat46/patches/112-fix_icmp_crash.patch index 61eeae17e43e05..5d34697a45b84d 100644 --- a/package/kernel/nat46/patches/112-fix_icmp_crash.patch +++ b/package/kernel/nat46/patches/112-fix_icmp_crash.patch @@ -16,7 +16,7 @@ Signed-off-by: Pavithra R --- a/nat46/modules/nat46-core.c +++ b/nat46/modules/nat46-core.c -@@ -2115,7 +2115,9 @@ static uint16_t xlate_pkt_in_err_v4_to_v +@@ -2245,7 +2245,9 @@ static uint16_t xlate_pkt_in_err_v4_to_v if (skb_tailroom(old_skb) >= IPV6V4HDRDELTA){ skb_put(old_skb, IPV6V4HDRDELTA); @@ -27,7 +27,7 @@ Signed-off-by: Pavithra R memcpy(iiph, &ip6h, IPV6HDRSIZE); } else { -@@ -2128,7 +2130,9 @@ static uint16_t xlate_pkt_in_err_v4_to_v +@@ -2258,7 +2260,9 @@ static uint16_t xlate_pkt_in_err_v4_to_v skb_put(old_skb, IPV6V4HDRDELTA); iiph = (struct iphdr *)(icmp_hdr(old_skb) + 1); diff --git a/package/kernel/nat46/patches/116-rate-limit-the-print.patch b/package/kernel/nat46/patches/116-rate-limit-the-print.patch index 5719b8a601ca4d..d857d0e6cb0a05 100644 --- a/package/kernel/nat46/patches/116-rate-limit-the-print.patch +++ b/package/kernel/nat46/patches/116-rate-limit-the-print.patch @@ -10,7 +10,7 @@ Change-Id: I2119fbe54d630c3ed39535f1cb1b8a0d9d3199b4 Signed-off-by: Pavithra R --- a/nat46/modules/nat46-core.c +++ b/nat46/modules/nat46-core.c -@@ -1828,7 +1828,9 @@ void nat46_ipv6_input(struct sk_buff *ol +@@ -1928,7 +1928,9 @@ int nat46_ipv6_input(struct sk_buff *old memcpy(&hdr6.saddr, &ip6h_inner->daddr, 16); memcpy(&hdr6.daddr, &ip6h_inner->saddr, 16); if (!pairs_xlate_v6_to_v4_outer(nat46, &apair, &hdr6, proto, &v4saddr, &v4daddr)) { @@ -21,7 +21,7 @@ Signed-off-by: Pavithra R goto done; } v4saddr = apair->local.v4_pref; -@@ -2296,7 +2298,9 @@ void nat46_ipv4_input(struct sk_buff *ol +@@ -2436,7 +2438,9 @@ int nat46_ipv4_input(struct sk_buff *old } if(!pairs_xlate_v4_to_v6_outer(nat46, &apair, hdr4, having_l4 ? &sport : NULL, having_l4 ? &dport : NULL, v6saddr, v6daddr)) { diff --git a/package/kernel/nat46/patches/117-fix-icmp-no-payload-bug.patch b/package/kernel/nat46/patches/117-fix-icmp-no-payload-bug.patch index 289963c0fb9af8..a8bff4a945457c 100644 --- a/package/kernel/nat46/patches/117-fix-icmp-no-payload-bug.patch +++ b/package/kernel/nat46/patches/117-fix-icmp-no-payload-bug.patch @@ -21,7 +21,7 @@ Change-Id: Ifd9802afb50771de39b4c6fb734d36b0801613ec Signed-off-by: Pavithra R --- a/nat46/modules/nat46-core.c +++ b/nat46/modules/nat46-core.c -@@ -2137,9 +2137,8 @@ static uint16_t xlate_pkt_in_err_v4_to_v +@@ -2266,9 +2266,8 @@ static uint16_t xlate_pkt_in_err_v4_to_v memmove(((char *)iiph + IPV6HDRSIZE), (iiph + 1), ntohs(iph->tot_len) - 2 * IPV4HDRSIZE - sizeof(struct icmphdr)); memcpy(iiph, &ip6h, IPV6HDRSIZE); diff --git a/package/kernel/nat46/patches/118-performance_fix.patch b/package/kernel/nat46/patches/118-performance_fix.patch new file mode 100644 index 00000000000000..5de4906ef99f7f --- /dev/null +++ b/package/kernel/nat46/patches/118-performance_fix.patch @@ -0,0 +1,415 @@ +Author: Suruchi Agarwal +Date: Fri Dec 17 13:37:15 2021 -0800 + + nat46: Performance fix + + Avoid allocating new skb and copy for map-t translation + + Change-Id: I621b90609b4642d64b6e4cfb98b105b3fcbb0365 + Signed-off-by: Suruchi Agarwal + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -118,7 +118,7 @@ char *get_next_arg(char **ptail) { + return pc; + } + +-/* ++/* + * Parse an IPv6 address (if pref_len is NULL), or prefix (if it isn't). + * parses destructively (places \0 between address and prefix len) + */ +@@ -163,7 +163,7 @@ int try_parse_ipv4_prefix(u32 *v4addr, i + } + + +-/* ++/* + * parse a rule argument and put config into a rule. + * advance the tail to prepare for the next arg parsing. + * destructive. +@@ -384,7 +384,7 @@ char *xlate_style_to_string(nat46_xlate_ + return "unknown"; + } + +-/* ++/* + * Get the nat46 configuration into a supplied buffer (if non-null). + */ + int nat46_get_ipair_config(nat46_instance_t *nat46, int ipair, char *buf, int count) { +@@ -985,6 +985,28 @@ __sum16 csum_ipv6_unmagic(nat46_instance + return csum; + } + ++/* Update UDP with incremental checksum */ ++__sum16 csum_ipv6_udp_remagic(struct ipv6hdr *ip6hdr, u32 csum) { ++ uint32_t sum; ++ sum = csum_partial(ip6hdr->saddr.s6_addr16, 2 * sizeof(ip6hdr->saddr), ~csum); ++ sum = ((sum >> 16) & 0xffff) + (sum & 0xffff); ++ sum += ((sum >> 16) & 0xffff); ++ return (u16)(~sum); ++} ++ ++/* Undo the IPv4 pseudoheader inclusion into the checksum */ ++__sum16 csum_ipv4_unmagic(__be32 saddr, __be32 daddr, ++ u32 csum) { ++ u32 s; ++ uint32_t addr_csum; ++ csum = ntohs(~csum); ++ addr_csum = (saddr & 0xffff) + (saddr >> 16) + (daddr & 0xffff) + (daddr >> 16); ++ s= csum + ntohs(~addr_csum); ++ s = ((s >> 16) & 0xffff) + (s & 0xffff); ++ s += ((s >> 16) & 0xffff); ++ return htons((u16)(~s)); ++} ++ + /* Update ICMPv6 type/code with incremental checksum adjustment */ + void update_icmp6_type_code(nat46_instance_t *nat46, struct icmp6hdr *icmp6h, u8 type, u8 code) { + u16 old_tc = *((u16 *)icmp6h); +@@ -1038,9 +1060,8 @@ void fill_v6hdr_from_v4hdr(struct iphdr + ip6h->hop_limit = iph->ttl; + } + +-void fill_v4hdr_from_v6hdr(struct iphdr * iph, struct ipv6hdr *ip6h, __u32 v4saddr, __u32 v4daddr, __u16 id, __u16 frag_off, __u16 proto, int l3_payload_len) { +- uint32_t ver_class_flow = ntohl(*(__be32 *)ip6h); +- iph->ttl = ip6h->hop_limit; ++void fill_v4hdr_from_v6hdr(struct iphdr * iph, uint32_t ver_class_flow, uint8_t hop_limit, __u32 v4saddr, __u32 v4daddr, __u16 id, __u16 frag_off, __u16 proto, int l3_payload_len) { ++ iph->ttl = hop_limit; + iph->saddr = v4saddr; + iph->daddr = v4daddr; + iph->protocol = proto; +@@ -1198,6 +1219,8 @@ void pairs_xlate_v6_to_v4_inner(nat46_in + */ + int xlate_payload6_to4(nat46_instance_t *nat46, void *pv6, void *ptrans_hdr, int v6_len, u16 *ul_sum, int *ptailTruncSize) { + struct ipv6hdr *ip6h = pv6; ++ uint32_t ver_class_flow; ++ uint8_t hop_limit; + __u32 v4saddr, v4daddr; + struct iphdr new_ipv4; + struct iphdr *iph = &new_ipv4; +@@ -1274,7 +1297,10 @@ int xlate_payload6_to4(nat46_instance_t + } + } + +- fill_v4hdr_from_v6hdr(iph, ip6h, v4saddr, v4daddr, ipid, ipflags, proto, infrag_payload_len); ++ ver_class_flow = ntohl(*(__be32 *)ip6h); ++ hop_limit = ip6h->hop_limit; ++ ++ fill_v4hdr_from_v6hdr(iph, ver_class_flow, hop_limit, v4saddr, v4daddr, ipid, ipflags, proto, infrag_payload_len); + if(ul_sum) { + *ul_sum = unchecksum16(pv6, (((u8 *)ptrans_hdr)-((u8 *)pv6))/2, *ul_sum); + *ul_sum = rechecksum16(iph, 10, *ul_sum); +@@ -1831,6 +1857,8 @@ EXPORT_SYMBOL(xlate_6_to_4); + + int nat46_ipv6_input(struct sk_buff *old_skb) { + struct ipv6hdr *ip6h = ipv6_hdr(old_skb); ++ uint32_t ver_class_flow; ++ uint8_t hop_limit; + nat46_xlate_rulepair_t *apair; + nat46_instance_t *nat46 = get_nat46_instance(old_skb); + uint16_t proto; +@@ -1839,22 +1867,20 @@ int nat46_ipv6_input(struct sk_buff *old + + struct iphdr * iph; + __u32 v4saddr, v4daddr; +- struct sk_buff * new_skb = 0; + int err = 0; +- int truncSize = 0; + int tailTruncSize = 0; + int v6packet_l3size = sizeof(*ip6h); + int l3_infrag_payload_len = ntohs(ip6h->payload_len); + int check_for_l4 = 0; + +- if (nat46 == NULL) { ++ if (unlikely(nat46 == NULL)) { + printk("nat46:%p skb is dropped for no valid instance found\n", old_skb); + return err; + } + + nat46debug(4, "nat46_ipv6_input packet"); + +- if(ip6_input_not_interested(nat46, ip6h, old_skb)) { ++ if(unlikely(ip6_input_not_interested(nat46, ip6h, old_skb))) { + nat46debug(1, "nat46_ipv6_input not interested"); + goto done; + } +@@ -1985,47 +2011,45 @@ int nat46_ipv6_input(struct sk_buff *old + } + } + +- new_skb = skb_copy(old_skb, GFP_ATOMIC); // other possible option: GFP_ATOMIC +- if (!new_skb) { +- nat46debug(0, "[nat46] Could not copy v6 skb"); +- goto done; +- } ++ ver_class_flow = ntohl(*(__be32 *)ip6h); ++ hop_limit = ip6h->hop_limit; + + /* Remove any debris in the socket control block */ +- memset(IPCB(new_skb), 0, sizeof(struct inet_skb_parm)); ++ memset(IPCB(old_skb), 0, sizeof(struct inet_skb_parm)); ++ + /* Remove netfilter references to IPv6 packet, new netfilter references will be created based on IPv4 packet */ + #if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) +- nf_reset(new_skb); ++ nf_reset(old_skb); + #else +- skb_ext_reset(new_skb); +- nf_reset_ct(new_skb); ++ skb_ext_reset(old_skb); ++ nf_reset_ct(old_skb); + #endif + + /* modify packet: actual IPv6->IPv4 transformation */ +- truncSize = v6packet_l3size - sizeof(struct iphdr); /* chop first 20 bytes */ +- skb_pull(new_skb, truncSize); +- skb_put(new_skb, -tailTruncSize); ++ skb_pull(old_skb, sizeof(struct iphdr)); + l3_infrag_payload_len -= tailTruncSize; +- skb_reset_network_header(new_skb); +- skb_set_transport_header(new_skb,IPV4HDRSIZE); /* transport (TCP/UDP/ICMP/...) header starts after 20 bytes */ ++ skb_reset_mac_header(old_skb); ++ skb_reset_network_header(old_skb); ++ skb_set_transport_header(old_skb,IPV4HDRSIZE); /* transport (TCP/UDP/ICMP/...) header starts after 20 bytes */ + + /* build IPv4 header */ +- iph = ip_hdr(new_skb); +- fill_v4hdr_from_v6hdr(iph, ip6h, v4saddr, v4daddr, frag_id, frag_off, proto, l3_infrag_payload_len); +- new_skb->protocol = htons(ETH_P_IP); ++ iph = ip_hdr(old_skb); ++ fill_v4hdr_from_v6hdr(iph, ver_class_flow, hop_limit, v4saddr, v4daddr, frag_id, frag_off, proto, l3_infrag_payload_len); ++ old_skb->protocol = htons(ETH_P_IP); + + if (ntohs(iph->tot_len) >= 2000) { + nat46debug(0, "Too big IP len: %d", ntohs(iph->tot_len)); + } + +- nat46debug(5, "about to send v4 packet, flags: %02x", IPCB(new_skb)->flags); +- nat46_netdev_count_xmit(new_skb, old_skb->dev); ++ nat46debug(5, "about to send v4 packet, flags: %02x", IPCB(old_skb)->flags); ++ nat46_netdev_count_xmit(old_skb, old_skb->dev); + +- /* set skb->iif */ +- new_skb->skb_iif = old_skb->skb_iif; +- +- netif_rx(new_skb); ++ netif_rx(old_skb); + ++ /* ++ * skb was consumed in the ipv4 format, don't release later. ++ */ ++ err = 1; + /* TBD: should copy be released here? */ + + done: +@@ -2056,7 +2080,7 @@ bool nat46_get_info(struct net_device *d + } + EXPORT_SYMBOL(nat46_get_info); + +-void ip6_update_csum(struct sk_buff * skb, struct ipv6hdr * ip6hdr, int do_atomic_frag) ++void ip6_update_csum(struct sk_buff * skb, struct ipv6hdr * ip6hdr, uint32_t v4saddr, uint32_t v4daddr, int do_atomic_frag) + { + u32 sum1=0; + u16 sum2=0; +@@ -2079,12 +2103,13 @@ void ip6_update_csum(struct sk_buff * sk + struct udphdr *udp = udp_hdr(skb); + unsigned udplen = ntohs(ip6hdr->payload_len) - (do_atomic_frag?8:0); /* UDP hdr + payload */ + +- oldsum = udp->check; +- udp->check = 0; +- +- sum1 = csum_partial((char*)udp, udplen, 0); /* calculate checksum for UDP hdr+payload */ +- sum2 = csum_ipv6_magic(&ip6hdr->saddr, &ip6hdr->daddr, udplen, ip6hdr->nexthdr, sum1); /* add pseudoheader */ +- ++ if (!udp->check) { ++ sum1 = csum_partial((char*)udp, udplen, 0); /* calculate checksum for UDP hdr+payload */ ++ sum2 = csum_ipv6_magic(&ip6hdr->saddr, &ip6hdr->daddr, udplen, ip6hdr->nexthdr, sum1); /* add pseudoheader */ ++ } else { ++ sum1 = csum_ipv4_unmagic(v4saddr, v4daddr, udp->check); ++ sum2 = csum_ipv6_udp_remagic(ip6hdr, sum1); ++ } + udp->check = sum2; + + break; +@@ -2348,7 +2373,6 @@ static uint16_t nat46_get_ce_port(nat46_ + int nat46_ipv4_input(struct sk_buff *old_skb) { + nat46_instance_t *nat46 = get_nat46_instance(old_skb); + nat46_xlate_rulepair_t apair; +- struct sk_buff *new_skb; + uint16_t sport = 0, dport = 0, ret = 0; + + int err = 0; +@@ -2360,10 +2384,15 @@ int nat46_ipv4_input(struct sk_buff *old + + struct ipv6hdr * hdr6; + struct iphdr * hdr4 = ip_hdr(old_skb); ++ uint32_t v4saddr, v4daddr; ++ uint8_t ttl; ++ uint16_t tot_len; ++ uint8_t protocol; ++ uint16_t frag_off, id; + + char v6saddr[16], v6daddr[16]; + +- if (nat46 == NULL) { ++ if (unlikely(nat46 == NULL)) { + printk("nat46:%p skb is dropped for no valid instance found\n", old_skb); + return err; + } +@@ -2443,31 +2472,39 @@ int nat46_ipv4_input(struct sk_buff *old + goto done; + } + +- new_skb = skb_copy(old_skb, GFP_ATOMIC); +- if (!new_skb) { +- nat46debug(0, "[nat46] Could not copy v4 skb"); +- goto done; +- } ++ v4saddr = hdr4->saddr; ++ v4daddr = hdr4->daddr; ++ protocol = hdr4->protocol; ++ tot_len = hdr4->tot_len; ++ ttl = hdr4->ttl; ++ frag_off = hdr4->frag_off; ++ id = hdr4->id; + + /* Remove any debris in the socket control block */ +- memset(IP6CB(new_skb), 0, sizeof(struct inet6_skb_parm)); ++ memset(IP6CB(old_skb), 0, sizeof(struct inet6_skb_parm)); + /* Remove netfilter references to IPv4 packet, new netfilter references will be created based on IPv6 packet */ + #if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) +- nf_reset(new_skb); ++ nf_reset(old_skb); + #else +- skb_ext_reset(new_skb); +- nf_reset_ct(new_skb); ++ skb_ext_reset(old_skb); ++ nf_reset_ct(old_skb); + #endif + + /* expand header (add 20 extra bytes at the beginning of sk_buff) */ +- pskb_expand_head(new_skb, IPV6HDRSIZE - (hdr4->ihl << 2) + (add_frag_header?8:0), 0, GFP_ATOMIC); ++ if (skb_headroom(old_skb) < IPV6V4HDRDELTA) { ++ ret = pskb_expand_head(old_skb, IPV6V4HDRDELTA + (add_frag_header?8:0), 0, GFP_ATOMIC); ++ if (unlikely(ret)) { ++ nat46debug(0, "[nat46] Could not expand skb header"); ++ goto done; ++ } ++ } + +- skb_push(new_skb, IPV6HDRSIZE - (hdr4->ihl << 2) + (add_frag_header?8:0)); /* push boundary by extra 20 bytes */ ++ skb_push(old_skb, IPV6HDRSIZE - (hdr4->ihl << 2) + (add_frag_header?8:0)); /* push boundary by extra 20 bytes */ + +- skb_reset_network_header(new_skb); +- skb_set_transport_header(new_skb, IPV6HDRSIZE + (add_frag_header?8:0) ); /* transport (TCP/UDP/ICMP/...) header starts after 40 bytes */ ++ skb_reset_network_header(old_skb); ++ skb_set_transport_header(old_skb, IPV6HDRSIZE + (add_frag_header?8:0) ); /* transport (TCP/UDP/ICMP/...) header starts after 40 bytes */ + +- hdr6 = ipv6_hdr(new_skb); ++ hdr6 = ipv6_hdr(old_skb); + memset(hdr6, 0, sizeof(*hdr6) + (add_frag_header?8:0)); + + /* build IPv6 header */ +@@ -2475,13 +2512,14 @@ int nat46_ipv4_input(struct sk_buff *old + *(__be32 *)hdr6 = htonl(0x60000000 | (tclass << 20)) | flowlabel; /* version, priority, flowlabel */ + + /* IPv6 length is a payload length, IPv4 is hdr+payload */ +- hdr6->payload_len = htons(ntohs(hdr4->tot_len) - (hdr4->ihl << 2) + (add_frag_header?8:0)); +- hdr6->nexthdr = hdr4->protocol; +- hdr6->hop_limit = hdr4->ttl; ++ hdr6->payload_len = htons(ntohs(tot_len) - sizeof(struct iphdr) + (add_frag_header?8:0)); ++ hdr6->nexthdr = protocol; ++ hdr6->hop_limit = ttl; ++ + memcpy(&hdr6->saddr, v6saddr, 16); + memcpy(&hdr6->daddr, v6daddr, 16); + +- new_skb->protocol = htons(ETH_P_IPV6); ++ old_skb->protocol = htons(ETH_P_IPV6); + + if (add_frag_header) { + struct frag_hdr *fh = (struct frag_hdr*)(hdr6 + 1); +@@ -2490,8 +2528,8 @@ int nat46_ipv4_input(struct sk_buff *old + /* Flag to represent whether PSID is assigned to MAP-T node or not */ + bool is_psid = false; + +- fh->frag_off = htons(((ntohs(hdr4->frag_off) >> 13) & 7) + ((ntohs(hdr4->frag_off) & 0x1FFF) << 3)); +- fh->nexthdr = hdr4->protocol; ++ fh->frag_off = htons(((ntohs(frag_off) >> 13) & 7) + ((ntohs(frag_off) & 0x1FFF) << 3)); ++ fh->nexthdr = protocol; + + /* + * PSID assigned MAP-T node will have non-zero ea_len and we are currently +@@ -2506,29 +2544,30 @@ int nat46_ipv4_input(struct sk_buff *old + if (ce_port_num) { + fh->identification = htonl(ce_port_num); + } else { +- fh->identification = htonl(ntohs(hdr4->id)); ++ fh->identification = htonl(ntohs(id)); + } + } else { +- fh->identification = htonl(ntohs(hdr4->id)); ++ fh->identification = htonl(ntohs(id)); + } + + + } +- ip6_update_csum(new_skb, hdr6, add_frag_header); ++ ip6_update_csum(old_skb, hdr6, v4saddr, v4daddr, add_frag_header); + +- hdr6->nexthdr = add_frag_header ? NEXTHDR_FRAGMENT : hdr4->protocol; ++ hdr6->nexthdr = add_frag_header ? NEXTHDR_FRAGMENT : protocol; + + + // FIXME: check if you can not fit the packet into the cached MTU +- // if (dst_mtu(skb_dst(new_skb))==0) { } +- +- nat46debug(5, "about to send v6 packet, flags: %02x", IP6CB(new_skb)->flags); +- nat46_netdev_count_xmit(new_skb, old_skb->dev); ++ // if (dst_mtu(skb_dst(old_skb))==0) { } + +- /* set skb->iif */ +- new_skb->skb_iif = old_skb->skb_iif; ++ nat46debug(5, "about to send v6 packet, flags: %02x", IPCB(old_skb)->flags); ++ nat46_netdev_count_xmit(old_skb, old_skb->dev); ++ netif_rx(old_skb); + +- netif_rx(new_skb); ++ /* ++ * skb was reused, needn't free it later. ++ */ ++ err = 1; + + done: + release_nat46_instance(nat46); +--- a/nat46/modules/nat46-core.h ++++ b/nat46/modules/nat46-core.h +@@ -39,7 +39,7 @@ + #define IPV4HDRSIZE 20 + #define IPV6V4HDRDELTA (IPV6HDRSIZE - IPV4HDRSIZE) + +-/* ++/* + * A generic v4<->v6 translation structure. + * The currently supported translation styles: + */ +--- a/nat46/modules/nat46-netdev.c ++++ b/nat46/modules/nat46-netdev.c +@@ -100,8 +100,7 @@ static netdev_tx_t nat46_netdev_xmit(str + + if(ETH_P_IP == ntohs(skb->protocol)) { + ret = nat46_ipv4_input(skb); +- } +- if(ETH_P_IPV6 == ntohs(skb->protocol)) { ++ }else if(ETH_P_IPV6 == ntohs(skb->protocol)) { + ret = nat46_ipv6_input(skb); + } + if(0 == ret) { +@@ -174,6 +173,7 @@ static void nat46_netdev_setup(struct ne + dev->mtu = 16384; /* iptables does reassembly. Rather than using ETH_DATA_LEN, let's try to get as much mileage as we can with the Linux stack */ + dev->features = NETIF_F_NETNS_LOCAL; + dev->flags = IFF_NOARP | IFF_POINTOPOINT; ++ dev->priv_flags_ext = IFF_EXT_MAPT; + } + + int nat46_netdev_create(char *basename, struct net_device **dev) diff --git a/package/kernel/nat46/patches/120-sleeping_backtrace.patch b/package/kernel/nat46/patches/120-sleeping_backtrace.patch new file mode 100644 index 00000000000000..5963af2b0365d7 --- /dev/null +++ b/package/kernel/nat46/patches/120-sleeping_backtrace.patch @@ -0,0 +1,57 @@ +commit 9457a8be6e700f39e6b545f8db0edd30c0693700 +Author: Ken Zhu +Date: Tue Sep 6 11:11:20 2022 -0700 + + nat46: fix sleeping warning back trace + + use spin_lock instead of mutex_lock since + mutex_lock could sleep in the kernel packet process. + + Change-Id: I65c15a9f618ef296159884a0d6d742e66aaf6623 + Signed-off-by: Ken Zhu + +--- a/nat46/modules/nat46-glue.c ++++ b/nat46/modules/nat46-glue.c +@@ -18,7 +18,7 @@ + #include "nat46-glue.h" + #include "nat46-core.h" + +-static DEFINE_MUTEX(ref_lock); ++static DEFINE_SPINLOCK(ref_lock); + int is_valid_nat46(nat46_instance_t *nat46) { + return (nat46 && (nat46->sig == NAT46_SIGNATURE)); + } +@@ -47,28 +47,27 @@ nat46_instance_t *alloc_nat46_instance(i + return nat46; + } + +- + nat46_instance_t *get_nat46_instance(struct sk_buff *sk) { + nat46_instance_t *nat46 = netdev_nat46_instance(sk->dev); +- mutex_lock(&ref_lock); ++ spin_lock_bh(&ref_lock); + if (is_valid_nat46(nat46)) { + nat46->refcount++; +- mutex_unlock(&ref_lock); ++ spin_unlock_bh(&ref_lock); + return nat46; + } else { + printk("[nat46] get_nat46_instance: Could not find a valid NAT46 instance!"); +- mutex_unlock(&ref_lock); ++ spin_unlock_bh(&ref_lock); + return NULL; + } + } + + void release_nat46_instance(nat46_instance_t *nat46) { +- mutex_lock(&ref_lock); ++ spin_lock_bh(&ref_lock); + nat46->refcount--; + if(0 == nat46->refcount) { + printk("[nat46] release_nat46_instance: freeing nat46 instance with %d pairs\n", nat46->npairs); + nat46->sig = FREED_NAT46_SIGNATURE; + kfree(nat46); + } +- mutex_unlock(&ref_lock); ++ spin_unlock_bh(&ref_lock); + } diff --git a/package/kernel/nat46/patches/121-tos-fix.patch b/package/kernel/nat46/patches/121-tos-fix.patch new file mode 100644 index 00000000000000..6b265886f5b70b --- /dev/null +++ b/package/kernel/nat46/patches/121-tos-fix.patch @@ -0,0 +1,27 @@ +Author: Ramkishan Gurjar +Date: Thu Nov 16 15:30:04 2023 +0530 + + nat46: Fix traffic class is not set in ipv6 Header from ipv4 tos value. + + Change-Id: I781d7af8bc9751dd23f6c3f4195644b3f9025fcb + Signed-off-by: Ramkishan Gurjar + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -2397,6 +2397,8 @@ int nat46_ipv4_input(struct sk_buff *old + return err; + } + ++ tclass = ip_tos_ignore ? 0 : hdr4->tos; /* traffic class */ ++ + memset(v6saddr, 1, 16); + memset(v6daddr, 2, 16); + +@@ -2508,7 +2510,6 @@ int nat46_ipv4_input(struct sk_buff *old + memset(hdr6, 0, sizeof(*hdr6) + (add_frag_header?8:0)); + + /* build IPv6 header */ +- tclass = ip_tos_ignore ? 0 : hdr4->tos; /* traffic class */ + *(__be32 *)hdr6 = htonl(0x60000000 | (tclass << 20)) | flowlabel; /* version, priority, flowlabel */ + + /* IPv6 length is a payload length, IPv4 is hdr+payload */ From 5eb71f15ddfe250a18c5f82c91fbdc6ea7dfeaa6 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 24 Mar 2024 21:08:35 -0400 Subject: [PATCH 153/225] qualcommax: Move ppdu-end-interrupts-mac3 to CPU2, xhci-hcd:usb1 to CPU1 For NSS builds, CPU3 is currently utilized by nss_empty_buf_sos (core0/1), nss_empty_buf_queue, and nss_queue3. Move ppdu-end-interrupts-mac3 over to CPU2 since ppdu-end-interrupts-mac2 is not utilizing it, as well balance out the CPU load. 39: 148 0 0 6215160 GIC-0 409 Edge nss_empty_buf_sos 40: 0 0 0 42756334 GIC-0 410 Edge nss_empty_buf_queue 42: 242935359 0 0 0 GIC-0 412 Edge nss_queue0 43: 0 10284395 0 0 GIC-0 413 Edge nss_queue1 44: 0 0 15731276 0 GIC-0 414 Edge nss_queue2 45: 0 0 0 10031023 GIC-0 415 Edge nss_queue3 49: 72 0 0 552286 GIC-0 422 Edge nss_empty_buf_sos 73: 14 25806714 0 0 GIC-0 261 Edge ppdu-end-interrupts-mac1 75: 9 0 24733399 0 GIC-0 263 Edge ppdu-end-interrupts-mac3 77: 0 0 0 0 GIC-0 262 Edge ppdu-end-interrupts-mac2 Also move xhci-hcd:usb1 to CPU1 since CE 0-11 occupies much of CPU0 and cannot be moved without causing stability issues. --- .../qualcommax/ipq807x/base-files/etc/init.d/smp_affinity | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/target/linux/qualcommax/ipq807x/base-files/etc/init.d/smp_affinity b/target/linux/qualcommax/ipq807x/base-files/etc/init.d/smp_affinity index 05d13fff633035..f52aca5e32c925 100755 --- a/target/linux/qualcommax/ipq807x/base-files/etc/init.d/smp_affinity +++ b/target/linux/qualcommax/ipq807x/base-files/etc/init.d/smp_affinity @@ -21,14 +21,18 @@ enable_affinity_ipq807x() { # assign 3 ppdu mac interrupts to last 3 cores set_affinity 'ppdu-end-interrupts-mac1' 2 - set_affinity 'ppdu-end-interrupts-mac2' 4 - set_affinity 'ppdu-end-interrupts-mac3' 8 + set_affinity 'ppdu-end-interrupts-mac2' 8 + set_affinity 'ppdu-end-interrupts-mac3' 4 # assign lan/wan to core 4 set_affinity 'edma_txcmpl' 8 set_affinity 'edma_rxfill' 8 set_affinity 'edma_rxdesc' 8 set_affinity 'edma_misc' 8 + + # assign usb1 to core 2 + set_affinity 'xhci-hcd:usb1' 2 + } boot() { From 5dab576e02fd96b6362c89c4bdf40d28cbab3cfc Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 24 Mar 2024 21:33:21 -0400 Subject: [PATCH 154/225] qualcommax: Move QCE to user selectable module The performance of Qualcomm Crypto Engine is 10x slower than kernel based encryption via ARMv8 crypto extensions. Rather than building it into the kernel allow users to select it as module which can be tested with other HW based crypto APIs via cryptodev-linux. --- package/kernel/linux/modules/crypto.mk | 17 +++++++++++++++++ target/linux/qualcommax/config-6.1 | 12 ++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/package/kernel/linux/modules/crypto.mk b/package/kernel/linux/modules/crypto.mk index be9893d4539675..60aaad7fe39b65 100644 --- a/package/kernel/linux/modules/crypto.mk +++ b/package/kernel/linux/modules/crypto.mk @@ -1159,3 +1159,20 @@ endef $(eval $(call KernelPackage,crypto-xts)) +define KernelPackage/crypto-qce + TITLE:=QTI Crypto Engine (QCE) + KCONFIG:= \ + CONFIG_CRYPTO_DEV_QCE \ + CONFIG_CRYPTO_DEV_QCE_AEAD=y \ + CONFIG_CRYPTO_DEV_QCE_ENABLE_ALL=y \ + CONFIG_CRYPTO_DEV_QCE_SHA=y \ + CONFIG_CRYPTO_DEV_QCE_SKCIPHER=y \ + CONFIG_CRYPTO_DEV_QCE_SW_MAX_LEN=512 + FILES:= \ + $(LINUX_DIR)/drivers/crypto/qce/qcrypto.ko + AUTOLOAD:=$(call AutoLoad,09,qcrypto) + DEPENDS:=@TARGET_qualcommax +kmod-crypto-manager +kmod-crypto-hash +kmod-crypto-des + $(call AddDepends/crypto) +endef + +$(eval $(call KernelPackage,crypto-qce)) diff --git a/target/linux/qualcommax/config-6.1 b/target/linux/qualcommax/config-6.1 index 67616fe12640fd..c90649040d9bfd 100644 --- a/target/linux/qualcommax/config-6.1 +++ b/target/linux/qualcommax/config-6.1 @@ -101,15 +101,15 @@ CONFIG_CRC8=y CONFIG_CRYPTO_AUTHENC=y CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_DEV_QCE=y -CONFIG_CRYPTO_DEV_QCE_AEAD=y +# CONFIG_CRYPTO_DEV_QCE=y +# CONFIG_CRYPTO_DEV_QCE_AEAD=y # CONFIG_CRYPTO_DEV_QCE_ENABLE_AEAD is not set -CONFIG_CRYPTO_DEV_QCE_ENABLE_ALL=y +# CONFIG_CRYPTO_DEV_QCE_ENABLE_ALL=y # CONFIG_CRYPTO_DEV_QCE_ENABLE_SHA is not set # CONFIG_CRYPTO_DEV_QCE_ENABLE_SKCIPHER is not set -CONFIG_CRYPTO_DEV_QCE_SHA=y -CONFIG_CRYPTO_DEV_QCE_SKCIPHER=y -CONFIG_CRYPTO_DEV_QCE_SW_MAX_LEN=512 +# CONFIG_CRYPTO_DEV_QCE_SHA=y +# CONFIG_CRYPTO_DEV_QCE_SKCIPHER=y +# CONFIG_CRYPTO_DEV_QCE_SW_MAX_LEN=512 CONFIG_CRYPTO_DEV_QCOM_RNG=y CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_HASH_INFO=y From bb0fdcbda12a57eb282b678e830aff45f6863c63 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 24 Mar 2024 22:44:54 -0400 Subject: [PATCH 155/225] qualcommax: NSS: initial kernel 6.6 support --- package/devel/perf/Makefile | 4 +- target/linux/qualcommax/config-6.6 | 39 +- .../files/net/core/skbuff_recycle.c | 5 + ...ts-ipq8074-add-reserved-memory-nodes.patch | 2 +- ...added-for-necessary-clocks-and-reset.patch | 311 +++++++ ...-gcc_snoc_bus_timeout_ahb_clk-offset.patch | 44 + ...074-Fix-gcc_blsp1_ahb_clk-properties.patch | 41 + .../0600-1-qca-nss-ecm-support-CORE.patch | 865 +++++++++++++++++ ...x-IPv6-user-route-change-event-calls.patch | 87 ++ ...-2-qca-nss-ecm-support-PPPOE-offload.patch | 600 ++++++++++++ ...00-3-qca-nss-ecm-support-net-bonding.patch | 46 + ...pport-net-bonding-over-LAG-interface.patch | 685 ++++++++++++++ .../0600-5-qca-nss-ecm-support-macvlan.patch | 96 ++ ...nss-ecm-support-netfilter-DSCPREMARK.patch | 154 +++ ...601-1-qca-add-nss-bridge-mgr-support.patch | 92 ++ ...0602-1-qca-nss-drv-add-qdisc-support.patch | 25 + ...-1-qca-nss-clients-add-qdisc-support.patch | 463 +++++++++ ...3-2-qca-nss-clients-add-l2tp-support.patch | 46 + ...3-3-qca-nss-clients-add-PPTP-support.patch | 478 ++++++++++ ...qca-nss-clients-add-iptunnel-support.patch | 77 ++ ...-5-qca-nss-clients-add-vxlan-support.patch | 103 ++ ...-clients-add-l2tp-offloading-support.patch | 368 ++++++++ ...a-nss-clients-iptunnel-lock-this-cpu.patch | 22 + ...-qca-nss-clients-add-tls-mgr-support.patch | 24 + .../0604-1-qca-add-mcs-support.patch | 876 ++++++++++++++++++ .../0605-1-qca-nss-cfi-support.patch | 111 +++ ..._ecache-Fix-NSS-ECM-BRK-kernel-panic.patch | 10 + ...l-pointer-dereference-in-ipv6-output.patch | 80 ++ .../9990-1-qca-skb_recycler-support.patch | 396 ++++++++ ...-api-disallow-identical-driver-names.patch | 10 + .../9999-silence-UBI-NAND-warnings.patch | 13 + 31 files changed, 6161 insertions(+), 12 deletions(-) create mode 100644 target/linux/qualcommax/patches-6.6/0170-clk-qcom-ipq8074-Support-added-for-necessary-clocks-and-reset.patch create mode 100644 target/linux/qualcommax/patches-6.6/0171-1-clk-qcom-ipq8074-Fix-gcc_snoc_bus_timeout_ahb_clk-offset.patch create mode 100644 target/linux/qualcommax/patches-6.6/0171-2-clk-qcom-ipq8074-Fix-gcc_blsp1_ahb_clk-properties.patch create mode 100644 target/linux/qualcommax/patches-6.6/0600-1-qca-nss-ecm-support-CORE.patch create mode 100644 target/linux/qualcommax/patches-6.6/0600-2-qca-nss-ecm-support-CORE-Fix-IPv6-user-route-change-event-calls.patch create mode 100644 target/linux/qualcommax/patches-6.6/0600-2-qca-nss-ecm-support-PPPOE-offload.patch create mode 100644 target/linux/qualcommax/patches-6.6/0600-3-qca-nss-ecm-support-net-bonding.patch create mode 100644 target/linux/qualcommax/patches-6.6/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch create mode 100644 target/linux/qualcommax/patches-6.6/0600-5-qca-nss-ecm-support-macvlan.patch create mode 100644 target/linux/qualcommax/patches-6.6/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch create mode 100644 target/linux/qualcommax/patches-6.6/0601-1-qca-add-nss-bridge-mgr-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/0602-1-qca-nss-drv-add-qdisc-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/0603-1-qca-nss-clients-add-qdisc-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/0603-2-qca-nss-clients-add-l2tp-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/0603-3-qca-nss-clients-add-PPTP-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/0603-4-qca-nss-clients-add-iptunnel-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/0603-5-qca-nss-clients-add-vxlan-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/0603-6-qca-nss-clients-add-l2tp-offloading-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch create mode 100644 target/linux/qualcommax/patches-6.6/0603-8-qca-nss-clients-add-tls-mgr-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/0604-1-qca-add-mcs-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/0605-1-qca-nss-cfi-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch create mode 100644 target/linux/qualcommax/patches-6.6/0611-ipv6-Fix-null-pointer-dereference-in-ipv6-output.patch create mode 100644 target/linux/qualcommax/patches-6.6/9990-1-qca-skb_recycler-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/9999-revert-crypto-api-disallow-identical-driver-names.patch create mode 100644 target/linux/qualcommax/patches-6.6/9999-silence-UBI-NAND-warnings.patch diff --git a/package/devel/perf/Makefile b/package/devel/perf/Makefile index f9573c4150feb7..979865690e4fc1 100644 --- a/package/devel/perf/Makefile +++ b/package/devel/perf/Makefile @@ -28,7 +28,7 @@ define Package/perf SECTION:=devel CATEGORY:=Development DEPENDS:= +libelf +libdw +PACKAGE_libunwind:libunwind +libpthread +librt +objdump @!IN_SDK @KERNEL_PERF_EVENTS \ - +PACKAGE_libbfd:libbfd +PACKAGE_libopcodes:libopcodes + +PACKAGE_libbfd:libbfd +PACKAGE_libopcodes:libopcodes +libstdcpp TITLE:=Linux performance monitoring tool VERSION:=$(LINUX_VERSION)-$(PKG_RELEASE) URL:=http://www.kernel.org @@ -56,6 +56,8 @@ MAKE_FLAGS = \ NO_LIBUNWIND=1 \ NO_LIBZSTD=1 \ NO_LIBCAP=1 \ + NO_LIBTRACEEVENT=1 \ + NO_LIBBPF=1 \ CROSS_COMPILE="$(TARGET_CROSS)" \ CC="$(TARGET_CC)" \ LD="$(TARGET_CROSS)ld" \ diff --git a/target/linux/qualcommax/config-6.6 b/target/linux/qualcommax/config-6.6 index 71b54041c50e59..b9313b3eb9bb0a 100644 --- a/target/linux/qualcommax/config-6.6 +++ b/target/linux/qualcommax/config-6.6 @@ -44,6 +44,8 @@ CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE=y CONFIG_ARM_AMBA=y CONFIG_ARM_ARCH_TIMER=y CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +# CONFIG_ARM_SMMU_V3_PMU is not set +# CONFIG_ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU is not set CONFIG_ARM_GIC=y CONFIG_ARM_GIC_V2M=y CONFIG_ARM_GIC_V3=y @@ -78,11 +80,11 @@ CONFIG_COREDUMP=y CONFIG_CPUFREQ_DT=y CONFIG_CPUFREQ_DT_PLATDEV=y CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set CONFIG_CPU_FREQ_GOV_ATTR_SET=y # CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set -# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_GOV_ONDEMAND=y CONFIG_CPU_FREQ_GOV_PERFORMANCE=y # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y @@ -101,15 +103,15 @@ CONFIG_CRC8=y CONFIG_CRYPTO_AUTHENC=y CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_DEV_QCE=y -CONFIG_CRYPTO_DEV_QCE_AEAD=y +# CONFIG_CRYPTO_DEV_QCE is not set +# CONFIG_CRYPTO_DEV_QCE_AEAD is not set # CONFIG_CRYPTO_DEV_QCE_ENABLE_AEAD is not set -CONFIG_CRYPTO_DEV_QCE_ENABLE_ALL=y +# CONFIG_CRYPTO_DEV_QCE_ENABLE_ALL is not set # CONFIG_CRYPTO_DEV_QCE_ENABLE_SHA is not set # CONFIG_CRYPTO_DEV_QCE_ENABLE_SKCIPHER is not set -CONFIG_CRYPTO_DEV_QCE_SHA=y -CONFIG_CRYPTO_DEV_QCE_SKCIPHER=y -CONFIG_CRYPTO_DEV_QCE_SW_MAX_LEN=512 +# CONFIG_CRYPTO_DEV_QCE_SHA is not set +# CONFIG_CRYPTO_DEV_QCE_SKCIPHER is not set +# CONFIG_CRYPTO_DEV_QCE_SW_MAX_LEN is not set CONFIG_CRYPTO_DEV_QCOM_RNG=y CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_HASH_INFO=y @@ -125,6 +127,8 @@ CONFIG_CRYPTO_RNG=y CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_SHA1=y CONFIG_CRYPTO_SHA256=y +# CONFIG_CRYPTO_SM4_ARM64_CE_CCM is not set +# CONFIG_CRYPTO_SM4_ARM64_CE_GCM is not set CONFIG_CRYPTO_XTS=y CONFIG_CRYPTO_ZSTD=y CONFIG_DCACHE_WORD_ACCESS=y @@ -192,6 +196,11 @@ CONFIG_HAS_IOPORT=y CONFIG_HAS_IOPORT_MAP=y CONFIG_HWSPINLOCK=y CONFIG_HWSPINLOCK_QCOM=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MSM=y +CONFIG_HZ=1000 +# CONFIG_HZ_100 is not set +CONFIG_HZ_1000=y CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y @@ -375,7 +384,12 @@ CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y CONFIG_POWER_RESET=y # CONFIG_POWER_RESET_MSM is not set CONFIG_POWER_SUPPLY=y -CONFIG_PREEMPT_NONE_BUILD=y +CONFIG_PREEMPT=y +CONFIG_PREEMPT_COUNT=y +# CONFIG_PREEMPT_DYNAMIC is not set +# CONFIG_PREEMPT_NONE_BUILD is not set +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_RCU=y CONFIG_PRINTK_TIME=y CONFIG_PTP_1588_CLOCK_OPTIONAL=y CONFIG_QCA807X_PHY=y @@ -504,6 +518,11 @@ CONFIG_SERIAL_MSM=y CONFIG_SERIAL_MSM_CONSOLE=y CONFIG_SGL_ALLOC=y CONFIG_SG_POOL=y +# CONFIG_ALLOC_SKB_PAGE_FRAG_DISABLE is not set +# CONFIG_DEBUG_OBJECTS_SKBUFF is not set +CONFIG_SKB_RECYCLER=y +CONFIG_SKB_RECYCLER_MULTI_CPU=y +# CONFIG_SKB_FAST_RECYCLABLE_DEBUG_ENABLE is not set CONFIG_SMP=y # CONFIG_SM_CAMCC_6350 is not set # CONFIG_SM_CAMCC_8450 is not set diff --git a/target/linux/qualcommax/files/net/core/skbuff_recycle.c b/target/linux/qualcommax/files/net/core/skbuff_recycle.c index 41add8d3098fca..cbcbc46c70d0a5 100644 --- a/target/linux/qualcommax/files/net/core/skbuff_recycle.c +++ b/target/linux/qualcommax/files/net/core/skbuff_recycle.c @@ -18,6 +18,7 @@ #include "skbuff_recycle.h" #include #include +#include #include "skbuff_debug.h" @@ -279,7 +280,11 @@ static void skb_recycler_free_skb(struct sk_buff_head *list) skbuff_debugobj_activate(skb); next = skb->next; __skb_unlink(skb, list); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,2,0) + skb_release_data(skb, SKB_CONSUMED, false); +#else skb_release_data(skb); +#endif kfree_skbmem(skb); /* * Update the skb->sum for next due to skb_link operation diff --git a/target/linux/qualcommax/patches-6.6/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch b/target/linux/qualcommax/patches-6.6/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch index 6d97641f658cc1..7d43b602c76e7a 100644 --- a/target/linux/qualcommax/patches-6.6/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch +++ b/target/linux/qualcommax/patches-6.6/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch @@ -23,7 +23,7 @@ Signed-off-by: Robert Marko #size-cells = <2>; ranges; -+ nss@40000000 { ++ nss_region@40000000 { + no-map; + reg = <0x0 0x40000000 0x0 0x01000000>; + }; diff --git a/target/linux/qualcommax/patches-6.6/0170-clk-qcom-ipq8074-Support-added-for-necessary-clocks-and-reset.patch b/target/linux/qualcommax/patches-6.6/0170-clk-qcom-ipq8074-Support-added-for-necessary-clocks-and-reset.patch new file mode 100644 index 00000000000000..76cc8caac9a412 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0170-clk-qcom-ipq8074-Support-added-for-necessary-clocks-and-reset.patch @@ -0,0 +1,311 @@ +From 6504bc9edeb1a2a54d813f4bb5d0267e7bf827f9 Mon Sep 17 00:00:00 2001 +From: Praveenkumar I +Date: Thu, 6 Feb 2020 17:35:42 +0530 +Subject: [PATCH 4/8] clk: ipq8074: Support added for necessary clocks and + reset + +Change-Id: I21a76a44185f766e9b6dcba274392ea8e599718b +Signed-off-by: Praveenkumar I +Signed-off-by: Rajkumar Ayyasamy +--- + drivers/clk/qcom/gcc-ipq8074.c | 238 ++++++++++++++++++- + include/dt-bindings/clock/qcom,gcc-ipq8074.h | 35 ++- + 2 files changed, 258 insertions(+), 15 deletions(-) + +--- a/drivers/clk/qcom/gcc-ipq8074.c ++++ b/drivers/clk/qcom/gcc-ipq8074.c +@@ -48,6 +48,22 @@ enum { + P_UNIPHY2_TX, + }; + ++static const char * const gcc_xo_gpll4_gpll0_gpll6_gpll0_div2[] = { ++ "xo", ++ "gpll4", ++ "gpll0", ++ "gpll6", ++ "gpll0_out_main_div2", ++}; ++ ++static const struct parent_map gcc_xo_gpll4_gpll0_gpll6_gpll0_div2_map[] = { ++ { P_XO, 0 }, ++ { P_GPLL4, 1 }, ++ { P_GPLL0, 2 }, ++ { P_GPLL6, 3 }, ++ { P_GPLL0_DIV2, 4 }, ++}; ++ + static struct clk_alpha_pll gpll0_main = { + .offset = 0x21000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], +@@ -629,6 +645,12 @@ static const struct freq_tbl ftbl_pcie_a + { } + }; + ++struct freq_tbl ftbl_pcie_rchng_clk_src[] = { ++ F(19200000, P_XO, 1, 0, 0), ++ F(100000000, P_GPLL0, 8, 0, 0), ++ { } ++}; ++ + static struct clk_rcg2 pcie0_axi_clk_src = { + .cmd_rcgr = 0x75054, + .freq_tbl = ftbl_pcie_axi_clk_src, +@@ -2029,6 +2051,78 @@ static struct clk_rcg2 gp3_clk_src = { + }, + }; + ++struct freq_tbl ftbl_qdss_tsctr_clk_src[] = { ++ F(160000000, P_GPLL0_DIV2, 2.5, 0, 0), ++ F(320000000, P_GPLL0, 2.5, 0, 0), ++ F(600000000, P_GPLL6, 2, 0, 0), ++ { } ++}; ++ ++struct clk_rcg2 qdss_tsctr_clk_src = { ++ .cmd_rcgr = 0x29064, ++ .freq_tbl = ftbl_qdss_tsctr_clk_src, ++ .hid_width = 5, ++ .parent_map = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2_map, ++ .clkr.hw.init = &(struct clk_init_data){ ++ .name = "qdss_tsctr_clk_src", ++ .parent_names = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2, ++ .num_parents = 5, ++ .ops = &clk_rcg2_ops, ++ }, ++}; ++ ++static struct clk_fixed_factor qdss_dap_sync_clk_src = { ++ .mult = 1, ++ .div = 4, ++ .hw.init = &(struct clk_init_data){ ++ .name = "qdss_dap_sync_clk_src", ++ .parent_names = (const char *[]){ ++ "qdss_tsctr_clk_src" ++ }, ++ .num_parents = 1, ++ .ops = &clk_fixed_factor_ops, ++ }, ++}; ++ ++struct freq_tbl ftbl_qdss_at_clk_src[] = { ++ F(66670000, P_GPLL0_DIV2, 6, 0, 0), ++ F(240000000, P_GPLL6, 6, 0, 0), ++ { } ++}; ++ ++struct clk_rcg2 qdss_at_clk_src = { ++ .cmd_rcgr = 0x2900c, ++ .freq_tbl = ftbl_qdss_at_clk_src, ++ .hid_width = 5, ++ .parent_map = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2_map, ++ .clkr.hw.init = &(struct clk_init_data){ ++ .name = "qdss_at_clk_src", ++ .parent_names = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2, ++ .num_parents = 5, ++ .ops = &clk_rcg2_ops, ++ }, ++}; ++ ++ ++struct freq_tbl ftbl_adss_pwm_clk_src[] = { ++ F(19200000, P_XO, 1, 0, 0), ++ F(200000000, P_GPLL0, 4, 0, 0), ++ { } ++}; ++ ++struct clk_rcg2 adss_pwm_clk_src = { ++ .cmd_rcgr = 0x1c008, ++ .freq_tbl = ftbl_adss_pwm_clk_src, ++ .hid_width = 5, ++ .parent_map = gcc_xo_gpll0_map, ++ .clkr.hw.init = &(struct clk_init_data){ ++ .name = "adss_pwm_clk_src", ++ .parent_data = gcc_xo_gpll0, ++ .num_parents = 2, ++ .ops = &clk_rcg2_ops, ++ }, ++}; ++ + static struct clk_branch gcc_blsp1_ahb_clk = { + .halt_reg = 0x01008, + .clkr = { +@@ -4224,13 +4318,7 @@ static struct clk_branch gcc_gp3_clk = { + }, + }; + +-static const struct freq_tbl ftbl_pcie_rchng_clk_src[] = { +- F(19200000, P_XO, 1, 0, 0), +- F(100000000, P_GPLL0, 8, 0, 0), +- { } +-}; +- +-static struct clk_rcg2 pcie0_rchng_clk_src = { ++struct clk_rcg2 pcie0_rchng_clk_src = { + .cmd_rcgr = 0x75070, + .freq_tbl = ftbl_pcie_rchng_clk_src, + .hid_width = 5, +@@ -4322,6 +4410,114 @@ static const struct alpha_pll_config nss + .alpha_en_mask = BIT(24), + }; + ++static struct clk_branch gcc_snoc_bus_timeout2_ahb_clk = { ++ .halt_reg = 0x4700c, ++ .halt_bit = 31, ++ .clkr = { ++ .enable_reg = 0x4700c, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_snoc_bus_timeout2_ahb_clk", ++ .parent_names = (const char *[]){ ++ "usb0_master_clk_src" ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_snoc_bus_timeout3_ahb_clk = { ++ .halt_reg = 0x47014, ++ .halt_bit = 31, ++ .clkr = { ++ .enable_reg = 0x47014, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_snoc_bus_timeout3_ahb_clk", ++ .parent_names = (const char *[]){ ++ "usb1_master_clk_src" ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_dcc_clk = { ++ .halt_reg = 0x77004, ++ .halt_bit = 31, ++ .clkr = { ++ .enable_reg = 0x77004, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_dcc_clk", ++ .parent_names = (const char *[]){ ++ "pcnoc_clk_src" ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_qdss_at_clk = { ++ .halt_reg = 0x29024, ++ .halt_bit = 31, ++ .clkr = { ++ .enable_reg = 0x29024, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_qdss_at_clk", ++ .parent_names = (const char *[]){ ++ "qdss_at_clk_src" ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_qdss_dap_clk = { ++ .halt_reg = 0x29084, ++ .halt_bit = 31, ++ .clkr = { ++ .enable_reg = 0x29084, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_qdss_dap_clk", ++ .parent_names = (const char *[]){ ++ "qdss_dap_sync_clk_src" ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_adss_pwm_clk = { ++ .halt_reg = 0x1c020, ++ .halt_bit = 31, ++ .clkr = { ++ .enable_reg = 0x1c020, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_adss_pwm_clk", ++ .parent_names = (const char *[]){ ++ "adss_pwm_clk_src" ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ + static struct clk_hw *gcc_ipq8074_hws[] = { + &gpll0_out_main_div2.hw, + &gpll6_out_main_div2.hw, +@@ -4330,6 +4526,7 @@ static struct clk_hw *gcc_ipq8074_hws[] + &gcc_xo_div4_clk_src.hw, + &nss_noc_clk_src.hw, + &nss_ppe_cdiv_clk_src.hw, ++ &qdss_dap_sync_clk_src.hw, + }; + + static struct clk_regmap *gcc_ipq8074_clks[] = { +@@ -4561,6 +4758,15 @@ static struct clk_regmap *gcc_ipq8074_cl + [GCC_PCIE0_RCHNG_CLK] = &gcc_pcie0_rchng_clk.clkr, + [GCC_PCIE0_AXI_S_BRIDGE_CLK] = &gcc_pcie0_axi_s_bridge_clk.clkr, + [GCC_CRYPTO_PPE_CLK] = &gcc_crypto_ppe_clk.clkr, ++ [GCC_SNOC_BUS_TIMEOUT2_AHB_CLK] = &gcc_snoc_bus_timeout2_ahb_clk.clkr, ++ [GCC_SNOC_BUS_TIMEOUT3_AHB_CLK] = &gcc_snoc_bus_timeout3_ahb_clk.clkr, ++ [GCC_DCC_CLK] = &gcc_dcc_clk.clkr, ++ [QDSS_TSCTR_CLK_SRC] = &qdss_tsctr_clk_src.clkr, ++ [QDSS_AT_CLK_SRC] = &qdss_at_clk_src.clkr, ++ [GCC_QDSS_AT_CLK] = &gcc_qdss_at_clk.clkr, ++ [GCC_QDSS_DAP_CLK] = &gcc_qdss_dap_clk.clkr, ++ [ADSS_PWM_CLK_SRC] = &adss_pwm_clk_src.clkr, ++ [GCC_ADSS_PWM_CLK] = &gcc_adss_pwm_clk.clkr, + }; + + static const struct qcom_reset_map gcc_ipq8074_resets[] = { +--- a/include/dt-bindings/clock/qcom,gcc-ipq8074.h ++++ b/include/dt-bindings/clock/qcom,gcc-ipq8074.h +@@ -230,10 +230,19 @@ + #define GCC_GP1_CLK 221 + #define GCC_GP2_CLK 222 + #define GCC_GP3_CLK 223 +-#define GCC_PCIE0_AXI_S_BRIDGE_CLK 224 +-#define GCC_PCIE0_RCHNG_CLK_SRC 225 +-#define GCC_PCIE0_RCHNG_CLK 226 +-#define GCC_CRYPTO_PPE_CLK 227 ++#define GCC_CRYPTO_PPE_CLK 224 ++#define GCC_PCIE0_RCHNG_CLK_SRC 225 ++#define GCC_PCIE0_RCHNG_CLK 226 ++#define GCC_PCIE0_AXI_S_BRIDGE_CLK 227 ++#define GCC_SNOC_BUS_TIMEOUT2_AHB_CLK 228 ++#define GCC_SNOC_BUS_TIMEOUT3_AHB_CLK 229 ++#define GCC_DCC_CLK 230 ++#define ADSS_PWM_CLK_SRC 231 ++#define GCC_ADSS_PWM_CLK 232 ++#define QDSS_TSCTR_CLK_SRC 233 ++#define QDSS_AT_CLK_SRC 234 ++#define GCC_QDSS_AT_CLK 235 ++#define GCC_QDSS_DAP_CLK 236 + + #define GCC_BLSP1_BCR 0 + #define GCC_BLSP1_QUP1_BCR 1 diff --git a/target/linux/qualcommax/patches-6.6/0171-1-clk-qcom-ipq8074-Fix-gcc_snoc_bus_timeout_ahb_clk-offset.patch b/target/linux/qualcommax/patches-6.6/0171-1-clk-qcom-ipq8074-Fix-gcc_snoc_bus_timeout_ahb_clk-offset.patch new file mode 100644 index 00000000000000..b1393fc9ad43c2 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0171-1-clk-qcom-ipq8074-Fix-gcc_snoc_bus_timeout_ahb_clk-offset.patch @@ -0,0 +1,44 @@ +From 462aa0c53397ec5bf78e3e7f68aa8a3ca300f4ba Mon Sep 17 00:00:00 2001 +From: Selvam Sathappan Periakaruppan +Date: Tue, 24 Mar 2020 19:09:38 +0530 +Subject: [PATCH 5/8] clk: qcom: ipq8074: Fix gcc_snoc_bus_timeout_ahb_clk + offset + +By default, the ipq8074 V2 clks are provided in the gcc driver. +Updating the gcc_snoc_bus_timeout_ahb_clk offsets also as needed +in ipq8074 V2. + +Change-Id: I5a6e98d002f5c3354a804e55dd9ebb1f83f7f974 +Signed-off-by: Selvam Sathappan Periakaruppan +--- + drivers/clk/qcom/gcc-ipq8074.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/clk/qcom/gcc-ipq8074.c ++++ b/drivers/clk/qcom/gcc-ipq8074.c +@@ -4411,10 +4411,10 @@ static const struct alpha_pll_config nss + }; + + static struct clk_branch gcc_snoc_bus_timeout2_ahb_clk = { +- .halt_reg = 0x4700c, ++ .halt_reg = 0x47014, + .halt_bit = 31, + .clkr = { +- .enable_reg = 0x4700c, ++ .enable_reg = 0x47014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_snoc_bus_timeout2_ahb_clk", +@@ -4429,10 +4429,10 @@ static struct clk_branch gcc_snoc_bus_ti + }; + + static struct clk_branch gcc_snoc_bus_timeout3_ahb_clk = { +- .halt_reg = 0x47014, ++ .halt_reg = 0x4701C, + .halt_bit = 31, + .clkr = { +- .enable_reg = 0x47014, ++ .enable_reg = 0x4701C, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_snoc_bus_timeout3_ahb_clk", diff --git a/target/linux/qualcommax/patches-6.6/0171-2-clk-qcom-ipq8074-Fix-gcc_blsp1_ahb_clk-properties.patch b/target/linux/qualcommax/patches-6.6/0171-2-clk-qcom-ipq8074-Fix-gcc_blsp1_ahb_clk-properties.patch new file mode 100644 index 00000000000000..a7abddd5fddf18 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0171-2-clk-qcom-ipq8074-Fix-gcc_blsp1_ahb_clk-properties.patch @@ -0,0 +1,41 @@ +From 52315bec6ed633b6a71f28b746029602f8bd70b9 Mon Sep 17 00:00:00 2001 +From: Balaji Prakash J +Date: Wed, 22 Apr 2020 20:35:30 +0530 +Subject: [PATCH] clk: ipq8074: fix gcc_blsp1_ahb_clk properties + +All the voting enabled clocks does not support the enable +from CBCR register. So, updated gcc_blsp1_ahb_clk enable +register and mask to enable bit in APCS_CLOCK_BRANCH_ENA_VOTE. + +Also, the voting controlled clocks are shared among multiple +components like APSS, RPM, NSS, TZ, etc. So, turning the +voting off from APSS does not make the clock off if it has +been voted from another component. Added the flag +BRANCH_HALT_VOTED in order to skip checking the clock +disable status. + +This change is referred from the below commits, +1. 246b4fb3af9bd65d8af794aac2f0e7b1ed9cc2dd +2. c8374157d5ae91d3b3e0d513d62808a798b32d3a + +Signed-off-by: Balaji Prakash J +Change-Id: I505cb560b31ad27a02c165fbe13bb33a2fc7d230 +--- + drivers/clk/qcom/gcc-ipq8074.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/clk/qcom/gcc-ipq8074.c ++++ b/drivers/clk/qcom/gcc-ipq8074.c +@@ -2125,9 +2125,10 @@ struct clk_rcg2 adss_pwm_clk_src = { + + static struct clk_branch gcc_blsp1_ahb_clk = { + .halt_reg = 0x01008, ++ .halt_check = BRANCH_HALT_VOTED, + .clkr = { +- .enable_reg = 0x01008, +- .enable_mask = BIT(0), ++ .enable_reg = 0x0b004, ++ .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ diff --git a/target/linux/qualcommax/patches-6.6/0600-1-qca-nss-ecm-support-CORE.patch b/target/linux/qualcommax/patches-6.6/0600-1-qca-nss-ecm-support-CORE.patch new file mode 100644 index 00000000000000..21006721e11666 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0600-1-qca-nss-ecm-support-CORE.patch @@ -0,0 +1,865 @@ +--- a/include/linux/if_bridge.h ++++ b/include/linux/if_bridge.h +@@ -71,6 +71,9 @@ void brioctl_set(int (*hook)(struct net + void __user *uarg)); + int br_ioctl_call(struct net *net, struct net_bridge *br, unsigned int cmd, + struct ifreq *ifr, void __user *uarg); ++extern void br_dev_update_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *nlstats); ++extern bool br_is_hairpin_enabled(struct net_device *dev); + + #if IS_ENABLED(CONFIG_BRIDGE) && IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING) + int br_multicast_list_adjacent(struct net_device *dev, +@@ -213,4 +216,42 @@ static inline clock_t br_get_ageing_time + } + #endif + ++/* QCA NSS ECM support - Start */ ++extern struct net_device *br_port_dev_get(struct net_device *dev, ++ unsigned char *addr, ++ struct sk_buff *skb, ++ unsigned int cookie); ++extern void br_refresh_fdb_entry(struct net_device *dev, const char *addr); ++extern void br_fdb_entry_refresh(struct net_device *dev, const char *addr, __u16 vid); ++extern struct net_bridge_fdb_entry *br_fdb_has_entry(struct net_device *dev, ++ const char *addr, ++ __u16 vid); ++extern void br_fdb_update_register_notify(struct notifier_block *nb); ++extern void br_fdb_update_unregister_notify(struct notifier_block *nb); ++ ++typedef struct net_bridge_port *br_port_dev_get_hook_t(struct net_device *dev, ++ struct sk_buff *skb, ++ unsigned char *addr, ++ unsigned int cookie); ++extern br_port_dev_get_hook_t __rcu *br_port_dev_get_hook; ++ ++#define BR_FDB_EVENT_ADD 0x01 ++#define BR_FDB_EVENT_DEL 0x02 ++ ++struct br_fdb_event { ++ struct net_device *dev; ++ unsigned char addr[6]; ++ unsigned char is_local; ++ struct net_bridge *br; ++ struct net_device *orig_dev; ++}; ++extern void br_fdb_register_notify(struct notifier_block *nb); ++extern void br_fdb_unregister_notify(struct notifier_block *nb); ++ ++typedef struct net_bridge_port *br_get_dst_hook_t( ++ const struct net_bridge_port *src, ++ struct sk_buff **skb); ++extern br_get_dst_hook_t __rcu *br_get_dst_hook; ++/* QCA NSS ECM support - End */ ++ + #endif +--- a/include/linux/if_vlan.h ++++ b/include/linux/if_vlan.h +@@ -143,7 +143,10 @@ extern struct net_device *__vlan_find_de + extern int vlan_for_each(struct net_device *dev, + int (*action)(struct net_device *dev, int vid, + void *arg), void *arg); ++extern void __vlan_dev_update_accel_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *stats); /* QCA NSS ECM support */ + extern struct net_device *vlan_dev_real_dev(const struct net_device *dev); ++extern struct net_device *vlan_dev_next_dev(const struct net_device *dev); /* QCA NSS ECM support */ + extern u16 vlan_dev_vlan_id(const struct net_device *dev); + extern __be16 vlan_dev_vlan_proto(const struct net_device *dev); + +@@ -236,6 +239,12 @@ extern void vlan_vids_del_by_dev(struct + extern bool vlan_uses_dev(const struct net_device *dev); + + #else ++static inline void __vlan_dev_update_accel_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *stats) ++{ ++ ++} /* QCA NSS ECM support */ ++ + static inline struct net_device * + __vlan_find_dev_deep_rcu(struct net_device *real_dev, + __be16 vlan_proto, u16 vlan_id) +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -2936,6 +2936,10 @@ enum netdev_cmd { + NETDEV_OFFLOAD_XSTATS_REPORT_USED, + NETDEV_OFFLOAD_XSTATS_REPORT_DELTA, + NETDEV_XDP_FEAT_CHANGE, ++ /* QCA NSS ECM Support - Start */ ++ NETDEV_BR_JOIN, ++ NETDEV_BR_LEAVE, ++ /* QCA NSS ECM Support - End */ + }; + const char *netdev_cmd_to_name(enum netdev_cmd cmd); + +--- a/include/net/ip6_route.h ++++ b/include/net/ip6_route.h +@@ -207,6 +207,11 @@ void rt6_multipath_rebalance(struct fib6 + void rt6_uncached_list_add(struct rt6_info *rt); + void rt6_uncached_list_del(struct rt6_info *rt); + ++/* QCA NSS ECM support - Start */ ++int rt6_register_notifier(struct notifier_block *nb); ++int rt6_unregister_notifier(struct notifier_block *nb); ++/* QCA NSS ECM support - End */ ++ + static inline const struct rt6_info *skb_rt6_info(const struct sk_buff *skb) + { + const struct dst_entry *dst = skb_dst(skb); +--- a/include/net/neighbour.h ++++ b/include/net/neighbour.h +@@ -249,6 +249,13 @@ static inline int neigh_parms_family(str + return p->tbl->family; + } + ++/* QCA NSS ECM support - Start */ ++struct neigh_mac_update { ++ unsigned char old_mac[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; ++ unsigned char update_mac[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; ++}; ++/* QCA NSS ECM support - End */ ++ + #define NEIGH_PRIV_ALIGN sizeof(long long) + #define NEIGH_ENTRY_SIZE(size) ALIGN((size), NEIGH_PRIV_ALIGN) + +@@ -395,6 +402,11 @@ void __neigh_for_each_release(struct nei + int (*cb)(struct neighbour *)); + int neigh_xmit(int fam, struct net_device *, const void *, struct sk_buff *); + ++/* QCA NSS ECM support - Start */ ++extern void neigh_mac_update_register_notify(struct notifier_block *nb); ++extern void neigh_mac_update_unregister_notify(struct notifier_block *nb); ++/* QCA NSS ECM support - End */ ++ + struct neigh_seq_state { + struct seq_net_private p; + struct neigh_table *tbl; +@@ -600,4 +612,5 @@ static inline void neigh_update_is_route + *notify = 1; + } + } ++ + #endif +--- a/include/net/route.h ++++ b/include/net/route.h +@@ -237,6 +237,11 @@ struct rtable *rt_dst_alloc(struct net_d + unsigned int flags, u16 type, bool noxfrm); + struct rtable *rt_dst_clone(struct net_device *dev, struct rtable *rt); + ++/* QCA NSS ECM support - Start */ ++int ip_rt_register_notifier(struct notifier_block *nb); ++int ip_rt_unregister_notifier(struct notifier_block *nb); ++/* QCA NSS ECM support - End */ ++ + struct in_ifaddr; + void fib_add_ifaddr(struct in_ifaddr *); + void fib_del_ifaddr(struct in_ifaddr *, struct in_ifaddr *); +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -2266,4 +2266,6 @@ void br_do_suppress_nd(struct sk_buff *s + u16 vid, struct net_bridge_port *p, struct nd_msg *msg); + struct nd_msg *br_is_nd_neigh_msg(struct sk_buff *skb, struct nd_msg *m); + bool br_is_neigh_suppress_enabled(const struct net_bridge_port *p, u16 vid); ++#define __br_get(__hook, __default, __args ...) \ ++ (__hook ? (__hook(__args)) : (__default)) /* QCA NSS ECM support */ + #endif +--- a/net/8021q/vlan_core.c ++++ b/net/8021q/vlan_core.c +@@ -72,6 +72,28 @@ bool vlan_do_receive(struct sk_buff **sk + return true; + } + ++/* QCA NSS ECM support - Start */ ++/* Update the VLAN device with statistics from network offload engines */ ++void __vlan_dev_update_accel_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *nlstats) ++{ ++ struct vlan_pcpu_stats *stats; ++ ++ if (!is_vlan_dev(dev)) ++ return; ++ ++ stats = per_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats, 0); ++ ++ u64_stats_update_begin(&stats->syncp); ++ u64_stats_add(&stats->rx_packets, nlstats->rx_packets); ++ u64_stats_add(&stats->rx_bytes, nlstats->rx_bytes); ++ u64_stats_add(&stats->tx_packets, nlstats->tx_packets); ++ u64_stats_add(&stats->tx_bytes, nlstats->tx_bytes); ++ u64_stats_update_end(&stats->syncp); ++} ++EXPORT_SYMBOL(__vlan_dev_update_accel_stats); ++/* QCA NSS ECM support - End */ ++ + /* Must be invoked with rcu_read_lock. */ + struct net_device *__vlan_find_dev_deep_rcu(struct net_device *dev, + __be16 vlan_proto, u16 vlan_id) +@@ -110,6 +132,15 @@ struct net_device *vlan_dev_real_dev(con + } + EXPORT_SYMBOL(vlan_dev_real_dev); + ++/* QCA NSS ECM support - Start */ ++/* Caller is responsible to hold the reference of the returned device */ ++struct net_device *vlan_dev_next_dev(const struct net_device *dev) ++{ ++ return vlan_dev_priv(dev)->real_dev; ++} ++EXPORT_SYMBOL(vlan_dev_next_dev); ++/* QCA NSS ECM support - End */ ++ + u16 vlan_dev_vlan_id(const struct net_device *dev) + { + return vlan_dev_priv(dev)->vlan_id; +--- a/net/bridge/br_fdb.c ++++ b/net/bridge/br_fdb.c +@@ -33,6 +33,20 @@ static const struct rhashtable_params br + + static struct kmem_cache *br_fdb_cache __read_mostly; + ++ATOMIC_NOTIFIER_HEAD(br_fdb_notifier_list); ++ ++void br_fdb_register_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_register(&br_fdb_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(br_fdb_register_notify); ++ ++void br_fdb_unregister_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_unregister(&br_fdb_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(br_fdb_unregister_notify); ++ + int __init br_fdb_init(void) + { + br_fdb_cache = kmem_cache_create("bridge_fdb_cache", +@@ -195,6 +209,25 @@ static void fdb_notify(struct net_bridge + if (swdev_notify) + br_switchdev_fdb_notify(br, fdb, type); + ++ /* QCA NSS ECM support - Start */ ++ if (fdb->dst) { ++ int event; ++ struct br_fdb_event fdb_event; ++ ++ if (type == RTM_NEWNEIGH) ++ event = BR_FDB_EVENT_ADD; ++ else ++ event = BR_FDB_EVENT_DEL; ++ ++ fdb_event.dev = fdb->dst->dev; ++ ether_addr_copy(fdb_event.addr, fdb->key.addr.addr); ++ fdb_event.is_local = test_bit(BR_FDB_LOCAL, &fdb->flags); ++ atomic_notifier_call_chain(&br_fdb_notifier_list, ++ event, ++ (void *)&fdb_event); ++ } ++ /* QCA NSS ECM support - End */ ++ + skb = nlmsg_new(fdb_nlmsg_size(), GFP_ATOMIC); + if (skb == NULL) + goto errout; +@@ -519,6 +552,22 @@ out: + spin_unlock_bh(&br->hash_lock); + } + ++/* QCA NSS ECM support - Start */ ++ATOMIC_NOTIFIER_HEAD(br_fdb_update_notifier_list); ++ ++void br_fdb_update_register_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_register(&br_fdb_update_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(br_fdb_update_register_notify); ++ ++void br_fdb_update_unregister_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_unregister(&br_fdb_update_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(br_fdb_update_unregister_notify); ++/* QCA NSS ECM support - End */ ++ + void br_fdb_cleanup(struct work_struct *work) + { + struct net_bridge *br = container_of(work, struct net_bridge, +@@ -527,6 +576,7 @@ void br_fdb_cleanup(struct work_struct * + unsigned long delay = hold_time(br); + unsigned long work_delay = delay; + unsigned long now = jiffies; ++ u8 mac_addr[6]; /* QCA NSS ECM support */ + + /* this part is tricky, in order to avoid blocking learning and + * consequently forwarding, we rely on rcu to delete objects with +@@ -553,8 +603,15 @@ void br_fdb_cleanup(struct work_struct * + work_delay = min(work_delay, this_timer - now); + } else { + spin_lock_bh(&br->hash_lock); +- if (!hlist_unhashed(&f->fdb_node)) ++ if (!hlist_unhashed(&f->fdb_node)) { ++ ether_addr_copy(mac_addr, f->key.addr.addr); + fdb_delete(br, f, true); ++ /* QCA NSS ECM support - Start */ ++ atomic_notifier_call_chain( ++ &br_fdb_update_notifier_list, 0, ++ (void *)mac_addr); ++ /* QCA NSS ECM support - End */ ++ } + spin_unlock_bh(&br->hash_lock); + } + } +@@ -891,6 +948,12 @@ void br_fdb_update(struct net_bridge *br + */ + if (unlikely(test_bit(BR_FDB_LOCKED, &fdb->flags))) + clear_bit(BR_FDB_LOCKED, &fdb->flags); ++ ++ /* QCA NSS ECM support - Start */ ++ atomic_notifier_call_chain( ++ &br_fdb_update_notifier_list, ++ 0, (void *)addr); ++ /* QCA NSS ECM support - End */ + } + + if (unlikely(test_bit(BR_FDB_ADDED_BY_USER, &flags))) +@@ -914,6 +977,64 @@ void br_fdb_update(struct net_bridge *br + } + } + ++/* QCA NSS ECM support - Start */ ++/* Refresh FDB entries for bridge packets being forwarded by offload engines */ ++void br_refresh_fdb_entry(struct net_device *dev, const char *addr) ++{ ++ struct net_bridge_port *p = br_port_get_rcu(dev); ++ ++ if (!p || p->state == BR_STATE_DISABLED) ++ return; ++ ++ if (!is_valid_ether_addr(addr)) { ++ pr_info("bridge: Attempt to refresh with invalid ether address %pM\n", ++ addr); ++ return; ++ } ++ ++ rcu_read_lock(); ++ br_fdb_update(p->br, p, addr, 0, true); ++ rcu_read_unlock(); ++} ++EXPORT_SYMBOL_GPL(br_refresh_fdb_entry); ++ ++/* Update timestamp of FDB entries for bridge packets being forwarded by offload engines */ ++void br_fdb_entry_refresh(struct net_device *dev, const char *addr, __u16 vid) ++{ ++ struct net_bridge_fdb_entry *fdb; ++ struct net_bridge_port *p = br_port_get_rcu(dev); ++ ++ if (!p || p->state == BR_STATE_DISABLED) ++ return; ++ ++ rcu_read_lock(); ++ fdb = fdb_find_rcu(&p->br->fdb_hash_tbl, addr, vid); ++ if (likely(fdb)) { ++ fdb->updated = jiffies; ++ } ++ rcu_read_unlock(); ++} ++EXPORT_SYMBOL_GPL(br_fdb_entry_refresh); ++ ++/* Look up the MAC address in the device's bridge fdb table */ ++struct net_bridge_fdb_entry *br_fdb_has_entry(struct net_device *dev, ++ const char *addr, __u16 vid) ++{ ++ struct net_bridge_port *p = br_port_get_rcu(dev); ++ struct net_bridge_fdb_entry *fdb; ++ ++ if (!p || p->state == BR_STATE_DISABLED) ++ return NULL; ++ ++ rcu_read_lock(); ++ fdb = fdb_find_rcu(&p->br->fdb_hash_tbl, addr, vid); ++ rcu_read_unlock(); ++ ++ return fdb; ++} ++EXPORT_SYMBOL_GPL(br_fdb_has_entry); ++ ++/* QCA NSS ECM support - End */ + /* Dump information about entries, in response to GETNEIGH */ + int br_fdb_dump(struct sk_buff *skb, + struct netlink_callback *cb, +--- a/net/bridge/br_if.c ++++ b/net/bridge/br_if.c +@@ -26,6 +26,12 @@ + + #include "br_private.h" + ++/* QCA NSS ECM support - Start */ ++/* Hook for external forwarding logic */ ++br_port_dev_get_hook_t __rcu *br_port_dev_get_hook __read_mostly; ++EXPORT_SYMBOL_GPL(br_port_dev_get_hook); ++/* QCA NSS ECM support - End */ ++ + /* + * Determine initial path cost based on speed. + * using recommendations from 802.1d standard +@@ -697,6 +703,8 @@ int br_add_if(struct net_bridge *br, str + + kobject_uevent(&p->kobj, KOBJ_ADD); + ++ call_netdevice_notifiers(NETDEV_BR_JOIN, dev); /* QCA NSS ECM support */ ++ + return 0; + + err6: +@@ -732,6 +740,8 @@ int br_del_if(struct net_bridge *br, str + if (!p || p->br != br) + return -EINVAL; + ++ call_netdevice_notifiers(NETDEV_BR_LEAVE, dev); /* QCA NSS ECM support */ ++ + /* Since more than one interface can be attached to a bridge, + * there still maybe an alternate path for netconsole to use; + * therefore there is no reason for a NETDEV_RELEASE event. +@@ -775,3 +785,97 @@ bool br_port_flag_is_set(const struct ne + return p->flags & flag; + } + EXPORT_SYMBOL_GPL(br_port_flag_is_set); ++ ++/* br_port_dev_get() ++ * If a skb is provided, and the br_port_dev_get_hook_t hook exists, ++ * use that to try and determine the egress port for that skb. ++ * If not, or no egress port could be determined, use the given addr ++ * to identify the port to which it is reachable, ++ * returing a reference to the net device associated with that port. ++ * ++ * NOTE: Return NULL if given dev is not a bridge or the mac has no ++ * associated port. ++ */ ++struct net_device *br_port_dev_get(struct net_device *dev, unsigned char *addr, ++ struct sk_buff *skb, ++ unsigned int cookie) ++{ ++ struct net_bridge_fdb_entry *fdbe; ++ struct net_bridge *br; ++ struct net_device *netdev = NULL; ++ ++ /* Is this a bridge? */ ++ if (!(dev->priv_flags & IFF_EBRIDGE)) ++ return NULL; ++ ++ rcu_read_lock(); ++ ++ /* If the hook exists and the skb isn't NULL, try and get the port */ ++ if (skb) { ++ br_port_dev_get_hook_t *port_dev_get_hook; ++ ++ port_dev_get_hook = rcu_dereference(br_port_dev_get_hook); ++ if (port_dev_get_hook) { ++ struct net_bridge_port *pdst = ++ __br_get(port_dev_get_hook, NULL, dev, skb, ++ addr, cookie); ++ if (pdst) { ++ dev_hold(pdst->dev); ++ netdev = pdst->dev; ++ goto out; ++ } ++ } ++ } ++ ++ /* Either there is no hook, or can't ++ * determine the port to use - fall back to using FDB ++ */ ++ ++ br = netdev_priv(dev); ++ ++ /* Lookup the fdb entry and get reference to the port dev */ ++ fdbe = br_fdb_find_rcu(br, addr, 0); ++ if (fdbe && fdbe->dst) { ++ netdev = fdbe->dst->dev; /* port device */ ++ dev_hold(netdev); ++ } ++out: ++ rcu_read_unlock(); ++ return netdev; ++} ++EXPORT_SYMBOL_GPL(br_port_dev_get); ++ ++/* Update bridge statistics for bridge packets processed by offload engines */ ++void br_dev_update_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *nlstats) ++{ ++ struct pcpu_sw_netstats *tstats; ++ ++ /* Is this a bridge? */ ++ if (!(dev->priv_flags & IFF_EBRIDGE)) ++ return; ++ ++ tstats = this_cpu_ptr(dev->tstats); ++ ++ u64_stats_update_begin(&tstats->syncp); ++ u64_stats_add(&tstats->rx_packets, nlstats->rx_packets); ++ u64_stats_add(&tstats->rx_bytes, nlstats->rx_bytes); ++ u64_stats_add(&tstats->tx_packets, nlstats->tx_packets); ++ u64_stats_add(&tstats->tx_bytes, nlstats->tx_bytes); ++ u64_stats_update_end(&tstats->syncp); ++} ++EXPORT_SYMBOL_GPL(br_dev_update_stats); ++ ++/* QCA NSS ECM support - Start */ ++/* API to know if hairpin feature is enabled/disabled on this bridge port */ ++bool br_is_hairpin_enabled(struct net_device *dev) ++{ ++ struct net_bridge_port *port = br_port_get_check_rcu(dev); ++ ++ if (likely(port)) ++ return port->flags & BR_HAIRPIN_MODE; ++ return false; ++} ++EXPORT_SYMBOL_GPL(br_is_hairpin_enabled); ++ ++/* QCA NSS ECM support - End */ +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -1275,6 +1275,22 @@ static void neigh_update_hhs(struct neig + } + } + ++/* QCA NSS ECM support - Start */ ++ATOMIC_NOTIFIER_HEAD(neigh_mac_update_notifier_list); ++ ++void neigh_mac_update_register_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_register(&neigh_mac_update_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(neigh_mac_update_register_notify); ++ ++void neigh_mac_update_unregister_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_unregister(&neigh_mac_update_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(neigh_mac_update_unregister_notify); ++/* QCA NSS ECM support - End */ ++ + /* Generic update routine. + -- lladdr is new lladdr or NULL, if it is not supplied. + -- new is new state. +@@ -1303,6 +1319,7 @@ static int __neigh_update(struct neighbo + struct net_device *dev; + int err, notify = 0; + u8 old; ++ struct neigh_mac_update nmu; /* QCA NSS ECM support */ + + trace_neigh_update(neigh, lladdr, new, flags, nlmsg_pid); + +@@ -1317,7 +1334,10 @@ static int __neigh_update(struct neighbo + new = old; + goto out; + } +- if (!(flags & NEIGH_UPDATE_F_ADMIN) && ++ ++ memset(&nmu, 0, sizeof(struct neigh_mac_update)); /* QCA NSS ECM support */ ++ ++ if (!(flags & NEIGH_UPDATE_F_ADMIN) && + (old & (NUD_NOARP | NUD_PERMANENT))) + goto out; + +@@ -1354,7 +1374,12 @@ static int __neigh_update(struct neighbo + - compare new & old + - if they are different, check override flag + */ +- if ((old & NUD_VALID) && ++ /* QCA NSS ECM update - Start */ ++ memcpy(nmu.old_mac, neigh->ha, dev->addr_len); ++ memcpy(nmu.update_mac, lladdr, dev->addr_len); ++ /* QCA NSS ECM update - End */ ++ ++ if ((old & NUD_VALID) && + !memcmp(lladdr, neigh->ha, dev->addr_len)) + lladdr = neigh->ha; + } else { +@@ -1476,8 +1501,11 @@ out: + neigh_update_gc_list(neigh); + if (managed_update) + neigh_update_managed_list(neigh); +- if (notify) ++ if (notify) { + neigh_update_notify(neigh, nlmsg_pid); ++ atomic_notifier_call_chain(&neigh_mac_update_notifier_list, 0, ++ (struct neigh_mac_update *)&nmu); /* QCA NSS ECM support */ ++ } + trace_neigh_update_done(neigh, err); + return err; + } +--- a/net/ipv4/fib_trie.c ++++ b/net/ipv4/fib_trie.c +@@ -1211,6 +1211,9 @@ static bool fib_valid_key_len(u32 key, u + static void fib_remove_alias(struct trie *t, struct key_vector *tp, + struct key_vector *l, struct fib_alias *old); + ++/* Define route change notification chain. */ ++static BLOCKING_NOTIFIER_HEAD(iproute_chain); /* QCA NSS ECM support */ ++ + /* Caller must hold RTNL. */ + int fib_table_insert(struct net *net, struct fib_table *tb, + struct fib_config *cfg, struct netlink_ext_ack *extack) +@@ -1404,6 +1407,9 @@ int fib_table_insert(struct net *net, st + rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, new_fa->tb_id, + &cfg->fc_nlinfo, nlflags); + succeeded: ++ blocking_notifier_call_chain(&iproute_chain, ++ RTM_NEWROUTE, fi); ++ + return 0; + + out_remove_new_fa: +@@ -1775,6 +1781,9 @@ int fib_table_delete(struct net *net, st + if (fa_to_delete->fa_state & FA_S_ACCESSED) + rt_cache_flush(cfg->fc_nlinfo.nl_net); + ++ blocking_notifier_call_chain(&iproute_chain, ++ RTM_DELROUTE, fa_to_delete->fa_info); ++ + fib_release_info(fa_to_delete->fa_info); + alias_free_mem_rcu(fa_to_delete); + return 0; +@@ -2407,6 +2416,20 @@ void __init fib_trie_init(void) + 0, SLAB_PANIC | SLAB_ACCOUNT, NULL); + } + ++/* QCA NSS ECM support - Start */ ++int ip_rt_register_notifier(struct notifier_block *nb) ++{ ++ return blocking_notifier_chain_register(&iproute_chain, nb); ++} ++EXPORT_SYMBOL(ip_rt_register_notifier); ++ ++int ip_rt_unregister_notifier(struct notifier_block *nb) ++{ ++ return blocking_notifier_chain_unregister(&iproute_chain, nb); ++} ++EXPORT_SYMBOL(ip_rt_unregister_notifier); ++/* QCA NSS ECM support - End */ ++ + struct fib_table *fib_trie_table(u32 id, struct fib_table *alias) + { + struct fib_table *tb; +--- a/net/ipv6/ndisc.c ++++ b/net/ipv6/ndisc.c +@@ -666,6 +666,7 @@ void ndisc_send_ns(struct net_device *de + if (skb) + ndisc_send_skb(skb, daddr, saddr); + } ++EXPORT_SYMBOL(ndisc_send_ns); + + void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr, + const struct in6_addr *daddr) +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -197,6 +197,9 @@ static void rt6_uncached_list_flush_dev( + } + } + ++/* Define route change notification chain. */ ++ATOMIC_NOTIFIER_HEAD(ip6route_chain); /* QCA NSS ECM support */ ++ + static inline const void *choose_neigh_daddr(const struct in6_addr *p, + struct sk_buff *skb, + const void *daddr) +@@ -3864,6 +3867,10 @@ int ip6_route_add(struct fib6_config *cf + return PTR_ERR(rt); + + err = __ip6_ins_rt(rt, &cfg->fc_nlinfo, extack); ++ if (!err) ++ atomic_notifier_call_chain(&ip6route_chain, ++ RTM_NEWROUTE, rt); ++ + fib6_info_release(rt); + + return err; +@@ -3885,6 +3892,9 @@ static int __ip6_del_rt(struct fib6_info + err = fib6_del(rt, info); + spin_unlock_bh(&table->tb6_lock); + ++ if (!err) ++ atomic_notifier_call_chain(&ip6route_chain, ++ RTM_DELROUTE, rt); + out: + fib6_info_release(rt); + return err; +@@ -6329,6 +6339,20 @@ static int ip6_route_dev_notify(struct n + return NOTIFY_OK; + } + ++/* QCA NSS ECM support - Start */ ++int rt6_register_notifier(struct notifier_block *nb) ++{ ++ return atomic_notifier_chain_register(&ip6route_chain, nb); ++} ++EXPORT_SYMBOL(rt6_register_notifier); ++ ++int rt6_unregister_notifier(struct notifier_block *nb) ++{ ++ return atomic_notifier_chain_unregister(&ip6route_chain, nb); ++} ++EXPORT_SYMBOL(rt6_unregister_notifier); ++/* QCA NSS ECM support - End */ ++ + /* + * /proc + */ +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -1673,6 +1673,7 @@ const char *netdev_cmd_to_name(enum netd + N(PRE_CHANGEADDR) N(OFFLOAD_XSTATS_ENABLE) N(OFFLOAD_XSTATS_DISABLE) + N(OFFLOAD_XSTATS_REPORT_USED) N(OFFLOAD_XSTATS_REPORT_DELTA) + N(XDP_FEAT_CHANGE) ++ N(BR_JOIN) N(BR_LEAVE) + } + #undef N + return "UNKNOWN_NETDEV_EVENT"; +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -1002,6 +1002,7 @@ void inet6_ifa_finish_destroy(struct ine + + kfree_rcu(ifp, rcu); + } ++EXPORT_SYMBOL(inet6_ifa_finish_destroy); + + static void + ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) +--- a/include/net/vxlan.h ++++ b/include/net/vxlan.h +@@ -440,6 +440,15 @@ static inline __be32 vxlan_compute_rco(u + return vni_field; + } + ++/* ++ * vxlan_get_vni() ++ * Returns the vni corresponding to tunnel ++ */ ++static inline u32 vxlan_get_vni(struct vxlan_dev *vxlan_tun) ++{ ++ return be32_to_cpu(vxlan_tun->cfg.vni); ++} ++ + static inline unsigned short vxlan_get_sk_family(struct vxlan_sock *vs) + { + return vs->sock->sk->sk_family; +--- a/include/uapi/linux/in.h ++++ b/include/uapi/linux/in.h +@@ -63,6 +63,8 @@ enum { + #define IPPROTO_MTP IPPROTO_MTP + IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */ + #define IPPROTO_BEETPH IPPROTO_BEETPH ++ IPPROTO_ETHERIP = 97, /* ETHERIP protocol number */ ++#define IPPROTO_ETHERIP IPPROTO_ETHERIP + IPPROTO_ENCAP = 98, /* Encapsulation Header */ + #define IPPROTO_ENCAP IPPROTO_ENCAP + IPPROTO_PIM = 103, /* Protocol Independent Multicast */ +@@ -327,7 +329,7 @@ struct sockaddr_in { + #endif + + /* contains the htonl type stuff.. */ +-#include ++#include + + + #endif /* _UAPI_LINUX_IN_H */ +--- a/tools/include/uapi/linux/in.h ++++ b/tools/include/uapi/linux/in.h +@@ -63,6 +63,8 @@ enum { + #define IPPROTO_MTP IPPROTO_MTP + IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */ + #define IPPROTO_BEETPH IPPROTO_BEETPH ++ IPPROTO_ETHERIP = 97, /* ETHERIP protocol number */ ++#define IPPROTO_ETHERIP IPPROTO_ETHERIP + IPPROTO_ENCAP = 98, /* Encapsulation Header */ + #define IPPROTO_ENCAP IPPROTO_ENCAP + IPPROTO_PIM = 103, /* Protocol Independent Multicast */ +@@ -327,7 +329,7 @@ struct sockaddr_in { + #endif + + /* contains the htonl type stuff.. */ +-#include ++#include + + + #endif /* _UAPI_LINUX_IN_H */ +--- a/include/net/netns/conntrack.h ++++ b/include/net/netns/conntrack.h +@@ -26,6 +26,7 @@ struct nf_tcp_net { + unsigned int timeouts[TCP_CONNTRACK_TIMEOUT_MAX]; + u8 tcp_loose; + u8 tcp_be_liberal; ++ u8 tcp_no_window_check; + u8 tcp_max_retrans; + u8 tcp_ignore_invalid_rst; + #if IS_ENABLED(CONFIG_NF_FLOW_TABLE) +--- a/net/netfilter/nf_conntrack_proto_tcp.c ++++ b/net/netfilter/nf_conntrack_proto_tcp.c +@@ -515,11 +515,15 @@ tcp_in_window(struct nf_conn *ct, enum i + struct ip_ct_tcp *state = &ct->proto.tcp; + struct ip_ct_tcp_state *sender = &state->seen[dir]; + struct ip_ct_tcp_state *receiver = &state->seen[!dir]; ++ const struct nf_tcp_net *tn = nf_tcp_pernet(nf_ct_net(ct)); + __u32 seq, ack, sack, end, win, swin; + bool in_recv_win, seq_ok; + s32 receiver_offset; + u16 win_raw; + ++ if (tn->tcp_no_window_check) ++ return NFCT_TCP_ACCEPT; ++ + /* + * Get the required data from the packet. + */ +@@ -1285,7 +1289,7 @@ int nf_conntrack_tcp_packet(struct nf_co + IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED && + timeouts[new_state] > timeouts[TCP_CONNTRACK_UNACK]) + timeout = timeouts[TCP_CONNTRACK_UNACK]; +- else if (ct->proto.tcp.last_win == 0 && ++ else if (!tn->tcp_no_window_check && ct->proto.tcp.last_win == 0 && + timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS]) + timeout = timeouts[TCP_CONNTRACK_RETRANS]; + else +@@ -1601,6 +1605,9 @@ void nf_conntrack_tcp_init_net(struct ne + */ + tn->tcp_be_liberal = 0; + ++ /* Skip Windows Check */ ++ tn->tcp_no_window_check = 0; ++ + /* If it's non-zero, we turn off RST sequence number check */ + tn->tcp_ignore_invalid_rst = 0; + +--- a/net/netfilter/nf_conntrack_standalone.c ++++ b/net/netfilter/nf_conntrack_standalone.c +@@ -633,6 +633,7 @@ enum nf_ct_sysctl_index { + #endif + NF_SYSCTL_CT_PROTO_TCP_LOOSE, + NF_SYSCTL_CT_PROTO_TCP_LIBERAL, ++ NF_SYSCTL_CT_PROTO_TCP_NO_WINDOW_CHECK, + NF_SYSCTL_CT_PROTO_TCP_IGNORE_INVALID_RST, + NF_SYSCTL_CT_PROTO_TCP_MAX_RETRANS, + NF_SYSCTL_CT_PROTO_TIMEOUT_UDP, +@@ -840,6 +841,14 @@ static struct ctl_table nf_ct_sysctl_tab + .extra1 = SYSCTL_ZERO, + .extra2 = SYSCTL_ONE, + }, ++ [NF_SYSCTL_CT_PROTO_TCP_NO_WINDOW_CHECK] = { ++ .procname = "nf_conntrack_tcp_no_window_check", ++ .maxlen = sizeof(u8), ++ .mode = 0644, ++ .proc_handler = proc_dou8vec_minmax, ++ .extra1 = SYSCTL_ZERO, ++ .extra2 = SYSCTL_ONE, ++ }, + [NF_SYSCTL_CT_PROTO_TCP_IGNORE_INVALID_RST] = { + .procname = "nf_conntrack_tcp_ignore_invalid_rst", + .maxlen = sizeof(u8), +@@ -1050,6 +1059,7 @@ static void nf_conntrack_standalone_init + + XASSIGN(LOOSE, &tn->tcp_loose); + XASSIGN(LIBERAL, &tn->tcp_be_liberal); ++ XASSIGN(NO_WINDOW_CHECK, &tn->tcp_no_window_check); + XASSIGN(MAX_RETRANS, &tn->tcp_max_retrans); + XASSIGN(IGNORE_INVALID_RST, &tn->tcp_ignore_invalid_rst); + #undef XASSIGN diff --git a/target/linux/qualcommax/patches-6.6/0600-2-qca-nss-ecm-support-CORE-Fix-IPv6-user-route-change-event-calls.patch b/target/linux/qualcommax/patches-6.6/0600-2-qca-nss-ecm-support-CORE-Fix-IPv6-user-route-change-event-calls.patch new file mode 100644 index 00000000000000..e3081a79aafdbe --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0600-2-qca-nss-ecm-support-CORE-Fix-IPv6-user-route-change-event-calls.patch @@ -0,0 +1,87 @@ +From ce18a6fdff6a39a01111d74f513d2ef66142047c Mon Sep 17 00:00:00 2001 +From: Murat Sezgin +Date: Wed, 5 Aug 2020 13:21:27 -0700 +Subject: [PATCH 246/281] net:ipv6: Fix IPv6 user route change event calls + +These events should be called only when the route table is +changed by the userspace. So, we should call them in the +ioctl and the netlink message handler function. + +Change-Id: If7ec615014cfc79d5fa72878e49eaf99c2560c32 +Signed-off-by: Murat Sezgin +--- + net/ipv6/route.c | 31 +++++++++++++++++++++---------- + 1 file changed, 21 insertions(+), 10 deletions(-) + +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -3867,10 +3867,6 @@ int ip6_route_add(struct fib6_config *cf + return PTR_ERR(rt); + + err = __ip6_ins_rt(rt, &cfg->fc_nlinfo, extack); +- if (!err) +- atomic_notifier_call_chain(&ip6route_chain, +- RTM_NEWROUTE, rt); +- + fib6_info_release(rt); + + return err; +@@ -3892,9 +3888,6 @@ static int __ip6_del_rt(struct fib6_info + err = fib6_del(rt, info); + spin_unlock_bh(&table->tb6_lock); + +- if (!err) +- atomic_notifier_call_chain(&ip6route_chain, +- RTM_DELROUTE, rt); + out: + fib6_info_release(rt); + return err; +@@ -4500,6 +4493,10 @@ int ipv6_route_ioctl(struct net *net, un + break; + } + rtnl_unlock(); ++ if (!err) ++ atomic_notifier_call_chain(&ip6route_chain, ++ (cmd == SIOCADDRT) ? RTM_NEWROUTE : RTM_DELROUTE, &cfg); ++ + return err; + } + +@@ -5518,11 +5515,17 @@ static int inet6_rtm_delroute(struct sk_ + } + + if (cfg.fc_mp) +- return ip6_route_multipath_del(&cfg, extack); ++ err = ip6_route_multipath_del(&cfg, extack); + else { + cfg.fc_delete_all_nh = 1; +- return ip6_route_del(&cfg, extack); ++ err = ip6_route_del(&cfg, extack); + } ++ ++ if (!err) ++ atomic_notifier_call_chain(&ip6route_chain, ++ RTM_DELROUTE, &cfg); ++ ++ return err; + } + + static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, +@@ -5539,9 +5542,15 @@ static int inet6_rtm_newroute(struct sk_ + cfg.fc_metric = IP6_RT_PRIO_USER; + + if (cfg.fc_mp) +- return ip6_route_multipath_add(&cfg, extack); ++ err = ip6_route_multipath_add(&cfg, extack); + else +- return ip6_route_add(&cfg, GFP_KERNEL, extack); ++ err = ip6_route_add(&cfg, GFP_KERNEL, extack); ++ ++ if (!err) ++ atomic_notifier_call_chain(&ip6route_chain, ++ RTM_NEWROUTE, &cfg); ++ ++ return err; + } + + /* add the overhead of this fib6_nh to nexthop_len */ diff --git a/target/linux/qualcommax/patches-6.6/0600-2-qca-nss-ecm-support-PPPOE-offload.patch b/target/linux/qualcommax/patches-6.6/0600-2-qca-nss-ecm-support-PPPOE-offload.patch new file mode 100644 index 00000000000000..e59290878db29e --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0600-2-qca-nss-ecm-support-PPPOE-offload.patch @@ -0,0 +1,600 @@ +--- a/drivers/net/ppp/ppp_generic.c ++++ b/drivers/net/ppp/ppp_generic.c +@@ -48,6 +48,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -254,6 +255,25 @@ struct ppp_net { + #define seq_before(a, b) ((s32)((a) - (b)) < 0) + #define seq_after(a, b) ((s32)((a) - (b)) > 0) + ++ ++/* ++ * Registration/Unregistration methods ++ * for PPP channel connect and disconnect event notifications. ++ */ ++RAW_NOTIFIER_HEAD(ppp_channel_connection_notifier_list); ++ ++void ppp_channel_connection_register_notify(struct notifier_block *nb) ++{ ++ raw_notifier_chain_register(&ppp_channel_connection_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(ppp_channel_connection_register_notify); ++ ++void ppp_channel_connection_unregister_notify(struct notifier_block *nb) ++{ ++ raw_notifier_chain_unregister(&ppp_channel_connection_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(ppp_channel_connection_unregister_notify); ++ + /* Prototypes. */ + static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf, + struct file *file, unsigned int cmd, unsigned long arg); +@@ -3453,7 +3473,10 @@ ppp_connect_channel(struct channel *pch, + struct ppp_net *pn; + int ret = -ENXIO; + int hdrlen; ++ int ppp_proto; ++ int version; + ++ int notify = 0; + pn = ppp_pernet(pch->chan_net); + + mutex_lock(&pn->all_ppp_mutex); +@@ -3485,13 +3508,40 @@ ppp_connect_channel(struct channel *pch, + ++ppp->n_channels; + pch->ppp = ppp; + refcount_inc(&ppp->file.refcnt); ++ ++ /* Set the netdev priv flag if the prototype ++ * is L2TP or PPTP. Return success in all cases ++ */ ++ if (!pch->chan) ++ goto out2; ++ ++ ppp_proto = ppp_channel_get_protocol(pch->chan); ++ if (ppp_proto == PX_PROTO_PPTP) { ++ ppp->dev->priv_flags_ext |= IFF_EXT_PPP_PPTP; ++ } else if (ppp_proto == PX_PROTO_OL2TP) { ++ version = ppp_channel_get_proto_version(pch->chan); ++ if (version == 2) ++ ppp->dev->priv_flags_ext |= IFF_EXT_PPP_L2TPV2; ++ else if (version == 3) ++ ppp->dev->priv_flags_ext |= IFF_EXT_PPP_L2TPV3; ++ } ++ notify = 1; ++ ++ out2: + ppp_unlock(ppp); + ret = 0; +- + outl: + write_unlock_bh(&pch->upl); + out: + mutex_unlock(&pn->all_ppp_mutex); ++ ++ if (notify && ppp && ppp->dev) { ++ dev_hold(ppp->dev); ++ raw_notifier_call_chain(&ppp_channel_connection_notifier_list, ++ PPP_CHANNEL_CONNECT, ppp->dev); ++ dev_put(ppp->dev); ++ } ++ + return ret; + } + +@@ -3509,6 +3559,13 @@ ppp_disconnect_channel(struct channel *p + pch->ppp = NULL; + write_unlock_bh(&pch->upl); + if (ppp) { ++ if (ppp->dev) { ++ dev_hold(ppp->dev); ++ raw_notifier_call_chain(&ppp_channel_connection_notifier_list, ++ PPP_CHANNEL_DISCONNECT, ppp->dev); ++ dev_put(ppp->dev); ++ } ++ + /* remove it from the ppp unit's list */ + ppp_lock(ppp); + list_del(&pch->clist); +@@ -3588,6 +3645,222 @@ static void *unit_find(struct idr *p, in + return idr_find(p, n); + } + ++/* Updates the PPP interface statistics. */ ++void ppp_update_stats(struct net_device *dev, unsigned long rx_packets, ++ unsigned long rx_bytes, unsigned long tx_packets, ++ unsigned long tx_bytes, unsigned long rx_errors, ++ unsigned long tx_errors, unsigned long rx_dropped, ++ unsigned long tx_dropped) ++{ ++ struct ppp *ppp; ++ ++ if (!dev) ++ return; ++ ++ if (dev->type != ARPHRD_PPP) ++ return; ++ ++ ppp = netdev_priv(dev); ++ ++ ppp_xmit_lock(ppp); ++ ppp->stats64.tx_packets += tx_packets; ++ ppp->stats64.tx_bytes += tx_bytes; ++ ppp->dev->stats.tx_errors += tx_errors; ++ ppp->dev->stats.tx_dropped += tx_dropped; ++ if (tx_packets) ++ ppp->last_xmit = jiffies; ++ ppp_xmit_unlock(ppp); ++ ++ ppp_recv_lock(ppp); ++ ppp->stats64.rx_packets += rx_packets; ++ ppp->stats64.rx_bytes += rx_bytes; ++ ppp->dev->stats.rx_errors += rx_errors; ++ ppp->dev->stats.rx_dropped += rx_dropped; ++ if (rx_packets) ++ ppp->last_recv = jiffies; ++ ppp_recv_unlock(ppp); ++} ++ ++/* Returns >0 if the device is a multilink PPP netdevice, 0 if not or < 0 if ++ * the device is not PPP. ++ */ ++int ppp_is_multilink(struct net_device *dev) ++{ ++ struct ppp *ppp; ++ unsigned int flags; ++ ++ if (!dev) ++ return -1; ++ ++ if (dev->type != ARPHRD_PPP) ++ return -1; ++ ++ ppp = netdev_priv(dev); ++ ppp_lock(ppp); ++ flags = ppp->flags; ++ ppp_unlock(ppp); ++ ++ if (flags & SC_MULTILINK) ++ return 1; ++ ++ return 0; ++} ++EXPORT_SYMBOL(ppp_is_multilink); ++ ++/* ppp_channel_get_protocol() ++ * Call this to obtain the underlying protocol of the PPP channel, ++ * e.g. PX_PROTO_OE ++ * ++ * NOTE: Some channels do not use PX sockets so the protocol value may be very ++ * different for them. ++ * NOTE: -1 indicates failure. ++ * NOTE: Once you know the channel protocol you may then either cast 'chan' to ++ * its sub-class or use the channel protocol specific API's as provided by that ++ * channel sub type. ++ */ ++int ppp_channel_get_protocol(struct ppp_channel *chan) ++{ ++ if (!chan->ops->get_channel_protocol) ++ return -1; ++ ++ return chan->ops->get_channel_protocol(chan); ++} ++EXPORT_SYMBOL(ppp_channel_get_protocol); ++ ++/* ppp_channel_get_proto_version() ++ * Call this to get channel protocol version ++ */ ++int ppp_channel_get_proto_version(struct ppp_channel *chan) ++{ ++ if (!chan->ops->get_channel_protocol_ver) ++ return -1; ++ ++ return chan->ops->get_channel_protocol_ver(chan); ++} ++EXPORT_SYMBOL(ppp_channel_get_proto_version); ++ ++/* ppp_channel_hold() ++ * Call this to hold a channel. ++ * ++ * Returns true on success or false if the hold could not happen. ++ * ++ * NOTE: chan must be protected against destruction during this call - ++ * either by correct locking etc. or because you already have an implicit ++ * or explicit hold to the channel already and this is an additional hold. ++ */ ++bool ppp_channel_hold(struct ppp_channel *chan) ++{ ++ if (!chan->ops->hold) ++ return false; ++ ++ chan->ops->hold(chan); ++ return true; ++} ++EXPORT_SYMBOL(ppp_channel_hold); ++ ++/* ppp_channel_release() ++ * Call this to release a hold you have upon a channel ++ */ ++void ppp_channel_release(struct ppp_channel *chan) ++{ ++ chan->ops->release(chan); ++} ++EXPORT_SYMBOL(ppp_channel_release); ++ ++/* Check if ppp xmit lock is on hold */ ++bool ppp_is_xmit_locked(struct net_device *dev) ++{ ++ struct ppp *ppp; ++ ++ if (!dev) ++ return false; ++ ++ if (dev->type != ARPHRD_PPP) ++ return false; ++ ++ ppp = netdev_priv(dev); ++ if (!ppp) ++ return false; ++ ++ if (spin_is_locked(&(ppp)->wlock)) ++ return true; ++ ++ return false; ++} ++EXPORT_SYMBOL(ppp_is_xmit_locked); ++ ++/* ppp_hold_channels() ++ * Returns the PPP channels of the PPP device, storing each one into ++ * channels[]. ++ * ++ * channels[] has chan_sz elements. ++ * This function returns the number of channels stored, up to chan_sz. ++ * It will return < 0 if the device is not PPP. ++ * ++ * You MUST release the channels using ppp_release_channels(). ++ */ ++int ppp_hold_channels(struct net_device *dev, struct ppp_channel *channels[], ++ unsigned int chan_sz) ++{ ++ struct ppp *ppp; ++ int c; ++ struct channel *pch; ++ ++ if (!dev) ++ return -1; ++ ++ if (dev->type != ARPHRD_PPP) ++ return -1; ++ ++ ppp = netdev_priv(dev); ++ ++ c = 0; ++ ppp_lock(ppp); ++ list_for_each_entry(pch, &ppp->channels, clist) { ++ struct ppp_channel *chan; ++ ++ if (!pch->chan) { ++ /* Channel is going / gone away */ ++ continue; ++ } ++ ++ if (c == chan_sz) { ++ /* No space to record channel */ ++ ppp_unlock(ppp); ++ return c; ++ } ++ ++ /* Hold the channel, if supported */ ++ chan = pch->chan; ++ if (!chan->ops->hold) ++ continue; ++ ++ chan->ops->hold(chan); ++ ++ /* Record the channel */ ++ channels[c++] = chan; ++ } ++ ppp_unlock(ppp); ++ return c; ++} ++EXPORT_SYMBOL(ppp_hold_channels); ++ ++/* ppp_release_channels() ++ * Releases channels ++ */ ++void ppp_release_channels(struct ppp_channel *channels[], unsigned int chan_sz) ++{ ++ unsigned int c; ++ ++ for (c = 0; c < chan_sz; ++c) { ++ struct ppp_channel *chan; ++ ++ chan = channels[c]; ++ chan->ops->release(chan); ++ } ++} ++EXPORT_SYMBOL(ppp_release_channels); ++ + /* Module/initialization stuff */ + + module_init(ppp_init); +@@ -3604,6 +3877,7 @@ EXPORT_SYMBOL(ppp_input_error); + EXPORT_SYMBOL(ppp_output_wakeup); + EXPORT_SYMBOL(ppp_register_compressor); + EXPORT_SYMBOL(ppp_unregister_compressor); ++EXPORT_SYMBOL(ppp_update_stats); + MODULE_LICENSE("GPL"); + MODULE_ALIAS_CHARDEV(PPP_MAJOR, 0); + MODULE_ALIAS_RTNL_LINK("ppp"); +--- a/drivers/net/ppp/pppoe.c ++++ b/drivers/net/ppp/pppoe.c +@@ -62,6 +62,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -87,7 +88,7 @@ + static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb); + + static const struct proto_ops pppoe_ops; +-static const struct ppp_channel_ops pppoe_chan_ops; ++static const struct pppoe_channel_ops pppoe_chan_ops; + + /* per-net private data for this module */ + static unsigned int pppoe_net_id __read_mostly; +@@ -692,7 +693,7 @@ static int pppoe_connect(struct socket * + + po->chan.mtu = dev->mtu - sizeof(struct pppoe_hdr) - 2; + po->chan.private = sk; +- po->chan.ops = &pppoe_chan_ops; ++ po->chan.ops = (struct ppp_channel_ops *)&pppoe_chan_ops; + + error = ppp_register_net_channel(dev_net(dev), &po->chan); + if (error) { +@@ -995,9 +996,80 @@ static int pppoe_fill_forward_path(struc + return 0; + } + +-static const struct ppp_channel_ops pppoe_chan_ops = { +- .start_xmit = pppoe_xmit, +- .fill_forward_path = pppoe_fill_forward_path, ++/************************************************************************ ++ * ++ * function called by generic PPP driver to hold channel ++ * ++ ***********************************************************************/ ++static void pppoe_hold_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_hold(sk); ++} ++ ++/************************************************************************ ++ * ++ * function called by generic PPP driver to release channel ++ * ++ ***********************************************************************/ ++static void pppoe_release_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_put(sk); ++} ++ ++/************************************************************************ ++ * ++ * function called to get the channel protocol type ++ * ++ ***********************************************************************/ ++static int pppoe_get_channel_protocol(struct ppp_channel *chan) ++{ ++ return PX_PROTO_OE; ++} ++ ++/************************************************************************ ++ * ++ * function called to get the PPPoE channel addressing ++ * NOTE: This function returns a HOLD to the netdevice ++ * ++ ***********************************************************************/ ++static int pppoe_get_addressing(struct ppp_channel *chan, ++ struct pppoe_opt *addressing) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ struct pppox_sock *po = pppox_sk(sk); ++ int err = 0; ++ ++ *addressing = po->proto.pppoe; ++ if (!addressing->dev) ++ return -ENODEV; ++ ++ dev_hold(addressing->dev); ++ return err; ++} ++ ++/* pppoe_channel_addressing_get() ++ * Return PPPoE channel specific addressing information. ++ */ ++int pppoe_channel_addressing_get(struct ppp_channel *chan, ++ struct pppoe_opt *addressing) ++{ ++ return pppoe_get_addressing(chan, addressing); ++} ++EXPORT_SYMBOL(pppoe_channel_addressing_get); ++ ++static const struct pppoe_channel_ops pppoe_chan_ops = { ++ /* PPPoE specific channel ops */ ++ .get_addressing = pppoe_get_addressing, ++ /* General ppp channel ops */ ++ .ops.start_xmit = pppoe_xmit, ++ .ops.get_channel_protocol = pppoe_get_channel_protocol, ++ .ops.hold = pppoe_hold_chan, ++ .ops.release = pppoe_release_chan, ++ .ops.fill_forward_path = pppoe_fill_forward_path, + }; + + static int pppoe_recvmsg(struct socket *sock, struct msghdr *m, +--- a/include/linux/if_pppox.h ++++ b/include/linux/if_pppox.h +@@ -91,4 +91,17 @@ enum { + PPPOX_DEAD = 16 /* dead, useless, please clean me up!*/ + }; + ++/* ++ * PPPoE Channel specific operations ++ */ ++struct pppoe_channel_ops { ++ /* Must be first - general to all PPP channels */ ++ struct ppp_channel_ops ops; ++ int (*get_addressing)(struct ppp_channel *, struct pppoe_opt *); ++}; ++ ++/* Return PPPoE channel specific addressing information */ ++extern int pppoe_channel_addressing_get(struct ppp_channel *chan, ++ struct pppoe_opt *addressing); ++ + #endif /* !(__LINUX_IF_PPPOX_H) */ +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -1762,6 +1762,36 @@ enum netdev_priv_flags { + IFF_NO_IP_ALIGN = BIT_ULL(34), + }; + ++/** ++ * enum netdev_priv_flags_ext - &struct net_device priv_flags_ext ++ * ++ * These flags are used to check for device type and can be ++ * set and used by the drivers ++ * ++ * @IFF_EXT_TUN_TAP: device is a TUN/TAP device ++ * @IFF_EXT_PPP_L2TPV2: device is a L2TPV2 device ++ * @IFF_EXT_PPP_L2TPV3: device is a L2TPV3 device ++ * @IFF_EXT_PPP_PPTP: device is a PPTP device ++ * @IFF_EXT_GRE_V4_TAP: device is a GRE IPv4 TAP device ++ * @IFF_EXT_GRE_V6_TAP: device is a GRE IPv6 TAP device ++ * @IFF_EXT_IFB: device is an IFB device ++ * @IFF_EXT_MAPT: device is an MAPT device ++ * @IFF_EXT_HW_NO_OFFLOAD: device is an NON Offload device ++ * @IFF_EXT_L2TPV3: device is a L2TPV3 Ethernet device ++ */ ++enum netdev_priv_flags_ext { ++ IFF_EXT_TUN_TAP = 1<<0, ++ IFF_EXT_PPP_L2TPV2 = 1<<1, ++ IFF_EXT_PPP_L2TPV3 = 1<<2, ++ IFF_EXT_PPP_PPTP = 1<<3, ++ IFF_EXT_GRE_V4_TAP = 1<<4, ++ IFF_EXT_GRE_V6_TAP = 1<<5, ++ IFF_EXT_IFB = 1<<6, ++ IFF_EXT_MAPT = 1<<7, ++ IFF_EXT_HW_NO_OFFLOAD = 1<<8, ++ IFF_EXT_ETH_L2TPV3 = 1<<9, ++}; ++ + #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN + #define IFF_EBRIDGE IFF_EBRIDGE + #define IFF_BONDING IFF_BONDING +@@ -2127,6 +2157,7 @@ struct net_device { + unsigned int flags; + xdp_features_t xdp_features; + unsigned long long priv_flags; ++ unsigned int priv_flags_ext; + const struct net_device_ops *netdev_ops; + const struct xdp_metadata_ops *xdp_metadata_ops; + int ifindex; +--- a/include/linux/ppp_channel.h ++++ b/include/linux/ppp_channel.h +@@ -19,6 +19,10 @@ + #include + #include + #include ++#include ++ ++#define PPP_CHANNEL_DISCONNECT 0 ++#define PPP_CHANNEL_CONNECT 1 + + struct net_device_path; + struct net_device_path_ctx; +@@ -30,9 +34,19 @@ struct ppp_channel_ops { + int (*start_xmit)(struct ppp_channel *, struct sk_buff *); + /* Handle an ioctl call that has come in via /dev/ppp. */ + int (*ioctl)(struct ppp_channel *, unsigned int, unsigned long); ++ /* Get channel protocol type, one of PX_PROTO_XYZ or specific to ++ * the channel subtype ++ */ ++ int (*get_channel_protocol)(struct ppp_channel *); ++ /* Get channel protocol version */ ++ int (*get_channel_protocol_ver)(struct ppp_channel *); ++ /* Hold the channel from being destroyed */ ++ void (*hold)(struct ppp_channel *); ++ /* Release hold on the channel */ ++ void (*release)(struct ppp_channel *); + int (*fill_forward_path)(struct net_device_path_ctx *, +- struct net_device_path *, +- const struct ppp_channel *); ++ struct net_device_path *, ++ const struct ppp_channel *); + }; + + struct ppp_channel { +@@ -76,6 +90,51 @@ extern int ppp_unit_number(struct ppp_ch + /* Get the device name associated with a channel, or NULL if none */ + extern char *ppp_dev_name(struct ppp_channel *); + ++/* Call this to obtain the underlying protocol of the PPP channel, ++ * e.g. PX_PROTO_OE ++ */ ++extern int ppp_channel_get_protocol(struct ppp_channel *); ++ ++/* Call this get protocol version */ ++extern int ppp_channel_get_proto_version(struct ppp_channel *); ++ ++/* Call this to hold a channel */ ++extern bool ppp_channel_hold(struct ppp_channel *); ++ ++/* Call this to release a hold you have upon a channel */ ++extern void ppp_channel_release(struct ppp_channel *); ++ ++/* Release hold on PPP channels */ ++extern void ppp_release_channels(struct ppp_channel *channels[], ++ unsigned int chan_sz); ++ ++/* Hold PPP channels for the PPP device */ ++extern int ppp_hold_channels(struct net_device *dev, ++ struct ppp_channel *channels[], ++ unsigned int chan_sz); ++ ++/* Test if ppp xmit lock is locked */ ++extern bool ppp_is_xmit_locked(struct net_device *dev); ++ ++/* Test if the ppp device is a multi-link ppp device */ ++extern int ppp_is_multilink(struct net_device *dev); ++ ++/* Register the PPP channel connect notifier */ ++extern void ppp_channel_connection_register_notify(struct notifier_block *nb); ++ ++/* Unregister the PPP channel connect notifier */ ++extern void ppp_channel_connection_unregister_notify(struct notifier_block *nb); ++ ++/* Update statistics of the PPP net_device by incrementing related ++ * statistics field value with corresponding parameter ++ */ ++extern void ppp_update_stats(struct net_device *dev, unsigned long rx_packets, ++ unsigned long rx_bytes, unsigned long tx_packets, ++ unsigned long tx_bytes, unsigned long rx_errors, ++ unsigned long tx_errors, unsigned long rx_dropped, ++ unsigned long tx_dropped); ++ ++ + /* + * SMP locking notes: + * The channel code must ensure that when it calls ppp_unregister_channel, diff --git a/target/linux/qualcommax/patches-6.6/0600-3-qca-nss-ecm-support-net-bonding.patch b/target/linux/qualcommax/patches-6.6/0600-3-qca-nss-ecm-support-net-bonding.patch new file mode 100644 index 00000000000000..4e683e3a3e7e8e --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0600-3-qca-nss-ecm-support-net-bonding.patch @@ -0,0 +1,46 @@ +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -210,6 +210,7 @@ atomic_t netpoll_block_tx = ATOMIC_INIT( + #endif + + unsigned int bond_net_id __read_mostly; ++static unsigned long bond_id_mask = 0xFFFFFFF0; /* QCA NSS ECM bonding support */ + + static const struct flow_dissector_key flow_keys_bonding_keys[] = { + { +@@ -5872,6 +5873,11 @@ static void bond_destructor(struct net_d + if (bond->wq) + destroy_workqueue(bond->wq); + ++ /* QCA NSS ECM bonding support - Start */ ++ if (bond->id != (~0U)) ++ clear_bit(bond->id, &bond_id_mask); ++ /* QCA NSS ECM bonding support - End */ ++ + free_percpu(bond->rr_tx_counter); + } + +@@ -6421,6 +6427,13 @@ int bond_create(struct net *net, const c + + bond_work_init_all(bond); + ++ /* QCA NSS ECM bonding support - Start */ ++ bond->id = ~0U; ++ if (bond_id_mask != (~0UL)) { ++ bond->id = (u32)ffz(bond_id_mask); ++ set_bit(bond->id, &bond_id_mask); ++ } ++ /* QCA NSS ECM bonding support - End */ + out: + rtnl_unlock(); + return res; +--- a/include/net/bonding.h ++++ b/include/net/bonding.h +@@ -261,6 +261,7 @@ struct bonding { + spinlock_t ipsec_lock; + #endif /* CONFIG_XFRM_OFFLOAD */ + struct bpf_prog *xdp_prog; ++ u32 id;/* QCA NSS ECM bonding support */ + }; + + #define bond_slave_get_rcu(dev) \ diff --git a/target/linux/qualcommax/patches-6.6/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch b/target/linux/qualcommax/patches-6.6/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch new file mode 100644 index 00000000000000..e02e9090db8c4e --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch @@ -0,0 +1,685 @@ +--- a/drivers/net/bonding/bond_3ad.c ++++ b/drivers/net/bonding/bond_3ad.c +@@ -116,6 +116,40 @@ static void ad_marker_response_received( + struct port *port); + static void ad_update_actor_keys(struct port *port, bool reset); + ++/* QCA NSS ECM bonding support - Start */ ++struct bond_cb __rcu *bond_cb; ++ ++int bond_register_cb(struct bond_cb *cb) ++{ ++ struct bond_cb *lag_cb; ++ ++ lag_cb = kzalloc(sizeof(*lag_cb), GFP_ATOMIC | __GFP_NOWARN); ++ if (!lag_cb) { ++ return -1; ++ } ++ ++ memcpy((void *)lag_cb, (void *)cb, sizeof(*cb)); ++ ++ rcu_read_lock(); ++ rcu_assign_pointer(bond_cb, lag_cb); ++ rcu_read_unlock(); ++ return 0; ++} ++EXPORT_SYMBOL(bond_register_cb); ++ ++void bond_unregister_cb(void) ++{ ++ struct bond_cb *lag_cb_main; ++ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ rcu_assign_pointer(bond_cb, NULL); ++ rcu_read_unlock(); ++ ++ kfree(lag_cb_main); ++} ++EXPORT_SYMBOL(bond_unregister_cb); ++/* QCA NSS ECM bonding support - End */ + + /* ================= api to bonding and kernel code ================== */ + +@@ -1073,7 +1107,31 @@ static void ad_mux_machine(struct port * + ad_disable_collecting_distributing(port, + update_slave_arr); + port->ntt = true; ++ ++ /* QCA NSS ECM bonding support - Start */ ++ /* Send a notificaton about change in state of this ++ * port. We only want to handle case where port moves ++ * from AD_MUX_COLLECTING_DISTRIBUTING -> ++ * AD_MUX_ATTACHED. ++ */ ++ if (bond_slave_is_up(port->slave) && ++ (last_state == AD_MUX_COLLECTING_DISTRIBUTING)) { ++ struct bond_cb *lag_cb_main; ++ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ if (lag_cb_main && ++ lag_cb_main->bond_cb_link_down) { ++ struct net_device *dev; ++ ++ dev = port->slave->dev; ++ lag_cb_main->bond_cb_link_down(dev); ++ } ++ rcu_read_unlock(); ++ } ++ + break; ++ /* QCA NSS ECM bonding support - End */ + case AD_MUX_COLLECTING_DISTRIBUTING: + port->actor_oper_port_state |= LACP_STATE_COLLECTING; + port->actor_oper_port_state |= LACP_STATE_DISTRIBUTING; +@@ -1917,6 +1975,7 @@ static void ad_enable_collecting_distrib + bool *update_slave_arr) + { + if (port->aggregator->is_active) { ++ struct bond_cb *lag_cb_main; /* QCA NSS ECM bonding support */ + slave_dbg(port->slave->bond->dev, port->slave->dev, + "Enabling port %d (LAG %d)\n", + port->actor_port_number, +@@ -1924,6 +1983,16 @@ static void ad_enable_collecting_distrib + __enable_port(port); + /* Slave array needs update */ + *update_slave_arr = true; ++ ++ /* QCA NSS ECM bonding support - Start */ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ ++ if (lag_cb_main && lag_cb_main->bond_cb_link_up) ++ lag_cb_main->bond_cb_link_up(port->slave->dev); ++ ++ rcu_read_unlock(); ++ /* QCA NSS ECM bonding support - End */ + } + } + +@@ -2683,6 +2752,104 @@ int bond_3ad_get_active_agg_info(struct + return ret; + } + ++/* QCA NSS ECM bonding support - Start */ ++/* bond_3ad_get_tx_dev - Calculate egress interface for a given packet, ++ * for a LAG that is configured in 802.3AD mode ++ * @skb: pointer to skb to be egressed ++ * @src_mac: pointer to source L2 address ++ * @dst_mac: pointer to destination L2 address ++ * @src: pointer to source L3 address ++ * @dst: pointer to destination L3 address ++ * @protocol: L3 protocol id from L2 header ++ * @bond_dev: pointer to bond master device ++ * ++ * If @skb is NULL, bond_xmit_hash is used to calculate hash using L2/L3 ++ * addresses. ++ * ++ * Returns: Either valid slave device, or NULL otherwise ++ */ ++struct net_device *bond_3ad_get_tx_dev(struct sk_buff *skb, u8 *src_mac, ++ u8 *dst_mac, void *src, ++ void *dst, u16 protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr) ++{ ++ struct bonding *bond = netdev_priv(bond_dev); ++ struct aggregator *agg; ++ struct ad_info ad_info; ++ struct list_head *iter; ++ struct slave *slave; ++ struct slave *first_ok_slave = NULL; ++ u32 hash = 0; ++ int slaves_in_agg; ++ int slave_agg_no = 0; ++ int agg_id; ++ ++ if (__bond_3ad_get_active_agg_info(bond, &ad_info)) { ++ pr_debug("%s: Error: __bond_3ad_get_active_agg_info failed\n", ++ bond_dev->name); ++ return NULL; ++ } ++ ++ slaves_in_agg = ad_info.ports; ++ agg_id = ad_info.aggregator_id; ++ ++ if (slaves_in_agg == 0) { ++ pr_debug("%s: Error: active aggregator is empty\n", ++ bond_dev->name); ++ return NULL; ++ } ++ ++ if (skb) { ++ hash = bond_xmit_hash(bond, skb); ++ slave_agg_no = hash % slaves_in_agg; ++ } else { ++ if (bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER23 && ++ bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER2 && ++ bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER34) { ++ pr_debug("%s: Error: Unsupported hash policy for 802.3AD fast path\n", ++ bond_dev->name); ++ return NULL; ++ } ++ ++ hash = bond_xmit_hash_without_skb(src_mac, dst_mac, ++ src, dst, protocol, ++ bond_dev, layer4hdr); ++ slave_agg_no = hash % slaves_in_agg; ++ } ++ ++ bond_for_each_slave_rcu(bond, slave, iter) { ++ agg = SLAVE_AD_INFO(slave)->port.aggregator; ++ if (!agg || agg->aggregator_identifier != agg_id) ++ continue; ++ ++ if (slave_agg_no >= 0) { ++ if (!first_ok_slave && bond_slave_can_tx(slave)) ++ first_ok_slave = slave; ++ slave_agg_no--; ++ continue; ++ } ++ ++ if (bond_slave_can_tx(slave)) ++ return slave->dev; ++ } ++ ++ if (slave_agg_no >= 0) { ++ pr_err("%s: Error: Couldn't find a slave to tx on for aggregator ID %d\n", ++ bond_dev->name, agg_id); ++ return NULL; ++ } ++ ++ /* we couldn't find any suitable slave after the agg_no, so use the ++ * first suitable found, if found. ++ */ ++ if (first_ok_slave) ++ return first_ok_slave->dev; ++ ++ return NULL; ++} ++/* QCA NSS ECM bonding support - End */ ++ + int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond, + struct slave *slave) + { +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -288,6 +288,21 @@ const char *bond_mode_name(int mode) + return names[mode]; + } + ++/* QCA NSS ECM bonding support */ ++int bond_get_id(struct net_device *bond_dev) ++{ ++ struct bonding *bond; ++ ++ if (!((bond_dev->priv_flags & IFF_BONDING) && ++ (bond_dev->flags & IFF_MASTER))) ++ return -EINVAL; ++ ++ bond = netdev_priv(bond_dev); ++ return bond->id; ++} ++EXPORT_SYMBOL(bond_get_id); ++/* QCA NSS ECM bonding support */ ++ + /** + * bond_dev_queue_xmit - Prepare skb for xmit. + * +@@ -1189,6 +1204,23 @@ void bond_change_active_slave(struct bon + if (BOND_MODE(bond) == BOND_MODE_8023AD) + bond_3ad_handle_link_change(new_active, BOND_LINK_UP); + ++ /* QCA NSS ECM bonding support - Start */ ++ if (bond->params.mode == BOND_MODE_XOR) { ++ struct bond_cb *lag_cb_main; ++ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ if (lag_cb_main && ++ lag_cb_main->bond_cb_link_up) { ++ struct net_device *dev; ++ ++ dev = new_active->dev; ++ lag_cb_main->bond_cb_link_up(dev); ++ } ++ rcu_read_unlock(); ++ } ++ /* QCA NSS ECM bonding support - End */ ++ + if (bond_is_lb(bond)) + bond_alb_handle_link_change(bond, new_active, BOND_LINK_UP); + } else { +@@ -1833,6 +1865,7 @@ int bond_enslave(struct net_device *bond + const struct net_device_ops *slave_ops = slave_dev->netdev_ops; + struct slave *new_slave = NULL, *prev_slave; + struct sockaddr_storage ss; ++ struct bond_cb *lag_cb_main; /* QCA NSS ECM bonding support */ + int link_reporting; + int res = 0, i; + +@@ -2278,6 +2311,15 @@ int bond_enslave(struct net_device *bond + bond_is_active_slave(new_slave) ? "an active" : "a backup", + new_slave->link != BOND_LINK_DOWN ? "an up" : "a down"); + ++ /* QCA NSS ECM bonding support - Start */ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ if (lag_cb_main && lag_cb_main->bond_cb_enslave) ++ lag_cb_main->bond_cb_enslave(slave_dev); ++ ++ rcu_read_unlock(); ++ /* QCA NSS ECM bonding support - End */ ++ + /* enslave is successful */ + bond_queue_slave_event(new_slave); + return 0; +@@ -2343,6 +2385,15 @@ err_undo_flags: + } + } + ++ /* QCA NSS ECM bonding support - Start */ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ if (lag_cb_main && lag_cb_main->bond_cb_enslave) ++ lag_cb_main->bond_cb_enslave(slave_dev); ++ ++ rcu_read_unlock(); ++ /* QCA NSS ECM bonding support - End */ ++ + return res; + } + +@@ -2364,6 +2415,7 @@ static int __bond_release_one(struct net + struct bonding *bond = netdev_priv(bond_dev); + struct slave *slave, *oldcurrent; + struct sockaddr_storage ss; ++ struct bond_cb *lag_cb_main; /* QCA NSS ECM bonding support */ + int old_flags = bond_dev->flags; + netdev_features_t old_features = bond_dev->features; + +@@ -2386,6 +2438,15 @@ static int __bond_release_one(struct net + + bond_set_slave_inactive_flags(slave, BOND_SLAVE_NOTIFY_NOW); + ++ /* QCA NSS ECM bonding support - Start */ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ if (lag_cb_main && lag_cb_main->bond_cb_release) ++ lag_cb_main->bond_cb_release(slave_dev); ++ ++ rcu_read_unlock(); ++ /* QCA NSS ECM bonding support - End */ ++ + bond_sysfs_slave_del(slave); + + /* recompute stats just before removing the slave */ +@@ -2708,6 +2769,8 @@ static void bond_miimon_commit(struct bo + struct slave *slave, *primary, *active; + bool do_failover = false; + struct list_head *iter; ++ struct net_device *slave_dev = NULL; /* QCA NSS ECM bonding support */ ++ struct bond_cb *lag_cb_main; /* QCA NSS ECM bonding support */ + + ASSERT_RTNL(); + +@@ -2747,6 +2810,12 @@ static void bond_miimon_commit(struct bo + bond_set_active_slave(slave); + } + ++ /* QCA NSS ECM bonding support - Start */ ++ if ((bond->params.mode == BOND_MODE_XOR) && ++ (!slave_dev)) ++ slave_dev = slave->dev; ++ /* QCA NSS ECM bonding support - End */ ++ + slave_info(bond->dev, slave->dev, "link status definitely up, %u Mbps %s duplex\n", + slave->speed == SPEED_UNKNOWN ? 0 : slave->speed, + slave->duplex ? "full" : "half"); +@@ -2795,6 +2864,16 @@ static void bond_miimon_commit(struct bo + unblock_netpoll_tx(); + } + ++ /* QCA NSS ECM bonding support - Start */ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ ++ if (slave_dev && lag_cb_main && lag_cb_main->bond_cb_link_up) ++ lag_cb_main->bond_cb_link_up(slave_dev); ++ ++ rcu_read_unlock(); ++ /* QCA NSS ECM bonding support - End */ ++ + bond_set_carrier(bond); + } + +@@ -4047,8 +4126,219 @@ static inline u32 bond_eth_hash(struct s + return 0; + + ep = (struct ethhdr *)(data + mhoff); +- return ep->h_dest[5] ^ ep->h_source[5] ^ be16_to_cpu(ep->h_proto); ++ return ep->h_dest[5] ^ ep->h_source[5]; /* QCA NSS ECM bonding support */ ++} ++ ++/* QCA NSS ECM bonding support - Start */ ++/* Extract the appropriate headers based on bond's xmit policy */ ++static bool bond_flow_dissect_without_skb(struct bonding *bond, ++ u8 *src_mac, u8 *dst_mac, ++ void *psrc, void *pdst, ++ u16 protocol, __be16 *layer4hdr, ++ struct flow_keys *fk) ++{ ++ u32 *src = NULL; ++ u32 *dst = NULL; ++ ++ fk->ports.ports = 0; ++ src = (uint32_t *)psrc; ++ dst = (uint32_t *)pdst; ++ ++ if (protocol == htons(ETH_P_IP)) { ++ /* V4 addresses and address type*/ ++ fk->addrs.v4addrs.src = src[0]; ++ fk->addrs.v4addrs.dst = dst[0]; ++ fk->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS; ++ } else if (protocol == htons(ETH_P_IPV6)) { ++ /* V6 addresses and address type*/ ++ memcpy(&fk->addrs.v6addrs.src, src, sizeof(struct in6_addr)); ++ memcpy(&fk->addrs.v6addrs.dst, dst, sizeof(struct in6_addr)); ++ fk->control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS; ++ } else { ++ return false; ++ } ++ if ((bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34) && ++ (layer4hdr)) ++ fk->ports.ports = *layer4hdr; ++ ++ return true; ++} ++ ++/* bond_xmit_hash_without_skb - Applies load balancing algorithm for a packet, ++ * to calculate hash for a given set of L2/L3 addresses. Does not ++ * calculate egress interface. ++ */ ++uint32_t bond_xmit_hash_without_skb(u8 *src_mac, u8 *dst_mac, ++ void *psrc, void *pdst, u16 protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr) ++{ ++ struct bonding *bond = netdev_priv(bond_dev); ++ struct flow_keys flow; ++ u32 hash = 0; ++ ++ if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER2 || ++ !bond_flow_dissect_without_skb(bond, src_mac, dst_mac, psrc, ++ pdst, protocol, layer4hdr, &flow)) ++ return (dst_mac[5] ^ src_mac[5]); ++ ++ if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER23) ++ hash = dst_mac[5] ^ src_mac[5]; ++ else if (layer4hdr) ++ hash = (__force u32)flow.ports.ports; ++ ++ hash ^= (__force u32)flow_get_u32_dst(&flow) ^ ++ (__force u32)flow_get_u32_src(&flow); ++ hash ^= (hash >> 16); ++ hash ^= (hash >> 8); ++ ++ return hash; ++} ++ ++/* bond_xor_get_tx_dev - Calculate egress interface for a given packet for a LAG ++ * that is configured in balance-xor mode ++ * @skb: pointer to skb to be egressed ++ * @src_mac: pointer to source L2 address ++ * @dst_mac: pointer to destination L2 address ++ * @src: pointer to source L3 address in network order ++ * @dst: pointer to destination L3 address in network order ++ * @protocol: L3 protocol ++ * @bond_dev: pointer to bond master device ++ * ++ * If @skb is NULL, bond_xmit_hash_without_skb is used to calculate hash using ++ * L2/L3 addresses. ++ * ++ * Returns: Either valid slave device, or NULL otherwise ++ */ ++static struct net_device *bond_xor_get_tx_dev(struct sk_buff *skb, ++ u8 *src_mac, u8 *dst_mac, ++ void *src, void *dst, ++ u16 protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr) ++{ ++ struct bonding *bond = netdev_priv(bond_dev); ++ int slave_cnt = READ_ONCE(bond->slave_cnt); ++ int slave_id = 0, i = 0; ++ u32 hash; ++ struct list_head *iter; ++ struct slave *slave; ++ ++ if (slave_cnt == 0) { ++ pr_debug("%s: Error: No slave is attached to the interface\n", ++ bond_dev->name); ++ return NULL; ++ } ++ ++ if (skb) { ++ hash = bond_xmit_hash(bond, skb); ++ slave_id = hash % slave_cnt; ++ } else { ++ if (bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER23 && ++ bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER2 && ++ bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER34) { ++ pr_debug("%s: Error: Unsupported hash policy for balance-XOR fast path\n", ++ bond_dev->name); ++ return NULL; ++ } ++ ++ hash = bond_xmit_hash_without_skb(src_mac, dst_mac, src, ++ dst, protocol, bond_dev, ++ layer4hdr); ++ slave_id = hash % slave_cnt; ++ } ++ ++ i = slave_id; ++ ++ /* Here we start from the slave with slave_id */ ++ bond_for_each_slave_rcu(bond, slave, iter) { ++ if (--i < 0) { ++ if (bond_slave_can_tx(slave)) ++ return slave->dev; ++ } ++ } ++ ++ /* Here we start from the first slave up to slave_id */ ++ i = slave_id; ++ bond_for_each_slave_rcu(bond, slave, iter) { ++ if (--i < 0) ++ break; ++ if (bond_slave_can_tx(slave)) ++ return slave->dev; ++ } ++ ++ return NULL; ++} ++ ++/* bond_get_tx_dev - Calculate egress interface for a given packet. ++ * ++ * Supports 802.3AD and balance-xor modes ++ * ++ * @skb: pointer to skb to be egressed, if valid ++ * @src_mac: pointer to source L2 address ++ * @dst_mac: pointer to destination L2 address ++ * @src: pointer to source L3 address in network order ++ * @dst: pointer to destination L3 address in network order ++ * @protocol: L3 protocol id from L2 header ++ * @bond_dev: pointer to bond master device ++ * ++ * Returns: Either valid slave device, or NULL for un-supported LAG modes ++ */ ++struct net_device *bond_get_tx_dev(struct sk_buff *skb, uint8_t *src_mac, ++ u8 *dst_mac, void *src, ++ void *dst, u16 protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr) ++{ ++ struct bonding *bond; ++ ++ if (!bond_dev) ++ return NULL; ++ ++ if (!((bond_dev->priv_flags & IFF_BONDING) && ++ (bond_dev->flags & IFF_MASTER))) ++ return NULL; ++ ++ bond = netdev_priv(bond_dev); ++ ++ switch (bond->params.mode) { ++ case BOND_MODE_XOR: ++ return bond_xor_get_tx_dev(skb, src_mac, dst_mac, ++ src, dst, protocol, ++ bond_dev, layer4hdr); ++ case BOND_MODE_8023AD: ++ return bond_3ad_get_tx_dev(skb, src_mac, dst_mac, ++ src, dst, protocol, ++ bond_dev, layer4hdr); ++ default: ++ return NULL; ++ } + } ++EXPORT_SYMBOL(bond_get_tx_dev); ++ ++/* In bond_xmit_xor() , we determine the output device by using a pre- ++ * determined xmit_hash_policy(), If the selected device is not enabled, ++ * find the next active slave. ++ */ ++static int bond_xmit_xor(struct sk_buff *skb, struct net_device *dev) ++{ ++ struct bonding *bond = netdev_priv(dev); ++ struct net_device *outdev; ++ ++ outdev = bond_xor_get_tx_dev(skb, NULL, NULL, NULL, ++ NULL, 0, dev, NULL); ++ if (!outdev) ++ goto out; ++ ++ bond_dev_queue_xmit(bond, skb, outdev); ++ goto final; ++out: ++ /* no suitable interface, frame not sent */ ++ dev_kfree_skb(skb); ++final: ++ return NETDEV_TX_OK; ++} ++/* QCA NSS ECM bonding support - End */ + + static bool bond_flow_ip(struct sk_buff *skb, struct flow_keys *fk, const void *data, + int hlen, __be16 l2_proto, int *nhoff, int *ip_proto, bool l34) +@@ -5177,15 +5467,18 @@ static netdev_tx_t bond_3ad_xor_xmit(str + struct net_device *dev) + { + struct bonding *bond = netdev_priv(dev); +- struct bond_up_slave *slaves; +- struct slave *slave; ++ /* QCA NSS ECM bonding support - Start */ ++ struct net_device *outdev = NULL; + +- slaves = rcu_dereference(bond->usable_slaves); +- slave = bond_xmit_3ad_xor_slave_get(bond, skb, slaves); +- if (likely(slave)) +- return bond_dev_queue_xmit(bond, skb, slave->dev); ++ outdev = bond_3ad_get_tx_dev(skb, NULL, NULL, NULL, ++ NULL, 0, dev, NULL); ++ if (!outdev) { ++ dev_kfree_skb(skb); ++ return NETDEV_TX_OK; ++ } + +- return bond_tx_drop(dev, skb); ++ return bond_dev_queue_xmit(bond, skb, outdev); ++ /* QCA NSS ECM bonding support - End */ + } + + /* in broadcast mode, we send everything to all usable interfaces. */ +@@ -5435,8 +5728,9 @@ static netdev_tx_t __bond_start_xmit(str + return bond_xmit_roundrobin(skb, dev); + case BOND_MODE_ACTIVEBACKUP: + return bond_xmit_activebackup(skb, dev); +- case BOND_MODE_8023AD: + case BOND_MODE_XOR: ++ return bond_xmit_xor(skb, dev); /* QCA NSS ECM bonding support */ ++ case BOND_MODE_8023AD: + return bond_3ad_xor_xmit(skb, dev); + case BOND_MODE_BROADCAST: + return bond_xmit_broadcast(skb, dev); +--- a/include/net/bond_3ad.h ++++ b/include/net/bond_3ad.h +@@ -302,8 +302,15 @@ int bond_3ad_lacpdu_recv(const struct sk + struct slave *slave); + int bond_3ad_set_carrier(struct bonding *bond); + void bond_3ad_update_lacp_rate(struct bonding *bond); ++/* QCA NSS ECM bonding support */ ++struct net_device *bond_3ad_get_tx_dev(struct sk_buff *skb, uint8_t *src_mac, ++ uint8_t *dst_mac, void *src, ++ void *dst, uint16_t protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr); ++/* QCA NSS ECM bonding support */ ++ + void bond_3ad_update_ad_actor_settings(struct bonding *bond); + int bond_3ad_stats_fill(struct sk_buff *skb, struct bond_3ad_stats *stats); + size_t bond_3ad_stats_size(void); + #endif /* _NET_BOND_3AD_H */ +- +--- a/include/net/bonding.h ++++ b/include/net/bonding.h +@@ -90,6 +90,8 @@ + #define BOND_XFRM_FEATURES (NETIF_F_HW_ESP | NETIF_F_HW_ESP_TX_CSUM | \ + NETIF_F_GSO_ESP) + ++extern struct bond_cb __rcu *bond_cb; /* QCA NSS ECM bonding support */ ++ + #ifdef CONFIG_NET_POLL_CONTROLLER + extern atomic_t netpoll_block_tx; + +@@ -653,6 +655,7 @@ struct bond_net { + + int bond_rcv_validate(const struct sk_buff *skb, struct bonding *bond, struct slave *slave); + netdev_tx_t bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); ++int bond_get_id(struct net_device *bond_dev); /* QCA NSS ECM bonding support */ + int bond_create(struct net *net, const char *name); + int bond_create_sysfs(struct bond_net *net); + void bond_destroy_sysfs(struct bond_net *net); +@@ -684,6 +687,13 @@ struct bond_vlan_tag *bond_verify_device + int level); + int bond_update_slave_arr(struct bonding *bond, struct slave *skipslave); + void bond_slave_arr_work_rearm(struct bonding *bond, unsigned long delay); ++/* QCA NSS ECM bonding support - Start */ ++uint32_t bond_xmit_hash_without_skb(uint8_t *src_mac, uint8_t *dst_mac, ++ void *psrc, void *pdst, uint16_t protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr); ++/* QCA NSS ECM bonding support - End */ ++ + void bond_work_init_all(struct bonding *bond); + + #ifdef CONFIG_PROC_FS +@@ -788,4 +798,18 @@ static inline netdev_tx_t bond_tx_drop(s + return NET_XMIT_DROP; + } + ++/* QCA NSS ECM bonding support - Start */ ++struct bond_cb { ++ void (*bond_cb_link_up)(struct net_device *slave); ++ void (*bond_cb_link_down)(struct net_device *slave); ++ void (*bond_cb_enslave)(struct net_device *slave); ++ void (*bond_cb_release)(struct net_device *slave); ++ void (*bond_cb_delete_by_slave)(struct net_device *slave); ++ void (*bond_cb_delete_by_mac)(uint8_t *mac_addr); ++}; ++ ++extern int bond_register_cb(struct bond_cb *cb); ++extern void bond_unregister_cb(void); ++/* QCA NSS ECM bonding support - End */ ++ + #endif /* _NET_BONDING_H */ diff --git a/target/linux/qualcommax/patches-6.6/0600-5-qca-nss-ecm-support-macvlan.patch b/target/linux/qualcommax/patches-6.6/0600-5-qca-nss-ecm-support-macvlan.patch new file mode 100644 index 00000000000000..29f7e96d791328 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0600-5-qca-nss-ecm-support-macvlan.patch @@ -0,0 +1,96 @@ +--- a/include/linux/if_macvlan.h ++++ b/include/linux/if_macvlan.h +@@ -15,6 +15,13 @@ struct macvlan_port; + #define MACVLAN_MC_FILTER_BITS 8 + #define MACVLAN_MC_FILTER_SZ (1 << MACVLAN_MC_FILTER_BITS) + ++/* QCA NSS ECM Support - Start */ ++/* ++ * Callback for updating interface statistics for macvlan flows offloaded from host CPU. ++ */ ++typedef void (*macvlan_offload_stats_update_cb_t)(struct net_device *dev, struct rtnl_link_stats64 *stats, bool update_mcast_rx_stats); ++/* QCA NSS ECM Support - End */ ++ + struct macvlan_dev { + struct net_device *dev; + struct list_head list; +@@ -35,6 +42,7 @@ struct macvlan_dev { + #ifdef CONFIG_NET_POLL_CONTROLLER + struct netpoll *netpoll; + #endif ++ macvlan_offload_stats_update_cb_t offload_stats_update; /* QCA NSS ECM support */ + }; + + static inline void macvlan_count_rx(const struct macvlan_dev *vlan, +@@ -107,4 +115,26 @@ static inline int macvlan_release_l2fw_o + macvlan->accel_priv = NULL; + return dev_uc_add(macvlan->lowerdev, dev->dev_addr); + } ++ ++/* QCA NSS ECM Support - Start */ ++#if IS_ENABLED(CONFIG_MACVLAN) ++static inline void ++macvlan_offload_stats_update(struct net_device *dev, ++ struct rtnl_link_stats64 *stats, ++ bool update_mcast_rx_stats) ++{ ++ struct macvlan_dev *macvlan = netdev_priv(dev); ++ ++ macvlan->offload_stats_update(dev, stats, update_mcast_rx_stats); ++} ++ ++static inline enum ++macvlan_mode macvlan_get_mode(struct net_device *dev) ++{ ++ struct macvlan_dev *macvlan = netdev_priv(dev); ++ ++ return macvlan->mode; ++} ++#endif ++/* QCA NSS ECM Support - End */ + #endif /* _LINUX_IF_MACVLAN_H */ +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -960,6 +960,34 @@ static void macvlan_uninit(struct net_de + macvlan_port_destroy(port->dev); + } + ++/* QCA NSS ECM Support - Start */ ++/* Update macvlan statistics processed by offload engines */ ++static void macvlan_dev_update_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *offl_stats, ++ bool update_mcast_rx_stats) ++{ ++ struct vlan_pcpu_stats *stats; ++ struct macvlan_dev *macvlan; ++ ++ /* Is this a macvlan? */ ++ if (!netif_is_macvlan(dev)) ++ return; ++ ++ macvlan = netdev_priv(dev); ++ stats = this_cpu_ptr(macvlan->pcpu_stats); ++ u64_stats_update_begin(&stats->syncp); ++ u64_stats_add(&stats->rx_packets, offl_stats->rx_packets); ++ u64_stats_add(&stats->rx_bytes, offl_stats->rx_bytes); ++ u64_stats_add(&stats->tx_packets, offl_stats->tx_packets); ++ u64_stats_add(&stats->tx_bytes, offl_stats->tx_bytes); ++ /* Update multicast statistics */ ++ if (unlikely(update_mcast_rx_stats)) { ++ u64_stats_add(&stats->rx_multicast, offl_stats->rx_packets); ++ } ++ u64_stats_update_end(&stats->syncp); ++} ++/* QCA NSS ECM Support - End */ ++ + static void macvlan_dev_get_stats64(struct net_device *dev, + struct rtnl_link_stats64 *stats) + { +@@ -1506,6 +1534,7 @@ int macvlan_common_newlink(struct net *s + vlan->dev = dev; + vlan->port = port; + vlan->set_features = MACVLAN_FEATURES; ++ vlan->offload_stats_update = macvlan_dev_update_stats; /* QCA NSS ECM Support */ + + vlan->mode = MACVLAN_MODE_VEPA; + if (data && data[IFLA_MACVLAN_MODE]) diff --git a/target/linux/qualcommax/patches-6.6/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch b/target/linux/qualcommax/patches-6.6/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch new file mode 100644 index 00000000000000..27650731a69612 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch @@ -0,0 +1,154 @@ +--- a/net/netfilter/Kconfig ++++ b/net/netfilter/Kconfig +@@ -174,6 +174,13 @@ config NF_CONNTRACK_TIMEOUT + + If unsure, say `N'. + ++config NF_CONNTRACK_DSCPREMARK_EXT ++ bool 'Connection tracking extension for dscp remark target' ++ depends on NETFILTER_ADVANCED ++ help ++ This option enables support for connection tracking extension ++ for dscp remark. ++ + config NF_CONNTRACK_TIMESTAMP + bool 'Connection tracking timestamping' + depends on NETFILTER_ADVANCED +--- a/include/net/netfilter/nf_conntrack_extend.h ++++ b/include/net/netfilter/nf_conntrack_extend.h +@@ -31,6 +31,10 @@ enum nf_ct_ext_id { + #if IS_ENABLED(CONFIG_NET_ACT_CT) + NF_CT_EXT_ACT_CT, + #endif ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ NF_CT_EXT_DSCPREMARK, /* QCA NSS ECM support */ ++#endif ++ + NF_CT_EXT_NUM, + }; + +--- a/net/netfilter/nf_conntrack_extend.c ++++ b/net/netfilter/nf_conntrack_extend.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + + #define NF_CT_EXT_PREALLOC 128u /* conntrack events are on by default */ +@@ -54,6 +55,9 @@ static const u8 nf_ct_ext_type_len[NF_CT + #if IS_ENABLED(CONFIG_NET_ACT_CT) + [NF_CT_EXT_ACT_CT] = sizeof(struct nf_conn_act_ct_ext), + #endif ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ [NF_CT_EXT_DSCPREMARK] = sizeof(struct nf_ct_dscpremark_ext), ++#endif + }; + + static __always_inline unsigned int total_extension_size(void) +@@ -86,6 +90,9 @@ static __always_inline unsigned int tota + #if IS_ENABLED(CONFIG_NET_ACT_CT) + + sizeof(struct nf_conn_act_ct_ext) + #endif ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ + sizeof(struct nf_ct_dscpremark_ext) ++#endif + ; + } + +--- a/net/netfilter/Makefile ++++ b/net/netfilter/Makefile +@@ -15,6 +15,7 @@ nf_conntrack-$(CONFIG_NF_CONNTRACK_OVS) + nf_conntrack-$(CONFIG_NF_CT_PROTO_DCCP) += nf_conntrack_proto_dccp.o + nf_conntrack-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o + nf_conntrack-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o ++nf_conntrack-$(CONFIG_NF_CONNTRACK_DSCPREMARK_EXT) += nf_conntrack_dscpremark_ext.o + ifeq ($(CONFIG_NF_CONNTRACK),m) + nf_conntrack-$(CONFIG_DEBUG_INFO_BTF_MODULES) += nf_conntrack_bpf.o + else ifeq ($(CONFIG_NF_CONNTRACK),y) +--- a/net/netfilter/nf_conntrack_core.c ++++ b/net/netfilter/nf_conntrack_core.c +@@ -45,6 +45,9 @@ + #include + #include + #include ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++#include ++#endif + #include + #include + #include +@@ -1740,6 +1743,9 @@ init_conntrack(struct net *net, struct n + nf_ct_acct_ext_add(ct, GFP_ATOMIC); + nf_ct_tstamp_ext_add(ct, GFP_ATOMIC); + nf_ct_labels_ext_add(ct); ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ nf_ct_dscpremark_ext_add(ct, GFP_ATOMIC); ++#endif + + #ifdef CONFIG_NF_CONNTRACK_EVENTS + ecache = tmpl ? nf_ct_ecache_find(tmpl) : NULL; +--- a/net/netfilter/xt_DSCP.c ++++ b/net/netfilter/xt_DSCP.c +@@ -15,6 +15,9 @@ + + #include + #include ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++#include ++#endif + + MODULE_AUTHOR("Harald Welte "); + MODULE_DESCRIPTION("Xtables: DSCP/TOS field modification"); +@@ -31,6 +34,10 @@ dscp_tg(struct sk_buff *skb, const struc + { + const struct xt_DSCP_info *dinfo = par->targinfo; + u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT; ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ struct nf_conn *ct; ++ enum ip_conntrack_info ctinfo; ++#endif + + if (dscp != dinfo->dscp) { + if (skb_ensure_writable(skb, sizeof(struct iphdr))) +@@ -39,6 +46,13 @@ dscp_tg(struct sk_buff *skb, const struc + ipv4_change_dsfield(ip_hdr(skb), XT_DSCP_ECN_MASK, + dinfo->dscp << XT_DSCP_SHIFT); + ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ ct = nf_ct_get(skb, &ctinfo); ++ if (!ct) ++ return XT_CONTINUE; ++ ++ nf_conntrack_dscpremark_ext_set_dscp_rule_valid(ct); ++#endif + } + return XT_CONTINUE; + } +@@ -48,13 +62,24 @@ dscp_tg6(struct sk_buff *skb, const stru + { + const struct xt_DSCP_info *dinfo = par->targinfo; + u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT; +- ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ struct nf_conn *ct; ++ enum ip_conntrack_info ctinfo; ++#endif + if (dscp != dinfo->dscp) { + if (skb_ensure_writable(skb, sizeof(struct ipv6hdr))) + return NF_DROP; + + ipv6_change_dsfield(ipv6_hdr(skb), XT_DSCP_ECN_MASK, + dinfo->dscp << XT_DSCP_SHIFT); ++ ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ ct = nf_ct_get(skb, &ctinfo); ++ if (!ct) ++ return XT_CONTINUE; ++ ++ nf_conntrack_dscpremark_ext_set_dscp_rule_valid(ct); ++#endif + } + return XT_CONTINUE; + } diff --git a/target/linux/qualcommax/patches-6.6/0601-1-qca-add-nss-bridge-mgr-support.patch b/target/linux/qualcommax/patches-6.6/0601-1-qca-add-nss-bridge-mgr-support.patch new file mode 100644 index 00000000000000..dcfd78d5932a6a --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0601-1-qca-add-nss-bridge-mgr-support.patch @@ -0,0 +1,92 @@ +From 3c17a0e1112be70071e98d5208da5b55dcec20a6 Mon Sep 17 00:00:00 2001 +From: Simon Casey +Date: Wed, 2 Feb 2022 19:37:29 +0100 +Subject: [PATCH] Update 607-qca-add-add-nss-bridge-mgr-support.patch for kernel 5.15 + +--- + include/linux/if_bridge.h | 4 ++++ + net/bridge/br_fdb.c | 25 +++++++++++++++++++++---- + 2 files changed, 25 insertions(+), 4 deletions(-) + +--- a/include/linux/if_bridge.h ++++ b/include/linux/if_bridge.h +@@ -254,4 +254,8 @@ typedef struct net_bridge_port *br_get_d + extern br_get_dst_hook_t __rcu *br_get_dst_hook; + /* QCA NSS ECM support - End */ + ++/* QCA NSS bridge-mgr support - Start */ ++extern struct net_device *br_fdb_bridge_dev_get_and_hold(struct net_bridge *br); ++/* QCA NSS bridge-mgr support - End */ ++ + #endif +--- a/net/bridge/br_fdb.c ++++ b/net/bridge/br_fdb.c +@@ -576,7 +576,7 @@ void br_fdb_cleanup(struct work_struct * + unsigned long delay = hold_time(br); + unsigned long work_delay = delay; + unsigned long now = jiffies; +- u8 mac_addr[6]; /* QCA NSS ECM support */ ++ struct br_fdb_event fdb_event; /* QCA NSS bridge-mgr support */ + + /* this part is tricky, in order to avoid blocking learning and + * consequently forwarding, we rely on rcu to delete objects with +@@ -604,12 +604,13 @@ void br_fdb_cleanup(struct work_struct * + } else { + spin_lock_bh(&br->hash_lock); + if (!hlist_unhashed(&f->fdb_node)) { +- ether_addr_copy(mac_addr, f->key.addr.addr); ++ memset(&fdb_event, 0, sizeof(fdb_event)); ++ ether_addr_copy(fdb_event.addr, f->key.addr.addr); + fdb_delete(br, f, true); + /* QCA NSS ECM support - Start */ + atomic_notifier_call_chain( + &br_fdb_update_notifier_list, 0, +- (void *)mac_addr); ++ (void *)&fdb_event); + /* QCA NSS ECM support - End */ + } + spin_unlock_bh(&br->hash_lock); +@@ -907,10 +908,21 @@ static bool __fdb_mark_active(struct net + test_and_clear_bit(BR_FDB_NOTIFY_INACTIVE, &fdb->flags)); + } + ++/* QCA NSS bridge-mgr support - Start */ ++/* Get the bridge device */ ++struct net_device *br_fdb_bridge_dev_get_and_hold(struct net_bridge *br) ++{ ++ dev_hold(br->dev); ++ return br->dev; ++} ++EXPORT_SYMBOL_GPL(br_fdb_bridge_dev_get_and_hold); ++/* QCA NSS bridge-mgr support - End */ ++ + void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, + const unsigned char *addr, u16 vid, unsigned long flags) + { + struct net_bridge_fdb_entry *fdb; ++ struct br_fdb_event fdb_event; /* QCA NSS bridge-mgr support */ + + /* some users want to always flood. */ + if (hold_time(br) == 0) +@@ -936,6 +948,12 @@ void br_fdb_update(struct net_bridge *br + if (unlikely(source != READ_ONCE(fdb->dst) && + !test_bit(BR_FDB_STICKY, &fdb->flags))) { + br_switchdev_fdb_notify(br, fdb, RTM_DELNEIGH); ++ /* QCA NSS bridge-mgr support - Start */ ++ ether_addr_copy(fdb_event.addr, addr); ++ fdb_event.br = br; ++ fdb_event.orig_dev = fdb->dst->dev; ++ fdb_event.dev = source->dev; ++ /* QCA NSS bridge-mgr support - End */ + WRITE_ONCE(fdb->dst, source); + fdb_modified = true; + /* Take over HW learned entry */ +@@ -952,7 +970,7 @@ void br_fdb_update(struct net_bridge *br + /* QCA NSS ECM support - Start */ + atomic_notifier_call_chain( + &br_fdb_update_notifier_list, +- 0, (void *)addr); ++ 0, (void *)&fdb_event); + /* QCA NSS ECM support - End */ + } + diff --git a/target/linux/qualcommax/patches-6.6/0602-1-qca-nss-drv-add-qdisc-support.patch b/target/linux/qualcommax/patches-6.6/0602-1-qca-nss-drv-add-qdisc-support.patch new file mode 100644 index 00000000000000..2926faacefebd7 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0602-1-qca-nss-drv-add-qdisc-support.patch @@ -0,0 +1,25 @@ +--- a/include/uapi/linux/pkt_cls.h ++++ b/include/uapi/linux/pkt_cls.h +@@ -139,6 +139,7 @@ enum tca_id { + TCA_ID_MPLS, + TCA_ID_CT, + TCA_ID_GATE, ++ TCA_ID_MIRRED_NSS, /* QCA NSS Qdisc IGS Support */ + /* other actions go here */ + __TCA_ID_MAX = 255 + }; +@@ -817,4 +818,14 @@ enum { + TCF_EM_OPND_LT + }; + ++/* QCA NSS Qdisc Support - Start */ ++#define _TC_MAKE32(x) ((x)) ++#define _TC_MAKEMASK1(n) (_TC_MAKE32(1) << _TC_MAKE32(n)) ++ ++#define TC_NCLS _TC_MAKEMASK1(8) ++#define TC_NCLS_NSS _TC_MAKEMASK1(12) ++#define SET_TC_NCLS_NSS(v) ( TC_NCLS_NSS | ((v) & ~TC_NCLS_NSS)) ++#define CLR_TC_NCLS_NSS(v) ( (v) & ~TC_NCLS_NSS) ++/* QCA NSS Qdisc Support - End */ ++ + #endif diff --git a/target/linux/qualcommax/patches-6.6/0603-1-qca-nss-clients-add-qdisc-support.patch b/target/linux/qualcommax/patches-6.6/0603-1-qca-nss-clients-add-qdisc-support.patch new file mode 100644 index 00000000000000..9220aca1c78be7 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0603-1-qca-nss-clients-add-qdisc-support.patch @@ -0,0 +1,463 @@ +--- a/include/linux/timer.h ++++ b/include/linux/timer.h +@@ -17,6 +17,7 @@ struct timer_list { + unsigned long expires; + void (*function)(struct timer_list *); + u32 flags; ++ unsigned long cust_data; + + #ifdef CONFIG_LOCKDEP + struct lockdep_map lockdep_map; +--- a/drivers/net/ifb.c ++++ b/drivers/net/ifb.c +@@ -151,6 +151,31 @@ resched: + + } + ++void ifb_update_offload_stats(struct net_device *dev, struct pcpu_sw_netstats *offload_stats) ++{ ++ struct ifb_dev_private *dp; ++ struct ifb_q_private *txp; ++ ++ if (!dev || !offload_stats) { ++ return; ++ } ++ ++ if (!(dev->priv_flags_ext & IFF_EXT_IFB)) { ++ return; ++ } ++ ++ dp = netdev_priv(dev); ++ txp = dp->tx_private; ++ ++ u64_stats_update_begin(&txp->rx_stats.sync); ++ txp->rx_stats.packets += u64_stats_read(&offload_stats->rx_packets); ++ txp->rx_stats.bytes += u64_stats_read(&offload_stats->rx_bytes); ++ txp->tx_stats.packets += u64_stats_read(&offload_stats->tx_packets); ++ txp->tx_stats.bytes += u64_stats_read(&offload_stats->tx_bytes); ++ u64_stats_update_end(&txp->rx_stats.sync); ++} ++EXPORT_SYMBOL(ifb_update_offload_stats); ++ + static void ifb_stats64(struct net_device *dev, + struct rtnl_link_stats64 *stats) + { +@@ -326,6 +351,7 @@ static void ifb_setup(struct net_device + dev->flags |= IFF_NOARP; + dev->flags &= ~IFF_MULTICAST; + dev->priv_flags &= ~IFF_TX_SKB_SHARING; ++ dev->priv_flags_ext |= IFF_EXT_IFB; /* Mark the device as an IFB device. */ + netif_keep_dst(dev); + eth_hw_addr_random(dev); + dev->needs_free_netdev = true; +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -4696,6 +4696,15 @@ void dev_uc_flush(struct net_device *dev + void dev_uc_init(struct net_device *dev); + + /** ++ * ifb_update_offload_stats - Update the IFB interface stats ++ * @dev: IFB device to update the stats ++ * @offload_stats: per CPU stats structure ++ * ++ * Allows update of IFB stats when flows are offloaded to an accelerator. ++ **/ ++void ifb_update_offload_stats(struct net_device *dev, struct pcpu_sw_netstats *offload_stats); ++ ++/** + * __dev_uc_sync - Synchonize device's unicast list + * @dev: device to sync + * @sync: function to call if address should be added +@@ -5222,6 +5231,11 @@ static inline bool netif_is_failover_sla + return dev->priv_flags & IFF_FAILOVER_SLAVE; + } + ++static inline bool netif_is_ifb_dev(const struct net_device *dev) ++{ ++ return dev->priv_flags_ext & IFF_EXT_IFB; ++} ++ + /* This device needs to keep skb dst for qdisc enqueue or ndo_start_xmit() */ + static inline void netif_keep_dst(struct net_device *dev) + { +--- a/include/uapi/linux/pkt_sched.h ++++ b/include/uapi/linux/pkt_sched.h +@@ -1306,4 +1306,248 @@ enum { + + #define TCA_ETS_MAX (__TCA_ETS_MAX - 1) + ++/* QCA NSS Clients Support - Start */ ++enum { ++ TCA_NSS_ACCEL_MODE_NSS_FW, ++ TCA_NSS_ACCEL_MODE_PPE, ++ TCA_NSS_ACCEL_MODE_MAX ++}; ++ ++/* NSSFIFO section */ ++ ++enum { ++ TCA_NSSFIFO_UNSPEC, ++ TCA_NSSFIFO_PARMS, ++ __TCA_NSSFIFO_MAX ++}; ++ ++#define TCA_NSSFIFO_MAX (__TCA_NSSFIFO_MAX - 1) ++ ++struct tc_nssfifo_qopt { ++ __u32 limit; /* Queue length: bytes for bfifo, packets for pfifo */ ++ __u8 set_default; /* Sets qdisc to be the default qdisc for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSWRED section */ ++ ++enum { ++ TCA_NSSWRED_UNSPEC, ++ TCA_NSSWRED_PARMS, ++ __TCA_NSSWRED_MAX ++}; ++ ++#define TCA_NSSWRED_MAX (__TCA_NSSWRED_MAX - 1) ++#define NSSWRED_CLASS_MAX 6 ++struct tc_red_alg_parameter { ++ __u32 min; /* qlen_avg < min: pkts are all enqueued */ ++ __u32 max; /* qlen_avg > max: pkts are all dropped */ ++ __u32 probability;/* Drop probability at qlen_avg = max */ ++ __u32 exp_weight_factor;/* exp_weight_factor for calculate qlen_avg */ ++}; ++ ++struct tc_nsswred_traffic_class { ++ __u32 limit; /* Queue length */ ++ __u32 weight_mode_value; /* Weight mode value */ ++ struct tc_red_alg_parameter rap;/* Parameters for RED alg */ ++}; ++ ++/* ++ * Weight modes for WRED ++ */ ++enum tc_nsswred_weight_modes { ++ TC_NSSWRED_WEIGHT_MODE_DSCP = 0,/* Weight mode is DSCP */ ++ TC_NSSWRED_WEIGHT_MODES, /* Must be last */ ++}; ++ ++struct tc_nsswred_qopt { ++ __u32 limit; /* Queue length */ ++ enum tc_nsswred_weight_modes weight_mode; ++ /* Weight mode */ ++ __u32 traffic_classes; /* How many traffic classes: DPs */ ++ __u32 def_traffic_class; /* Default traffic if no match: def_DP */ ++ __u32 traffic_id; /* The traffic id to be configured: DP */ ++ __u32 weight_mode_value; /* Weight mode value */ ++ struct tc_red_alg_parameter rap;/* RED algorithm parameters */ ++ struct tc_nsswred_traffic_class tntc[NSSWRED_CLASS_MAX]; ++ /* Traffic settings for dumpping */ ++ __u8 ecn; /* Setting ECN bit or dropping */ ++ __u8 set_default; /* Sets qdisc to be the default for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSCODEL section */ ++ ++enum { ++ TCA_NSSCODEL_UNSPEC, ++ TCA_NSSCODEL_PARMS, ++ __TCA_NSSCODEL_MAX ++}; ++ ++#define TCA_NSSCODEL_MAX (__TCA_NSSCODEL_MAX - 1) ++ ++struct tc_nsscodel_qopt { ++ __u32 target; /* Acceptable queueing delay */ ++ __u32 limit; /* Max number of packets that can be held in the queue */ ++ __u32 interval; /* Monitoring interval */ ++ __u32 flows; /* Number of flow buckets */ ++ __u32 quantum; /* Weight (in bytes) used for DRR of flow buckets */ ++ __u8 ecn; /* 0 - disable ECN, 1 - enable ECN */ ++ __u8 set_default; /* Sets qdisc to be the default qdisc for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++struct tc_nsscodel_xstats { ++ __u32 peak_queue_delay; /* Peak delay experienced by a dequeued packet */ ++ __u32 peak_drop_delay; /* Peak delay experienced by a dropped packet */ ++}; ++ ++/* NSSFQ_CODEL section */ ++ ++struct tc_nssfq_codel_xstats { ++ __u32 new_flow_count; /* Total number of new flows seen */ ++ __u32 new_flows_len; /* Current number of new flows */ ++ __u32 old_flows_len; /* Current number of old flows */ ++ __u32 ecn_mark; /* Number of packets marked with ECN */ ++ __u32 drop_overlimit; /* Number of packets dropped due to overlimit */ ++ __u32 maxpacket; /* The largest packet seen so far in the queue */ ++}; ++ ++/* NSSTBL section */ ++ ++enum { ++ TCA_NSSTBL_UNSPEC, ++ TCA_NSSTBL_PARMS, ++ __TCA_NSSTBL_MAX ++}; ++ ++#define TCA_NSSTBL_MAX (__TCA_NSSTBL_MAX - 1) ++ ++struct tc_nsstbl_qopt { ++ __u32 burst; /* Maximum burst size */ ++ __u32 rate; /* Limiting rate of TBF */ ++ __u32 peakrate; /* Maximum rate at which TBF is allowed to send */ ++ __u32 mtu; /* Max size of packet, or minumim burst size */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSPRIO section */ ++ ++#define TCA_NSSPRIO_MAX_BANDS 256 ++ ++enum { ++ TCA_NSSPRIO_UNSPEC, ++ TCA_NSSPRIO_PARMS, ++ __TCA_NSSPRIO_MAX ++}; ++ ++#define TCA_NSSPRIO_MAX (__TCA_NSSPRIO_MAX - 1) ++ ++struct tc_nssprio_qopt { ++ __u32 bands; /* Number of bands */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSBF section */ ++ ++enum { ++ TCA_NSSBF_UNSPEC, ++ TCA_NSSBF_CLASS_PARMS, ++ TCA_NSSBF_QDISC_PARMS, ++ __TCA_NSSBF_MAX ++}; ++ ++#define TCA_NSSBF_MAX (__TCA_NSSBF_MAX - 1) ++ ++struct tc_nssbf_class_qopt { ++ __u32 burst; /* Maximum burst size */ ++ __u32 rate; /* Allowed bandwidth for this class */ ++ __u32 mtu; /* MTU of the associated interface */ ++ __u32 quantum; /* Quantum allocation for DRR */ ++}; ++ ++struct tc_nssbf_qopt { ++ __u16 defcls; /* Default class value */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSWRR section */ ++ ++enum { ++ TCA_NSSWRR_UNSPEC, ++ TCA_NSSWRR_CLASS_PARMS, ++ TCA_NSSWRR_QDISC_PARMS, ++ __TCA_NSSWRR_MAX ++}; ++ ++#define TCA_NSSWRR_MAX (__TCA_NSSWRR_MAX - 1) ++ ++struct tc_nsswrr_class_qopt { ++ __u32 quantum; /* Weight associated to this class */ ++}; ++ ++struct tc_nsswrr_qopt { ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSWFQ section */ ++ ++enum { ++ TCA_NSSWFQ_UNSPEC, ++ TCA_NSSWFQ_CLASS_PARMS, ++ TCA_NSSWFQ_QDISC_PARMS, ++ __TCA_NSSWFQ_MAX ++}; ++ ++#define TCA_NSSWFQ_MAX (__TCA_NSSWFQ_MAX - 1) ++ ++struct tc_nsswfq_class_qopt { ++ __u32 quantum; /* Weight associated to this class */ ++}; ++ ++struct tc_nsswfq_qopt { ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSHTB section */ ++ ++enum { ++ TCA_NSSHTB_UNSPEC, ++ TCA_NSSHTB_CLASS_PARMS, ++ TCA_NSSHTB_QDISC_PARMS, ++ __TCA_NSSHTB_MAX ++}; ++ ++#define TCA_NSSHTB_MAX (__TCA_NSSHTB_MAX - 1) ++ ++struct tc_nsshtb_class_qopt { ++ __u32 burst; /* Allowed burst size */ ++ __u32 rate; /* Allowed bandwidth for this class */ ++ __u32 cburst; /* Maximum burst size */ ++ __u32 crate; /* Maximum bandwidth for this class */ ++ __u32 quantum; /* Quantum allocation for DRR */ ++ __u32 priority; /* Priority value associated with this class */ ++ __u32 overhead; /* Overhead in bytes per packet */ ++}; ++ ++struct tc_nsshtb_qopt { ++ __u32 r2q; /* Rate to quantum ratio */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSBLACKHOLE section */ ++ ++enum { ++ TCA_NSSBLACKHOLE_UNSPEC, ++ TCA_NSSBLACKHOLE_PARMS, ++ __TCA_NSSBLACKHOLE_MAX ++}; ++ ++#define TCA_NSSBLACKHOLE_MAX (__TCA_NSSBLACKHOLE_MAX - 1) ++ ++struct tc_nssblackhole_qopt { ++ __u8 set_default; /* Sets qdisc to be the default qdisc for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++/* QCA NSS Clients Support - End */ + #endif +--- a/net/sched/sch_api.c ++++ b/net/sched/sch_api.c +@@ -314,6 +314,7 @@ struct Qdisc *qdisc_lookup(struct net_de + out: + return q; + } ++EXPORT_SYMBOL(qdisc_lookup); + + struct Qdisc *qdisc_lookup_rcu(struct net_device *dev, u32 handle) + { +@@ -2389,4 +2390,26 @@ static int __init pktsched_init(void) + return 0; + } + ++/* QCA NSS Qdisc Support - Start */ ++bool tcf_destroy(struct tcf_proto *tp, bool force) ++{ ++ tp->ops->destroy(tp, force, NULL); ++ module_put(tp->ops->owner); ++ kfree_rcu(tp, rcu); ++ ++ return true; ++} ++ ++void tcf_destroy_chain(struct tcf_proto __rcu **fl) ++{ ++ struct tcf_proto *tp; ++ ++ while ((tp = rtnl_dereference(*fl)) != NULL) { ++ RCU_INIT_POINTER(*fl, tp->next); ++ tcf_destroy(tp, true); ++ } ++} ++EXPORT_SYMBOL(tcf_destroy_chain); ++/* QCA NSS Qdisc Support - End */ ++ + subsys_initcall(pktsched_init); +--- a/net/sched/sch_generic.c ++++ b/net/sched/sch_generic.c +@@ -1069,6 +1069,7 @@ static void __qdisc_destroy(struct Qdisc + + call_rcu(&qdisc->rcu, qdisc_free_cb); + } ++EXPORT_SYMBOL(qdisc_destroy); + + void qdisc_destroy(struct Qdisc *qdisc) + { +--- a/include/net/sch_generic.h ++++ b/include/net/sch_generic.h +@@ -94,6 +94,7 @@ struct Qdisc { + #define TCQ_F_INVISIBLE 0x80 /* invisible by default in dump */ + #define TCQ_F_NOLOCK 0x100 /* qdisc does not require locking */ + #define TCQ_F_OFFLOADED 0x200 /* qdisc is offloaded to HW */ ++#define TCQ_F_NSS 0x1000 /* NSS qdisc flag. */ + u32 limit; + const struct Qdisc_ops *ops; + struct qdisc_size_table __rcu *stab; +@@ -751,6 +752,42 @@ static inline bool skb_skip_tc_classify( + return false; + } + ++/* QCA NSS Qdisc Support - Start */ ++/* ++ * Set skb classify bit field. ++ */ ++static inline void skb_set_tc_classify_offload(struct sk_buff *skb) ++{ ++#ifdef CONFIG_NET_CLS_ACT ++ skb->tc_skip_classify_offload = 1; ++#endif ++} ++ ++/* ++ * Clear skb classify bit field. ++ */ ++static inline void skb_clear_tc_classify_offload(struct sk_buff *skb) ++{ ++#ifdef CONFIG_NET_CLS_ACT ++ skb->tc_skip_classify_offload = 0; ++#endif ++} ++ ++/* ++ * Skip skb processing if sent from ifb dev. ++ */ ++static inline bool skb_skip_tc_classify_offload(struct sk_buff *skb) ++{ ++#ifdef CONFIG_NET_CLS_ACT ++ if (skb->tc_skip_classify_offload) { ++ skb_clear_tc_classify_offload(skb); ++ return true; ++ } ++#endif ++ return false; ++} ++/* QCA NSS Qdisc Support - End */ ++ + /* Reset all TX qdiscs greater than index of a device. */ + static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i) + { +@@ -1323,4 +1360,9 @@ static inline void qdisc_synchronize(con + msleep(1); + } + ++/* QCA NSS Qdisc Support - Start */ ++void qdisc_destroy(struct Qdisc *qdisc); ++void tcf_destroy_chain(struct tcf_proto __rcu **fl); ++/* QCA NSS Qdisc Support - End */ ++ + #endif +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -764,6 +764,7 @@ typedef unsigned char *sk_buff_data_t; + * @offload_fwd_mark: Packet was L2-forwarded in hardware + * @offload_l3_fwd_mark: Packet was L3-forwarded in hardware + * @tc_skip_classify: do not classify packet. set by IFB device ++ * @tc_skip_classify_offload: do not classify packet set by offload IFB device + * @tc_at_ingress: used within tc_classify to distinguish in/egress + * @redirected: packet was redirected by packet classifier + * @from_ingress: packet was redirected from the ingress path +@@ -945,6 +946,9 @@ struct sk_buff { + __u8 tc_at_ingress:1; /* See TC_AT_INGRESS_MASK */ + __u8 tc_skip_classify:1; + #endif ++#ifdef CONFIG_NET_CLS_ACT ++ __u8 tc_skip_classify_offload:1; /* QCA NSS Qdisc Support */ ++#endif + __u8 remcsum_offload:1; + __u8 csum_complete_sw:1; + __u8 csum_level:2; diff --git a/target/linux/qualcommax/patches-6.6/0603-2-qca-nss-clients-add-l2tp-support.patch b/target/linux/qualcommax/patches-6.6/0603-2-qca-nss-clients-add-l2tp-support.patch new file mode 100644 index 00000000000000..7fa9184df25155 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0603-2-qca-nss-clients-add-l2tp-support.patch @@ -0,0 +1,46 @@ +--- a/net/l2tp/l2tp_core.c ++++ b/net/l2tp/l2tp_core.c +@@ -398,6 +398,31 @@ err_tlock: + } + EXPORT_SYMBOL_GPL(l2tp_session_register); + ++void l2tp_stats_update(struct l2tp_tunnel *tunnel, ++ struct l2tp_session *session, ++ struct l2tp_stats *stats) ++{ ++ atomic_long_add(atomic_long_read(&stats->rx_packets), ++ &tunnel->stats.rx_packets); ++ atomic_long_add(atomic_long_read(&stats->rx_bytes), ++ &tunnel->stats.rx_bytes); ++ atomic_long_add(atomic_long_read(&stats->tx_packets), ++ &tunnel->stats.tx_packets); ++ atomic_long_add(atomic_long_read(&stats->tx_bytes), ++ &tunnel->stats.tx_bytes); ++ ++ atomic_long_add(atomic_long_read(&stats->rx_packets), ++ &session->stats.rx_packets); ++ atomic_long_add(atomic_long_read(&stats->rx_bytes), ++ &session->stats.rx_bytes); ++ atomic_long_add(atomic_long_read(&stats->tx_packets), ++ &session->stats.tx_packets); ++ atomic_long_add(atomic_long_read(&stats->tx_bytes), ++ &session->stats.tx_bytes); ++} ++EXPORT_SYMBOL_GPL(l2tp_stats_update); ++ ++ + /***************************************************************************** + * Receive data handling + *****************************************************************************/ +--- a/net/l2tp/l2tp_core.h ++++ b/net/l2tp/l2tp_core.h +@@ -232,6 +232,9 @@ struct l2tp_session *l2tp_session_get_nt + struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net, + const char *ifname); + ++void l2tp_stats_update(struct l2tp_tunnel *tunnel, struct l2tp_session *session, ++ struct l2tp_stats *stats); ++ + /* Tunnel and session lifetime management. + * Creation of a new instance is a two-step process: create, then register. + * Destruction is triggered using the *_delete functions, and completes asynchronously. diff --git a/target/linux/qualcommax/patches-6.6/0603-3-qca-nss-clients-add-PPTP-support.patch b/target/linux/qualcommax/patches-6.6/0603-3-qca-nss-clients-add-PPTP-support.patch new file mode 100644 index 00000000000000..5fb9917bc9067e --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0603-3-qca-nss-clients-add-PPTP-support.patch @@ -0,0 +1,478 @@ +--- a/include/linux/if_pppox.h ++++ b/include/linux/if_pppox.h +@@ -36,6 +36,7 @@ struct pptp_opt { + u32 ack_sent, ack_recv; + u32 seq_sent, seq_recv; + int ppp_flags; ++ bool pptp_offload_mode; + }; + #include + +@@ -100,8 +101,40 @@ struct pppoe_channel_ops { + int (*get_addressing)(struct ppp_channel *, struct pppoe_opt *); + }; + ++/* PPTP client callback */ ++typedef int (*pptp_gre_seq_offload_callback_t)(struct sk_buff *skb, ++ struct net_device *pptp_dev); ++ + /* Return PPPoE channel specific addressing information */ + extern int pppoe_channel_addressing_get(struct ppp_channel *chan, + struct pppoe_opt *addressing); + ++/* Lookup PPTP session info and return PPTP session using sip, dip and local call id */ ++extern int pptp_session_find_by_src_callid(struct pptp_opt *opt, __be16 src_call_id, ++ __be32 daddr, __be32 saddr); ++ ++/* Lookup PPTP session info and return PPTP session using dip and peer call id */ ++extern int pptp_session_find(struct pptp_opt *opt, __be16 peer_call_id, ++ __be32 peer_ip_addr); ++ ++/* Return PPTP session information given the channel */ ++extern void pptp_channel_addressing_get(struct pptp_opt *opt, ++ struct ppp_channel *chan); ++ ++/* Enable the PPTP session offload flag */ ++extern int pptp_session_enable_offload_mode(__be16 peer_call_id, ++ __be32 peer_ip_addr); ++ ++/* Disable the PPTP session offload flag */ ++extern int pptp_session_disable_offload_mode(__be16 peer_call_id, ++ __be32 peer_ip_addr); ++ ++/* Register the PPTP GRE packets sequence number offload callback */ ++extern int ++pptp_register_gre_seq_offload_callback(pptp_gre_seq_offload_callback_t ++ pptp_client_cb); ++ ++/* Unregister the PPTP GRE packets sequence number offload callback */ ++extern void pptp_unregister_gre_seq_offload_callback(void); ++ + #endif /* !(__LINUX_IF_PPPOX_H) */ +--- a/drivers/net/ppp/ppp_generic.c ++++ b/drivers/net/ppp/ppp_generic.c +@@ -2973,6 +2973,20 @@ char *ppp_dev_name(struct ppp_channel *c + return name; + } + ++/* Return the PPP net device index */ ++int ppp_dev_index(struct ppp_channel *chan) ++{ ++ struct channel *pch = chan->ppp; ++ int ifindex = 0; ++ ++ if (pch) { ++ read_lock_bh(&pch->upl); ++ if (pch->ppp && pch->ppp->dev) ++ ifindex = pch->ppp->dev->ifindex; ++ read_unlock_bh(&pch->upl); ++ } ++ return ifindex; ++} + + /* + * Disconnect a channel from the generic layer. +@@ -3681,6 +3695,28 @@ void ppp_update_stats(struct net_device + ppp_recv_unlock(ppp); + } + ++/* Returns true if Compression is enabled on PPP device ++ */ ++bool ppp_is_cp_enabled(struct net_device *dev) ++{ ++ struct ppp *ppp; ++ bool flag = false; ++ ++ if (!dev) ++ return false; ++ ++ if (dev->type != ARPHRD_PPP) ++ return false; ++ ++ ppp = netdev_priv(dev); ++ ppp_lock(ppp); ++ flag = !!(ppp->xstate & SC_COMP_RUN) || !!(ppp->rstate & SC_DECOMP_RUN); ++ ppp_unlock(ppp); ++ ++ return flag; ++} ++EXPORT_SYMBOL(ppp_is_cp_enabled); ++ + /* Returns >0 if the device is a multilink PPP netdevice, 0 if not or < 0 if + * the device is not PPP. + */ +@@ -3872,6 +3908,7 @@ EXPORT_SYMBOL(ppp_unregister_channel); + EXPORT_SYMBOL(ppp_channel_index); + EXPORT_SYMBOL(ppp_unit_number); + EXPORT_SYMBOL(ppp_dev_name); ++EXPORT_SYMBOL(ppp_dev_index); + EXPORT_SYMBOL(ppp_input); + EXPORT_SYMBOL(ppp_input_error); + EXPORT_SYMBOL(ppp_output_wakeup); +--- a/include/linux/ppp_channel.h ++++ b/include/linux/ppp_channel.h +@@ -84,6 +84,9 @@ extern void ppp_unregister_channel(struc + /* Get the channel number for a channel */ + extern int ppp_channel_index(struct ppp_channel *); + ++/* Get the device index associated with a channel, or 0, if none */ ++extern int ppp_dev_index(struct ppp_channel *); ++ + /* Get the unit number associated with a channel, or -1 if none */ + extern int ppp_unit_number(struct ppp_channel *); + +@@ -116,6 +119,7 @@ extern int ppp_hold_channels(struct net_ + /* Test if ppp xmit lock is locked */ + extern bool ppp_is_xmit_locked(struct net_device *dev); + ++bool ppp_is_cp_enabled(struct net_device *dev); + /* Test if the ppp device is a multi-link ppp device */ + extern int ppp_is_multilink(struct net_device *dev); + +--- a/drivers/net/ppp/pptp.c ++++ b/drivers/net/ppp/pptp.c +@@ -50,6 +50,8 @@ static struct proto pptp_sk_proto __read + static const struct ppp_channel_ops pptp_chan_ops; + static const struct proto_ops pptp_ops; + ++static pptp_gre_seq_offload_callback_t __rcu pptp_gre_offload_xmit_cb; ++ + static struct pppox_sock *lookup_chan(u16 call_id, __be32 s_addr) + { + struct pppox_sock *sock; +@@ -91,6 +93,79 @@ static int lookup_chan_dst(u16 call_id, + return i < MAX_CALLID; + } + ++/* Search a pptp session based on local call id, local and remote ip address */ ++static int lookup_session_src(struct pptp_opt *opt, u16 call_id, __be32 daddr, __be32 saddr) ++{ ++ struct pppox_sock *sock; ++ int i = 1; ++ ++ rcu_read_lock(); ++ for_each_set_bit_from(i, callid_bitmap, MAX_CALLID) { ++ sock = rcu_dereference(callid_sock[i]); ++ if (!sock) ++ continue; ++ ++ if (sock->proto.pptp.src_addr.call_id == call_id && ++ sock->proto.pptp.dst_addr.sin_addr.s_addr == daddr && ++ sock->proto.pptp.src_addr.sin_addr.s_addr == saddr) { ++ sock_hold(sk_pppox(sock)); ++ memcpy(opt, &sock->proto.pptp, sizeof(struct pptp_opt)); ++ sock_put(sk_pppox(sock)); ++ rcu_read_unlock(); ++ return 0; ++ } ++ } ++ rcu_read_unlock(); ++ return -EINVAL; ++} ++ ++/* Search a pptp session based on peer call id and peer ip address */ ++static int lookup_session_dst(struct pptp_opt *opt, u16 call_id, __be32 d_addr) ++{ ++ struct pppox_sock *sock; ++ int i = 1; ++ ++ rcu_read_lock(); ++ for_each_set_bit_from(i, callid_bitmap, MAX_CALLID) { ++ sock = rcu_dereference(callid_sock[i]); ++ if (!sock) ++ continue; ++ ++ if (sock->proto.pptp.dst_addr.call_id == call_id && ++ sock->proto.pptp.dst_addr.sin_addr.s_addr == d_addr) { ++ sock_hold(sk_pppox(sock)); ++ memcpy(opt, &sock->proto.pptp, sizeof(struct pptp_opt)); ++ sock_put(sk_pppox(sock)); ++ rcu_read_unlock(); ++ return 0; ++ } ++ } ++ rcu_read_unlock(); ++ return -EINVAL; ++} ++ ++/* If offload mode set then this function sends all packets to ++ * offload module instead of network stack ++ */ ++static int pptp_client_skb_xmit(struct sk_buff *skb, ++ struct net_device *pptp_dev) ++{ ++ pptp_gre_seq_offload_callback_t pptp_gre_offload_cb_f; ++ int ret; ++ ++ rcu_read_lock(); ++ pptp_gre_offload_cb_f = rcu_dereference(pptp_gre_offload_xmit_cb); ++ ++ if (!pptp_gre_offload_cb_f) { ++ rcu_read_unlock(); ++ return -1; ++ } ++ ++ ret = pptp_gre_offload_cb_f(skb, pptp_dev); ++ rcu_read_unlock(); ++ return ret; ++} ++ + static int add_chan(struct pppox_sock *sock, + struct pptp_addr *sa) + { +@@ -136,7 +211,7 @@ static struct rtable *pptp_route_output( + struct net *net; + + net = sock_net(sk); +- flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark, 0, ++ flowi4_init_output(fl4, 0, sk->sk_mark, 0, + RT_SCOPE_UNIVERSE, IPPROTO_GRE, 0, + po->proto.pptp.dst_addr.sin_addr.s_addr, + po->proto.pptp.src_addr.sin_addr.s_addr, +@@ -163,8 +238,11 @@ static int pptp_xmit(struct ppp_channel + + struct rtable *rt; + struct net_device *tdev; ++ struct net_device *pptp_dev; + struct iphdr *iph; + int max_headroom; ++ int pptp_ifindex; ++ int ret; + + if (sk_pppox(po)->sk_state & PPPOX_DEAD) + goto tx_error; +@@ -258,7 +336,32 @@ static int pptp_xmit(struct ppp_channel + ip_select_ident(net, skb, NULL); + ip_send_check(iph); + +- ip_local_out(net, skb->sk, skb); ++ pptp_ifindex = ppp_dev_index(chan); ++ ++ /* set incoming interface as the ppp interface */ ++ if (skb->skb_iif) ++ skb->skb_iif = pptp_ifindex; ++ ++ /* If the PPTP GRE seq number offload module is not enabled yet ++ * then sends all PPTP GRE packets through linux network stack ++ */ ++ if (!opt->pptp_offload_mode) { ++ ip_local_out(net, skb->sk, skb); ++ return 1; ++ } ++ ++ pptp_dev = dev_get_by_index(&init_net, pptp_ifindex); ++ if (!pptp_dev) ++ goto tx_error; ++ ++ /* If PPTP offload module is enabled then forward all PPTP GRE ++ * packets to PPTP GRE offload module ++ */ ++ ret = pptp_client_skb_xmit(skb, pptp_dev); ++ dev_put(pptp_dev); ++ if (ret < 0) ++ goto tx_error; ++ + return 1; + + tx_error: +@@ -314,6 +417,13 @@ static int pptp_rcv_core(struct sock *sk + goto drop; + + payload = skb->data + headersize; ++ ++ /* If offload is enabled, we expect the offload module ++ * to handle PPTP GRE sequence number checks ++ */ ++ if (opt->pptp_offload_mode) ++ goto allow_packet; ++ + /* check for expected sequence number */ + if (seq < opt->seq_recv + 1 || WRAPPED(opt->seq_recv, seq)) { + if ((payload[0] == PPP_ALLSTATIONS) && (payload[1] == PPP_UI) && +@@ -371,6 +481,7 @@ static int pptp_rcv(struct sk_buff *skb) + if (po) { + skb_dst_drop(skb); + nf_reset_ct(skb); ++ skb->skb_iif = ppp_dev_index(&po->chan); + return sk_receive_skb(sk_pppox(po), skb, 0); + } + drop: +@@ -473,7 +584,7 @@ static int pptp_connect(struct socket *s + + opt->dst_addr = sp->sa_addr.pptp; + sk->sk_state |= PPPOX_CONNECTED; +- ++ opt->pptp_offload_mode = false; + end: + release_sock(sk); + return error; +@@ -603,9 +714,169 @@ static int pptp_ppp_ioctl(struct ppp_cha + return err; + } + ++/* pptp_channel_addressing_get() ++ * Return PPTP channel specific addressing information. ++ */ ++void pptp_channel_addressing_get(struct pptp_opt *opt, struct ppp_channel *chan) ++{ ++ struct sock *sk; ++ struct pppox_sock *po; ++ ++ if (!opt) ++ return; ++ ++ sk = (struct sock *)chan->private; ++ if (!sk) ++ return; ++ ++ sock_hold(sk); ++ ++ /* This is very unlikely, but check the socket is connected state */ ++ if (unlikely(sock_flag(sk, SOCK_DEAD) || ++ !(sk->sk_state & PPPOX_CONNECTED))) { ++ sock_put(sk); ++ return; ++ } ++ ++ po = pppox_sk(sk); ++ memcpy(opt, &po->proto.pptp, sizeof(struct pptp_opt)); ++ sock_put(sk); ++} ++EXPORT_SYMBOL(pptp_channel_addressing_get); ++ ++/* pptp_session_find() ++ * Search and return a PPTP session info based on peer callid and IP ++ * address. The function accepts the parameters in network byte order. ++ */ ++int pptp_session_find(struct pptp_opt *opt, __be16 peer_call_id, ++ __be32 peer_ip_addr) ++{ ++ if (!opt) ++ return -EINVAL; ++ ++ return lookup_session_dst(opt, ntohs(peer_call_id), peer_ip_addr); ++} ++EXPORT_SYMBOL(pptp_session_find); ++ ++/* pptp_session_find_by_src_callid() ++ * Search and return a PPTP session info based on src callid and IP ++ * address. The function accepts the parameters in network byte order. ++ */ ++int pptp_session_find_by_src_callid(struct pptp_opt *opt, __be16 src_call_id, ++ __be32 daddr, __be32 saddr) ++{ ++ if (!opt) ++ return -EINVAL; ++ ++ return lookup_session_src(opt, ntohs(src_call_id), daddr, saddr); ++} ++EXPORT_SYMBOL(pptp_session_find_by_src_callid); ++ ++ /* Function to change the offload mode true/false for a PPTP session */ ++static int pptp_set_offload_mode(bool accel_mode, ++ __be16 peer_call_id, __be32 peer_ip_addr) ++{ ++ struct pppox_sock *sock; ++ int i = 1; ++ ++ rcu_read_lock(); ++ for_each_set_bit_from(i, callid_bitmap, MAX_CALLID) { ++ sock = rcu_dereference(callid_sock[i]); ++ if (!sock) ++ continue; ++ ++ if (sock->proto.pptp.dst_addr.call_id == peer_call_id && ++ sock->proto.pptp.dst_addr.sin_addr.s_addr == peer_ip_addr) { ++ sock_hold(sk_pppox(sock)); ++ sock->proto.pptp.pptp_offload_mode = accel_mode; ++ sock_put(sk_pppox(sock)); ++ rcu_read_unlock(); ++ return 0; ++ } ++ } ++ rcu_read_unlock(); ++ return -EINVAL; ++} ++ ++/* Enable the PPTP session offload flag */ ++int pptp_session_enable_offload_mode(__be16 peer_call_id, __be32 peer_ip_addr) ++{ ++ return pptp_set_offload_mode(true, peer_call_id, peer_ip_addr); ++} ++EXPORT_SYMBOL(pptp_session_enable_offload_mode); ++ ++/* Disable the PPTP session offload flag */ ++int pptp_session_disable_offload_mode(__be16 peer_call_id, __be32 peer_ip_addr) ++{ ++ return pptp_set_offload_mode(false, peer_call_id, peer_ip_addr); ++} ++EXPORT_SYMBOL(pptp_session_disable_offload_mode); ++ ++/* Register the offload callback function on behalf of the module which ++ * will own the sequence and acknowledgment number updates for all ++ * PPTP GRE packets. All PPTP GRE packets are then transmitted to this ++ * module after encapsulation in order to ensure the correct seq/ack ++ * fields are set in the packets before transmission. This is required ++ * when PPTP flows are offloaded to acceleration engines, in-order to ++ * ensure consistency in sequence and ack numbers between PPTP control ++ * (PPP LCP) and data packets ++ */ ++int pptp_register_gre_seq_offload_callback(pptp_gre_seq_offload_callback_t ++ pptp_gre_offload_cb) ++{ ++ pptp_gre_seq_offload_callback_t pptp_gre_offload_cb_f; ++ ++ rcu_read_lock(); ++ pptp_gre_offload_cb_f = rcu_dereference(pptp_gre_offload_xmit_cb); ++ ++ if (pptp_gre_offload_cb_f) { ++ rcu_read_unlock(); ++ return -1; ++ } ++ ++ rcu_assign_pointer(pptp_gre_offload_xmit_cb, pptp_gre_offload_cb); ++ rcu_read_unlock(); ++ return 0; ++} ++EXPORT_SYMBOL(pptp_register_gre_seq_offload_callback); ++ ++/* Unregister the PPTP GRE packets sequence number offload callback */ ++void pptp_unregister_gre_seq_offload_callback(void) ++{ ++ rcu_assign_pointer(pptp_gre_offload_xmit_cb, NULL); ++} ++EXPORT_SYMBOL(pptp_unregister_gre_seq_offload_callback); ++ ++/* pptp_hold_chan() */ ++static void pptp_hold_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_hold(sk); ++} ++ ++/* pptp_release_chan() */ ++static void pptp_release_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_put(sk); ++} ++ ++/* pptp_get_channel_protocol() ++ * Return the protocol type of the PPTP over PPP protocol ++ */ ++static int pptp_get_channel_protocol(struct ppp_channel *chan) ++{ ++ return PX_PROTO_PPTP; ++} ++ + static const struct ppp_channel_ops pptp_chan_ops = { + .start_xmit = pptp_xmit, + .ioctl = pptp_ppp_ioctl, ++ .get_channel_protocol = pptp_get_channel_protocol, ++ .hold = pptp_hold_chan, ++ .release = pptp_release_chan, + }; + + static struct proto pptp_sk_proto __read_mostly = { diff --git a/target/linux/qualcommax/patches-6.6/0603-4-qca-nss-clients-add-iptunnel-support.patch b/target/linux/qualcommax/patches-6.6/0603-4-qca-nss-clients-add-iptunnel-support.patch new file mode 100644 index 00000000000000..c9fc33686480ec --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0603-4-qca-nss-clients-add-iptunnel-support.patch @@ -0,0 +1,77 @@ +--- a/include/net/ip6_tunnel.h ++++ b/include/net/ip6_tunnel.h +@@ -36,6 +36,7 @@ struct __ip6_tnl_parm { + __u8 proto; /* tunnel protocol */ + __u8 encap_limit; /* encapsulation limit for tunnel */ + __u8 hop_limit; /* hop limit for tunnel */ ++ __u8 draft03; /* FMR using draft03 of map-e - QCA NSS Clients Support */ + bool collect_md; + __be32 flowinfo; /* traffic class and flowlabel for tunnel */ + __u32 flags; /* tunnel flags */ +--- a/include/net/ip_tunnels.h ++++ b/include/net/ip_tunnels.h +@@ -558,4 +558,9 @@ static inline void ip_tunnel_info_opts_s + + #endif /* CONFIG_INET */ + ++/* QCA NSS Clients Support - Start */ ++void ipip6_update_offload_stats(struct net_device *dev, void *ptr); ++void ip6_update_offload_stats(struct net_device *dev, void *ptr); ++/* QCA NSS Clients Support - End */ ++ + #endif /* __NET_IP_TUNNELS_H */ +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -2411,6 +2411,26 @@ nla_put_failure: + return -EMSGSIZE; + } + ++/* QCA NSS Client Support - Start */ ++/* ++ * Update offload stats ++ */ ++void ip6_update_offload_stats(struct net_device *dev, void *ptr) ++{ ++ struct pcpu_sw_netstats *tstats = per_cpu_ptr(dev->tstats, 0); ++ const struct pcpu_sw_netstats *offload_stats = ++ (struct pcpu_sw_netstats *)ptr; ++ ++ u64_stats_update_begin(&tstats->syncp); ++ u64_stats_add(&tstats->tx_packets, u64_stats_read(&offload_stats->tx_packets)); ++ u64_stats_add(&tstats->tx_bytes, u64_stats_read(&offload_stats->tx_bytes)); ++ u64_stats_add(&tstats->rx_packets, u64_stats_read(&offload_stats->rx_packets)); ++ u64_stats_add(&tstats->rx_bytes, u64_stats_read(&offload_stats->rx_bytes)); ++ u64_stats_update_end(&tstats->syncp); ++} ++EXPORT_SYMBOL(ip6_update_offload_stats); ++/* QCA NSS Client Support - End */ ++ + struct net *ip6_tnl_get_link_net(const struct net_device *dev) + { + struct ip6_tnl *tunnel = netdev_priv(dev); +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -1733,6 +1733,23 @@ nla_put_failure: + return -EMSGSIZE; + } + ++/* QCA NSS Clients Support - Start */ ++void ipip6_update_offload_stats(struct net_device *dev, void *ptr) ++{ ++ struct pcpu_sw_netstats *tstats = per_cpu_ptr(dev->tstats, 0); ++ const struct pcpu_sw_netstats *offload_stats = ++ (struct pcpu_sw_netstats *)ptr; ++ ++ u64_stats_update_begin(&tstats->syncp); ++ u64_stats_add(&tstats->tx_packets, u64_stats_read(&offload_stats->tx_packets)); ++ u64_stats_add(&tstats->tx_bytes, u64_stats_read(&offload_stats->tx_bytes)); ++ u64_stats_add(&tstats->rx_packets, u64_stats_read(&offload_stats->rx_packets)); ++ u64_stats_add(&tstats->rx_bytes, u64_stats_read(&offload_stats->rx_bytes)); ++ u64_stats_update_end(&tstats->syncp); ++} ++EXPORT_SYMBOL(ipip6_update_offload_stats); ++/* QCA NSS Clients Support - End */ ++ + static const struct nla_policy ipip6_policy[IFLA_IPTUN_MAX + 1] = { + [IFLA_IPTUN_LINK] = { .type = NLA_U32 }, + [IFLA_IPTUN_LOCAL] = { .type = NLA_U32 }, diff --git a/target/linux/qualcommax/patches-6.6/0603-5-qca-nss-clients-add-vxlan-support.patch b/target/linux/qualcommax/patches-6.6/0603-5-qca-nss-clients-add-vxlan-support.patch new file mode 100644 index 00000000000000..7d05fd1aff619c --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0603-5-qca-nss-clients-add-vxlan-support.patch @@ -0,0 +1,103 @@ +--- a/drivers/net/vxlan/vxlan_core.c ++++ b/drivers/net/vxlan/vxlan_core.c +@@ -29,6 +29,20 @@ + #include + #include + ++ATOMIC_NOTIFIER_HEAD(vxlan_fdb_notifier_list); ++ ++void vxlan_fdb_register_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_register(&vxlan_fdb_notifier_list, nb); ++} ++EXPORT_SYMBOL(vxlan_fdb_register_notify); ++ ++void vxlan_fdb_unregister_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_unregister(&vxlan_fdb_notifier_list, nb); ++} ++EXPORT_SYMBOL(vxlan_fdb_unregister_notify); ++ + #if IS_ENABLED(CONFIG_IPV6) + #include + #include +@@ -260,6 +274,7 @@ static void __vxlan_fdb_notify(struct vx + { + struct net *net = dev_net(vxlan->dev); + struct sk_buff *skb; ++ struct vxlan_fdb_event vfe; + int err = -ENOBUFS; + + skb = nlmsg_new(vxlan_nlmsg_size(), GFP_ATOMIC); +@@ -275,6 +290,10 @@ static void __vxlan_fdb_notify(struct vx + } + + rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); ++ vfe.dev = vxlan->dev; ++ vfe.rdst = rd; ++ ether_addr_copy(vfe.eth_addr, fdb->eth_addr); ++ atomic_notifier_call_chain(&vxlan_fdb_notifier_list, type, (void *)&vfe); + return; + errout: + if (err < 0) +@@ -441,6 +460,18 @@ static struct vxlan_fdb *vxlan_find_mac( + return f; + } + ++/* Find and update age of fdb entry corresponding to MAC. */ ++void vxlan_fdb_update_mac(struct vxlan_dev *vxlan, const u8 *mac, uint32_t vni) ++{ ++ u32 hash_index; ++ ++ hash_index = fdb_head_index(vxlan, mac, vni); ++ spin_lock_bh(&vxlan->hash_lock[hash_index]); ++ vxlan_find_mac(vxlan, mac, vni); ++ spin_unlock_bh(&vxlan->hash_lock[hash_index]); ++} ++EXPORT_SYMBOL(vxlan_fdb_update_mac); ++ + /* caller should hold vxlan->hash_lock */ + static struct vxlan_rdst *vxlan_fdb_find_rdst(struct vxlan_fdb *f, + union vxlan_addr *ip, __be16 port, +@@ -2581,6 +2612,9 @@ void vxlan_xmit_one(struct sk_buff *skb, + goto out_unlock; + } + ++ /* Reset the skb_iif to Tunnels interface index */ ++ skb->skb_iif = dev->ifindex; ++ + tos = ip_tunnel_ecn_encap(tos, old_iph, skb); + ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); + err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr), +@@ -2652,6 +2686,9 @@ void vxlan_xmit_one(struct sk_buff *skb, + if (err < 0) + goto tx_error; + ++ /* Reset the skb_iif to Tunnels interface index */ ++ skb->skb_iif = dev->ifindex; ++ + udp_tunnel6_xmit_skb(ndst, sock6->sock->sk, skb, dev, + &local_ip.sin6.sin6_addr, + &dst->sin6.sin6_addr, tos, ttl, +--- a/include/net/vxlan.h ++++ b/include/net/vxlan.h +@@ -352,6 +352,19 @@ struct vxlan_dev { + VXLAN_F_VNIFILTER | \ + VXLAN_F_LOCALBYPASS) + ++/* ++ * Application data for fdb notifier event ++ */ ++struct vxlan_fdb_event { ++ struct net_device *dev; ++ struct vxlan_rdst *rdst; ++ u8 eth_addr[ETH_ALEN]; ++}; ++ ++extern void vxlan_fdb_register_notify(struct notifier_block *nb); ++extern void vxlan_fdb_unregister_notify(struct notifier_block *nb); ++extern void vxlan_fdb_update_mac(struct vxlan_dev *vxlan, const u8 *mac, uint32_t vni); ++ + struct net_device *vxlan_dev_create(struct net *net, const char *name, + u8 name_assign_type, struct vxlan_config *conf); + diff --git a/target/linux/qualcommax/patches-6.6/0603-6-qca-nss-clients-add-l2tp-offloading-support.patch b/target/linux/qualcommax/patches-6.6/0603-6-qca-nss-clients-add-l2tp-offloading-support.patch new file mode 100644 index 00000000000000..4032eb3c227134 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0603-6-qca-nss-clients-add-l2tp-offloading-support.patch @@ -0,0 +1,368 @@ +--- a/include/linux/ppp_channel.h ++++ b/include/linux/ppp_channel.h +@@ -61,6 +61,51 @@ struct ppp_channel { + }; + + #ifdef __KERNEL__ ++/* Call this to obtain the underlying protocol of the PPP channel, ++ * e.g. PX_PROTO_OE ++ */ ++extern int ppp_channel_get_protocol(struct ppp_channel *); ++ ++/* Call this to hold a channel */ ++extern bool ppp_channel_hold(struct ppp_channel *); ++ ++/* Call this to release a hold you have upon a channel */ ++extern void ppp_channel_release(struct ppp_channel *); ++ ++/* Release hold on PPP channels */ ++extern void ppp_release_channels(struct ppp_channel *channels[], ++ unsigned int chan_sz); ++ ++/* Test if ppp xmit lock is locked */ ++extern bool ppp_is_xmit_locked(struct net_device *dev); ++ ++/* Call this get protocol version */ ++extern int ppp_channel_get_proto_version(struct ppp_channel *); ++ ++/* Get the device index associated with a channel, or 0, if none */ ++extern int ppp_dev_index(struct ppp_channel *); ++ ++/* Hold PPP channels for the PPP device */ ++extern int ppp_hold_channels(struct net_device *dev, ++ struct ppp_channel *channels[], ++ unsigned int chan_sz); ++extern int __ppp_hold_channels(struct net_device *dev, ++ struct ppp_channel *channels[], ++ unsigned int chan_sz); ++ ++/* Test if the ppp device is a multi-link ppp device */ ++extern int ppp_is_multilink(struct net_device *dev); ++extern int __ppp_is_multilink(struct net_device *dev); ++ ++/* Update statistics of the PPP net_device by incrementing related ++ * statistics field value with corresponding parameter ++ */ ++extern void ppp_update_stats(struct net_device *dev, unsigned long rx_packets, ++ unsigned long rx_bytes, unsigned long tx_packets, ++ unsigned long tx_bytes, unsigned long rx_errors, ++ unsigned long tx_errors, unsigned long rx_dropped, ++ unsigned long tx_dropped); ++ + /* Called by the channel when it can send some more data. */ + extern void ppp_output_wakeup(struct ppp_channel *); + +@@ -148,5 +193,17 @@ extern void ppp_update_stats(struct net_ + * that ppp_unregister_channel returns. + */ + ++/* QCA NSS Clients Support - Start */ ++/* PPP channel connection event types */ ++#define PPP_CHANNEL_DISCONNECT 0 ++#define PPP_CHANNEL_CONNECT 1 ++ ++/* Register the PPP channel connect notifier */ ++extern void ppp_channel_connection_register_notify(struct notifier_block *nb); ++ ++/* Unregister the PPP channel connect notifier */ ++extern void ppp_channel_connection_unregister_notify(struct notifier_block *nb); ++/* QCA NSS Clients Support - End */ ++ + #endif /* __KERNEL__ */ + #endif +--- a/include/linux/if_pppol2tp.h ++++ b/include/linux/if_pppol2tp.h +@@ -12,4 +12,30 @@ + #include + #include + ++/* QCA NSS ECM support - Start */ ++/* ++ * Holds L2TP channel info ++ */ ++struct pppol2tp_common_addr { ++ int tunnel_version; /* v2 or v3 */ ++ __u32 local_tunnel_id, remote_tunnel_id; /* tunnel id */ ++ __u32 local_session_id, remote_session_id; /* session id */ ++ struct sockaddr_in local_addr, remote_addr; /* ip address and port */ ++}; ++ ++/* ++ * L2TP channel operations ++ */ ++struct pppol2tp_channel_ops { ++ struct ppp_channel_ops ops; /* ppp channel ops */ ++}; ++ ++/* ++ * exported function which calls pppol2tp channel's get addressing ++ * function ++ */ ++extern int pppol2tp_channel_addressing_get(struct ppp_channel *, ++ struct pppol2tp_common_addr *); ++/* QCA NSS ECM support - End */ ++ + #endif +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -123,9 +123,17 @@ struct pppol2tp_session { + }; + + static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb); +- +-static const struct ppp_channel_ops pppol2tp_chan_ops = { +- .start_xmit = pppol2tp_xmit, ++static int pppol2tp_get_channel_protocol(struct ppp_channel *); ++static int pppol2tp_get_channel_protocol_ver(struct ppp_channel *); ++static void pppol2tp_hold_chan(struct ppp_channel *); ++static void pppol2tp_release_chan(struct ppp_channel *); ++ ++static const struct pppol2tp_channel_ops pppol2tp_chan_ops = { ++ .ops.start_xmit = pppol2tp_xmit, ++ .ops.get_channel_protocol = pppol2tp_get_channel_protocol, ++ .ops.get_channel_protocol_ver = pppol2tp_get_channel_protocol_ver, ++ .ops.hold = pppol2tp_hold_chan, ++ .ops.release = pppol2tp_release_chan, + }; + + static const struct proto_ops pppol2tp_ops; +@@ -373,6 +381,13 @@ static int pppol2tp_xmit(struct ppp_chan + skb->data[0] = PPP_ALLSTATIONS; + skb->data[1] = PPP_UI; + ++ /* QCA NSS ECM support - start */ ++ /* set incoming interface as the ppp interface */ ++ if ((skb->protocol == htons(ETH_P_IP)) || ++ (skb->protocol == htons(ETH_P_IPV6))) ++ skb->skb_iif = ppp_dev_index(chan); ++ /* QCA NSS ECM support - End */ ++ + local_bh_disable(); + l2tp_xmit_skb(session, skb); + local_bh_enable(); +@@ -818,7 +833,7 @@ static int pppol2tp_connect(struct socke + po->chan.hdrlen = PPPOL2TP_L2TP_HDR_SIZE_NOSEQ; + + po->chan.private = sk; +- po->chan.ops = &pppol2tp_chan_ops; ++ po->chan.ops = (struct ppp_channel_ops *)&pppol2tp_chan_ops.ops; + po->chan.mtu = pppol2tp_tunnel_mtu(tunnel); + + error = ppp_register_net_channel(sock_net(sk), &po->chan); +@@ -1732,6 +1747,109 @@ static void __exit pppol2tp_exit(void) + unregister_pernet_device(&pppol2tp_net_ops); + } + ++/* QCA NSS ECM support - Start */ ++/* pppol2tp_hold_chan() */ ++static void pppol2tp_hold_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_hold(sk); ++} ++ ++/* pppol2tp_release_chan() */ ++static void pppol2tp_release_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_put(sk); ++} ++ ++/* pppol2tp_get_channel_protocol() ++ * Return the protocol type of the L2TP over PPP protocol ++ */ ++static int pppol2tp_get_channel_protocol(struct ppp_channel *chan) ++{ ++ return PX_PROTO_OL2TP; ++} ++ ++/* pppol2tp_get_channel_protocol_ver() ++ * Return the protocol version of the L2TP over PPP protocol ++ */ ++static int pppol2tp_get_channel_protocol_ver(struct ppp_channel *chan) ++{ ++ struct sock *sk; ++ struct l2tp_session *session; ++ struct l2tp_tunnel *tunnel; ++ int version = 0; ++ ++ if (chan && chan->private) ++ sk = (struct sock *)chan->private; ++ else ++ return -1; ++ ++ /* Get session and tunnel contexts from the socket */ ++ session = pppol2tp_sock_to_session(sk); ++ if (!session) ++ return -1; ++ ++ tunnel = session->tunnel; ++ if (!tunnel) { ++ sock_put(sk); ++ return -1; ++ } ++ ++ version = tunnel->version; ++ ++ sock_put(sk); ++ ++ return version; ++} ++ ++/* pppol2tp_get_addressing() */ ++static int pppol2tp_get_addressing(struct ppp_channel *chan, ++ struct pppol2tp_common_addr *addr) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ struct l2tp_session *session; ++ struct l2tp_tunnel *tunnel; ++ struct inet_sock *isk = NULL; ++ int err = -ENXIO; ++ ++ /* Get session and tunnel contexts from the socket */ ++ session = pppol2tp_sock_to_session(sk); ++ if (!session) ++ return err; ++ ++ tunnel = session->tunnel; ++ if (!tunnel) { ++ sock_put(sk); ++ return err; ++ } ++ isk = inet_sk(tunnel->sock); ++ ++ addr->local_tunnel_id = tunnel->tunnel_id; ++ addr->remote_tunnel_id = tunnel->peer_tunnel_id; ++ addr->local_session_id = session->session_id; ++ addr->remote_session_id = session->peer_session_id; ++ ++ addr->local_addr.sin_port = isk->inet_sport; ++ addr->remote_addr.sin_port = isk->inet_dport; ++ addr->local_addr.sin_addr.s_addr = isk->inet_saddr; ++ addr->remote_addr.sin_addr.s_addr = isk->inet_daddr; ++ ++ sock_put(sk); ++ return 0; ++} ++ ++/* pppol2tp_channel_addressing_get() */ ++int pppol2tp_channel_addressing_get(struct ppp_channel *chan, ++ struct pppol2tp_common_addr *addr) ++{ ++ return pppol2tp_get_addressing(chan, addr); ++} ++EXPORT_SYMBOL(pppol2tp_channel_addressing_get); ++/* QCA NSS ECM support - End */ ++ + module_init(pppol2tp_init); + module_exit(pppol2tp_exit); + +--- a/drivers/net/ppp/ppp_generic.c ++++ b/drivers/net/ppp/ppp_generic.c +@@ -3743,6 +3743,32 @@ int ppp_is_multilink(struct net_device * + } + EXPORT_SYMBOL(ppp_is_multilink); + ++/* __ppp_is_multilink() ++ * Returns >0 if the device is a multilink PPP netdevice, 0 if not or < 0 ++ * if the device is not PPP. Caller should acquire ppp_lock before calling ++ * this function ++ */ ++int __ppp_is_multilink(struct net_device *dev) ++{ ++ struct ppp *ppp; ++ unsigned int flags; ++ ++ if (!dev) ++ return -1; ++ ++ if (dev->type != ARPHRD_PPP) ++ return -1; ++ ++ ppp = netdev_priv(dev); ++ flags = ppp->flags; ++ ++ if (flags & SC_MULTILINK) ++ return 1; ++ ++ return 0; ++} ++EXPORT_SYMBOL(__ppp_is_multilink); ++ + /* ppp_channel_get_protocol() + * Call this to obtain the underlying protocol of the PPP channel, + * e.g. PX_PROTO_OE +@@ -3881,6 +3907,59 @@ int ppp_hold_channels(struct net_device + } + EXPORT_SYMBOL(ppp_hold_channels); + ++/* __ppp_hold_channels() ++ * Returns the PPP channels of the PPP device, storing each one into ++ * channels[]. ++ * ++ * channels[] has chan_sz elements. ++ * This function returns the number of channels stored, up to chan_sz. ++ * It will return < 0 if the device is not PPP. ++ * ++ * You MUST release the channels using ppp_release_channels(). ++ */ ++int __ppp_hold_channels(struct net_device *dev, struct ppp_channel *channels[], ++ unsigned int chan_sz) ++{ ++ struct ppp *ppp; ++ int c; ++ struct channel *pch; ++ ++ if (!dev) ++ return -1; ++ ++ if (dev->type != ARPHRD_PPP) ++ return -1; ++ ++ ppp = netdev_priv(dev); ++ ++ c = 0; ++ list_for_each_entry(pch, &ppp->channels, clist) { ++ struct ppp_channel *chan; ++ ++ if (!pch->chan) { ++ /* Channel is going / gone away */ ++ continue; ++ } ++ ++ if (c == chan_sz) { ++ /* No space to record channel */ ++ return c; ++ } ++ ++ /* Hold the channel, if supported */ ++ chan = pch->chan; ++ if (!chan->ops->hold) ++ continue; ++ ++ chan->ops->hold(chan); ++ ++ /* Record the channel */ ++ channels[c++] = chan; ++ } ++ return c; ++} ++EXPORT_SYMBOL(__ppp_hold_channels); ++ + /* ppp_release_channels() + * Releases channels + */ +--- a/net/l2tp/l2tp_core.h ++++ b/net/l2tp/l2tp_core.h +@@ -235,6 +235,9 @@ struct l2tp_session *l2tp_session_get_by + void l2tp_stats_update(struct l2tp_tunnel *tunnel, struct l2tp_session *session, + struct l2tp_stats *stats); + ++void l2tp_stats_update(struct l2tp_tunnel *tunnel, struct l2tp_session *session, ++ struct l2tp_stats *stats); ++ + /* Tunnel and session lifetime management. + * Creation of a new instance is a two-step process: create, then register. + * Destruction is triggered using the *_delete functions, and completes asynchronously. diff --git a/target/linux/qualcommax/patches-6.6/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch b/target/linux/qualcommax/patches-6.6/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch new file mode 100644 index 00000000000000..e4ed49ea4c21fb --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch @@ -0,0 +1,22 @@ +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -2417,7 +2417,7 @@ nla_put_failure: + */ + void ip6_update_offload_stats(struct net_device *dev, void *ptr) + { +- struct pcpu_sw_netstats *tstats = per_cpu_ptr(dev->tstats, 0); ++ struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats); + const struct pcpu_sw_netstats *offload_stats = + (struct pcpu_sw_netstats *)ptr; + +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -1736,7 +1736,7 @@ nla_put_failure: + /* QCA NSS Clients Support - Start */ + void ipip6_update_offload_stats(struct net_device *dev, void *ptr) + { +- struct pcpu_sw_netstats *tstats = per_cpu_ptr(dev->tstats, 0); ++ struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats); + const struct pcpu_sw_netstats *offload_stats = + (struct pcpu_sw_netstats *)ptr; + diff --git a/target/linux/qualcommax/patches-6.6/0603-8-qca-nss-clients-add-tls-mgr-support.patch b/target/linux/qualcommax/patches-6.6/0603-8-qca-nss-clients-add-tls-mgr-support.patch new file mode 100644 index 00000000000000..0499e237f6be88 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0603-8-qca-nss-clients-add-tls-mgr-support.patch @@ -0,0 +1,24 @@ +--- /dev/null ++++ b/include/uapi/linux/tlshdr.h +@@ -0,0 +1,21 @@ ++#ifndef _UAPI_LINUX_TLSHDR_H ++#define _UAPI_LINUX_TLSHDR_H ++ ++#include ++ ++struct tlshdr { ++ __u8 type; ++ __be16 version; ++ __be16 len; ++} __attribute__((packed)); ++ ++#define TLSHDR_REC_TYPE_CCS 20 /* TLS packet is change cipher specification */ ++#define TLSHDR_REC_TYPE_ALERT 21 /* TLS packet is Alert */ ++#define TLSHDR_REC_TYPE_HANDSHAKE 22 /* TLS packet is Handshake */ ++#define TLSHDR_REC_TYPE_DATA 23 /* TLS packet is Application data */ ++ ++#define TLSHDR_VERSION_1_1 0x0302 /* TLS Header Version(tls 1.1) */ ++#define TLSHDR_VERSION_1_2 0x0303 /* TLS Header Version(tls 1.2) */ ++#define TLSHDR_VERSION_1_3 0x0304 /* TLS Header Version(tls 1.3) */ ++ ++#endif /* _UAPI_LINUX_TLSHDR_H */ diff --git a/target/linux/qualcommax/patches-6.6/0604-1-qca-add-mcs-support.patch b/target/linux/qualcommax/patches-6.6/0604-1-qca-add-mcs-support.patch new file mode 100644 index 00000000000000..edf21700c3e94c --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0604-1-qca-add-mcs-support.patch @@ -0,0 +1,876 @@ +--- a/include/linux/if_bridge.h ++++ b/include/linux/if_bridge.h +@@ -258,4 +258,17 @@ extern br_get_dst_hook_t __rcu *br_get_d + extern struct net_device *br_fdb_bridge_dev_get_and_hold(struct net_bridge *br); + /* QCA NSS bridge-mgr support - End */ + ++/* QCA qca-mcs support - Start */ ++typedef struct net_bridge_port *br_get_dst_hook_t(const struct net_bridge_port *src, ++ struct sk_buff **skb); ++extern br_get_dst_hook_t __rcu *br_get_dst_hook; ++ ++typedef int (br_multicast_handle_hook_t)(const struct net_bridge_port *src, ++ struct sk_buff *skb); ++extern br_multicast_handle_hook_t __rcu *br_multicast_handle_hook; ++ ++typedef void (br_notify_hook_t)(int group, int event, const void *ptr); ++extern br_notify_hook_t __rcu *br_notify_hook; ++/* QCA qca-mcs support - End */ ++ + #endif +--- a/net/bridge/br_fdb.c ++++ b/net/bridge/br_fdb.c +@@ -239,6 +239,8 @@ static void fdb_notify(struct net_bridge + kfree_skb(skb); + goto errout; + } ++ ++ __br_notify(RTNLGRP_NEIGH, type, fdb); /* QCA qca-mcs support */ + rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); + return; + errout: +@@ -305,6 +307,7 @@ struct net_bridge_fdb_entry *br_fdb_find + { + return fdb_find_rcu(&br->fdb_hash_tbl, addr, vid); + } ++EXPORT_SYMBOL_GPL(br_fdb_find_rcu); /* QCA qca-mcs support */ + + /* When a static FDB entry is added, the mac address from the entry is + * added to the bridge private HW address list and all required ports +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -906,6 +906,7 @@ void br_manage_promisc(struct net_bridge + int nbp_backup_change(struct net_bridge_port *p, struct net_device *backup_dev); + + /* br_input.c */ ++int br_pass_frame_up(struct sk_buff *skb); /* QCA qca-mcs support */ + int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb); + rx_handler_func_t *br_get_rx_handler(const struct net_device *dev); + +@@ -2268,4 +2269,14 @@ struct nd_msg *br_is_nd_neigh_msg(struct + bool br_is_neigh_suppress_enabled(const struct net_bridge_port *p, u16 vid); + #define __br_get(__hook, __default, __args ...) \ + (__hook ? (__hook(__args)) : (__default)) /* QCA NSS ECM support */ ++ ++/* QCA qca-mcs support - Start */ ++static inline void __br_notify(int group, int type, const void *data) ++{ ++ br_notify_hook_t *notify_hook = rcu_dereference(br_notify_hook); ++ ++ if (notify_hook) ++ notify_hook(group, type, data); ++} ++/* QCA qca-mcs support - End */ + #endif +--- a/net/bridge/br_netlink.c ++++ b/net/bridge/br_netlink.c +@@ -656,6 +656,7 @@ void br_info_notify(int event, const str + kfree_skb(skb); + goto errout; + } ++ __br_notify(RTNLGRP_LINK, event, port); /* QCA qca-mcs support */ + rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC); + return; + errout: +--- a/net/bridge/br.c ++++ b/net/bridge/br.c +@@ -472,6 +472,12 @@ static void __exit br_deinit(void) + br_fdb_fini(); + } + ++/* QCA qca-mcs support - Start */ ++/* Hook for bridge event notifications */ ++br_notify_hook_t __rcu *br_notify_hook __read_mostly; ++EXPORT_SYMBOL_GPL(br_notify_hook); ++/* QCA qca-mcs support - End */ ++ + module_init(br_init) + module_exit(br_deinit) + MODULE_LICENSE("GPL"); +--- a/net/bridge/br_device.c ++++ b/net/bridge/br_device.c +@@ -83,6 +83,13 @@ netdev_tx_t br_dev_xmit(struct sk_buff * + if (is_broadcast_ether_addr(dest)) { + br_flood(br, skb, BR_PKT_BROADCAST, false, true, vid); + } else if (is_multicast_ether_addr(dest)) { ++ /* QCA qca-mcs support - Start */ ++ br_multicast_handle_hook_t *multicast_handle_hook = ++ rcu_dereference(br_multicast_handle_hook); ++ if (!__br_get(multicast_handle_hook, true, NULL, skb)) ++ goto out; ++ /* QCA qca-mcs support - End */ ++ + if (unlikely(netpoll_tx_running(dev))) { + br_flood(br, skb, BR_PKT_MULTICAST, false, true, vid); + goto out; +--- a/net/bridge/br_input.c ++++ b/net/bridge/br_input.c +@@ -30,7 +30,17 @@ br_netif_receive_skb(struct net *net, st + return netif_receive_skb(skb); + } + +-static int br_pass_frame_up(struct sk_buff *skb) ++/* QCA qca-mcs support - Start */ ++/* Hook for external Multicast handler */ ++br_multicast_handle_hook_t __rcu *br_multicast_handle_hook __read_mostly; ++EXPORT_SYMBOL_GPL(br_multicast_handle_hook); ++ ++/* Hook for external forwarding logic */ ++br_get_dst_hook_t __rcu *br_get_dst_hook __read_mostly; ++EXPORT_SYMBOL_GPL(br_get_dst_hook); ++/* QCA qca-mcs support - End */ ++ ++int br_pass_frame_up(struct sk_buff *skb) + { + struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev; + struct net_bridge *br = netdev_priv(brdev); +@@ -69,6 +79,7 @@ static int br_pass_frame_up(struct sk_bu + dev_net(indev), NULL, skb, indev, NULL, + br_netif_receive_skb); + } ++EXPORT_SYMBOL_GPL(br_pass_frame_up); /* QCA qca-mcs support */ + + /* note: already called with rcu_read_lock */ + int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb) +@@ -82,6 +93,11 @@ int br_handle_frame_finish(struct net *n + struct net_bridge_mcast *brmctx; + struct net_bridge_vlan *vlan; + struct net_bridge *br; ++ /* QCA qca-mcs support - Start */ ++ br_multicast_handle_hook_t *multicast_handle_hook; ++ struct net_bridge_port *pdst = NULL; ++ br_get_dst_hook_t *get_dst_hook = rcu_dereference(br_get_dst_hook); ++ /* QCA qca-mcs support - End */ + u16 vid = 0; + u8 state; + +@@ -175,6 +191,12 @@ int br_handle_frame_finish(struct net *n + + switch (pkt_type) { + case BR_PKT_MULTICAST: ++ /* QCA qca-mcs support - Start */ ++ multicast_handle_hook = rcu_dereference(br_multicast_handle_hook); ++ if (!__br_get(multicast_handle_hook, true, p, skb)) ++ goto out; ++ /* QCA qca-mcs support - End */ ++ + mdst = br_mdb_get(brmctx, skb, vid); + if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) && + br_multicast_querier_exists(brmctx, eth_hdr(skb), mdst)) { +@@ -190,8 +212,15 @@ int br_handle_frame_finish(struct net *n + } + break; + case BR_PKT_UNICAST: +- dst = br_fdb_find_rcu(br, eth_hdr(skb)->h_dest, vid); +- break; ++ /* QCA qca-mcs support - Start */ ++ pdst = __br_get(get_dst_hook, NULL, p, &skb); ++ if (pdst) { ++ if (!skb) ++ goto out; ++ } else { ++ /* QCA qca-mcs support - End */ ++ dst = br_fdb_find_rcu(br, eth_hdr(skb)->h_dest, vid); ++ } + default: + break; + } +@@ -206,6 +235,13 @@ int br_handle_frame_finish(struct net *n + dst->used = now; + br_forward(dst->dst, skb, local_rcv, false); + } else { ++ /* QCA qca-mcs support - Start */ ++ if (pdst) { ++ br_forward(pdst, skb, local_rcv, false); ++ goto out; ++ } ++ /* QCA qca-mcs support - End */ ++ + if (!mcast_hit) + br_flood(br, skb, pkt_type, local_rcv, false, vid); + else +--- a/include/linux/mroute.h ++++ b/include/linux/mroute.h +@@ -92,4 +92,44 @@ struct rtmsg; + int ipmr_get_route(struct net *net, struct sk_buff *skb, + __be32 saddr, __be32 daddr, + struct rtmsg *rtm, u32 portid); ++ ++/* QCA ECM qca-mcs support - Start */ ++#define IPMR_MFC_EVENT_UPDATE 1 ++#define IPMR_MFC_EVENT_DELETE 2 ++ ++/* ++ * Callback to registered modules in the event of updates to a multicast group ++ */ ++typedef void (*ipmr_mfc_event_offload_callback_t)(__be32 origin, __be32 group, ++ u32 max_dest_dev, ++ u32 dest_dev_idx[], ++ u8 op); ++ ++/* ++ * Register the callback used to inform offload modules when updates occur to ++ * MFC. The callback is registered by offload modules ++ */ ++extern bool ipmr_register_mfc_event_offload_callback( ++ ipmr_mfc_event_offload_callback_t mfc_offload_cb); ++ ++/* ++ * De-Register the callback used to inform offload modules when updates occur ++ * to MFC ++ */ ++extern void ipmr_unregister_mfc_event_offload_callback(void); ++ ++/* ++ * Find the destination interface list, given a multicast group and source ++ */ ++extern int ipmr_find_mfc_entry(struct net *net, __be32 origin, __be32 group, ++ u32 max_dst_cnt, u32 dest_dev[]); ++ ++/* ++ * Out-of-band multicast statistics update for flows that are offloaded from ++ * Linux ++ */ ++extern int ipmr_mfc_stats_update(struct net *net, __be32 origin, __be32 group, ++ u64 pkts_in, u64 bytes_in, ++ u64 pkts_out, u64 bytes_out); ++/* QCA ECM qca-mcs support - End */ + #endif +--- a/include/linux/mroute6.h ++++ b/include/linux/mroute6.h +@@ -137,4 +137,47 @@ static inline int ip6mr_sk_ioctl(struct + return 1; + } + #endif ++ ++/* QCA qca-mcs support - Start */ ++#define IP6MR_MFC_EVENT_UPDATE 1 ++#define IP6MR_MFC_EVENT_DELETE 2 ++ ++/* ++ * Callback to registered modules in the event of updates to a multicast group ++ */ ++typedef void (*ip6mr_mfc_event_offload_callback_t)(struct in6_addr *origin, ++ struct in6_addr *group, ++ u32 max_dest_dev, ++ u32 dest_dev_idx[], ++ uint8_t op); ++ ++/* ++ * Register the callback used to inform offload modules when updates occur ++ * to MFC. The callback is registered by offload modules ++ */ ++extern bool ip6mr_register_mfc_event_offload_callback( ++ ip6mr_mfc_event_offload_callback_t mfc_offload_cb); ++ ++/* ++ * De-Register the callback used to inform offload modules when updates occur ++ * to MFC ++ */ ++extern void ip6mr_unregister_mfc_event_offload_callback(void); ++ ++/* ++ * Find the destination interface list given a multicast group and source ++ */ ++extern int ip6mr_find_mfc_entry(struct net *net, struct in6_addr *origin, ++ struct in6_addr *group, u32 max_dst_cnt, ++ u32 dest_dev[]); ++ ++/* ++ * Out-of-band multicast statistics update for flows that are offloaded from ++ * Linux ++ */ ++extern int ip6mr_mfc_stats_update(struct net *net, struct in6_addr *origin, ++ struct in6_addr *group, uint64_t pkts_in, ++ uint64_t bytes_in, uint64_t pkts_out, ++ uint64_t bytes_out); ++/* QCA qca-mcs support - End */ + #endif +--- a/net/ipv4/ipmr.c ++++ b/net/ipv4/ipmr.c +@@ -89,6 +89,9 @@ static struct net_device *vif_dev_read(c + /* Special spinlock for queue of unresolved entries */ + static DEFINE_SPINLOCK(mfc_unres_lock); + ++/* spinlock for offload */ ++static DEFINE_SPINLOCK(lock); /* QCA ECM qca-mcs support */ ++ + /* We return to original Alan's scheme. Hash table of resolved + * entries is changed only in process context and protected + * with weak lock mrt_lock. Queue of unresolved entries is protected +@@ -112,6 +115,9 @@ static void mroute_netlink_event(struct + static void igmpmsg_netlink_event(const struct mr_table *mrt, struct sk_buff *pkt); + static void mroute_clean_tables(struct mr_table *mrt, int flags); + static void ipmr_expire_process(struct timer_list *t); ++static struct mfc_cache *ipmr_cache_find(struct mr_table *mrt, __be32 origin, ++ __be32 mcastgrp); ++static ipmr_mfc_event_offload_callback_t __rcu ipmr_mfc_event_offload_callback; /* QCA ECM qca-mcs support */ + + #ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES + #define ipmr_for_each_table(mrt, net) \ +@@ -223,6 +229,80 @@ static int ipmr_rule_fill(struct fib_rul + return 0; + } + ++/* QCA ECM qca-mcs support - Start */ ++/* ipmr_sync_entry_update() ++ * Call the registered offload callback to report an update to a multicast ++ * route entry. The callback receives the list of destination interfaces and ++ * the interface count ++ */ ++static void ipmr_sync_entry_update(struct mr_table *mrt, ++ struct mfc_cache *cache) ++{ ++ int vifi, dest_if_count = 0; ++ u32 dest_dev[MAXVIFS]; ++ __be32 origin; ++ __be32 group; ++ ipmr_mfc_event_offload_callback_t offload_update_cb_f; ++ ++ memset(dest_dev, 0, sizeof(dest_dev)); ++ ++ origin = cache->mfc_origin; ++ group = cache->mfc_mcastgrp; ++ ++ spin_lock(&mrt_lock); ++ for (vifi = 0; vifi < cache->_c.mfc_un.res.maxvif; vifi++) { ++ if (!((cache->_c.mfc_un.res.ttls[vifi] > 0) && ++ (cache->_c.mfc_un.res.ttls[vifi] < 255))) { ++ continue; ++ } ++ if (dest_if_count == MAXVIFS) { ++ spin_unlock(&mrt_lock); ++ return; ++ } ++ ++ if (!VIF_EXISTS(mrt, vifi)) { ++ spin_unlock(&mrt_lock); ++ return; ++ } ++ dest_dev[dest_if_count] = mrt->vif_table[vifi].dev->ifindex; ++ dest_if_count++; ++ } ++ spin_unlock(&mrt_lock); ++ ++ rcu_read_lock(); ++ offload_update_cb_f = rcu_dereference(ipmr_mfc_event_offload_callback); ++ ++ if (!offload_update_cb_f) { ++ rcu_read_unlock(); ++ return; ++ } ++ ++ offload_update_cb_f(group, origin, dest_if_count, dest_dev, ++ IPMR_MFC_EVENT_UPDATE); ++ rcu_read_unlock(); ++} ++ ++/* ipmr_sync_entry_delete() ++ * Call the registered offload callback to inform of a multicast route entry ++ * delete event ++ */ ++static void ipmr_sync_entry_delete(u32 origin, u32 group) ++{ ++ ipmr_mfc_event_offload_callback_t offload_update_cb_f; ++ ++ rcu_read_lock(); ++ offload_update_cb_f = rcu_dereference(ipmr_mfc_event_offload_callback); ++ ++ if (!offload_update_cb_f) { ++ rcu_read_unlock(); ++ return; ++ } ++ ++ offload_update_cb_f(group, origin, 0, NULL, IPMR_MFC_EVENT_DELETE); ++ rcu_read_unlock(); ++} ++/* QCA ECM qca-mcs support - End */ ++ + static const struct fib_rules_ops __net_initconst ipmr_rules_ops_template = { + .family = RTNL_FAMILY_IPMR, + .rule_size = sizeof(struct ipmr_rule), +@@ -236,6 +316,156 @@ static const struct fib_rules_ops __net_ + .owner = THIS_MODULE, + }; + ++/* QCA ECM qca-mcs support - Start */ ++/* ipmr_register_mfc_event_offload_callback() ++ * Register the IPv4 Multicast update offload callback with IPMR ++ */ ++bool ipmr_register_mfc_event_offload_callback( ++ ipmr_mfc_event_offload_callback_t mfc_offload_cb) ++{ ++ ipmr_mfc_event_offload_callback_t offload_update_cb_f; ++ ++ rcu_read_lock(); ++ offload_update_cb_f = rcu_dereference(ipmr_mfc_event_offload_callback); ++ ++ if (offload_update_cb_f) { ++ rcu_read_unlock(); ++ return false; ++ } ++ rcu_read_unlock(); ++ ++ spin_lock(&lock); ++ rcu_assign_pointer(ipmr_mfc_event_offload_callback, mfc_offload_cb); ++ spin_unlock(&lock); ++ synchronize_rcu(); ++ return true; ++} ++EXPORT_SYMBOL(ipmr_register_mfc_event_offload_callback); ++ ++/* ipmr_unregister_mfc_event_offload_callback() ++ * De-register the IPv4 Multicast update offload callback with IPMR ++ */ ++void ipmr_unregister_mfc_event_offload_callback(void) ++{ ++ spin_lock(&lock); ++ rcu_assign_pointer(ipmr_mfc_event_offload_callback, NULL); ++ spin_unlock(&lock); ++ synchronize_rcu(); ++} ++EXPORT_SYMBOL(ipmr_unregister_mfc_event_offload_callback); ++ ++/* ipmr_find_mfc_entry() ++ * Returns destination interface list for a particular multicast flow, and ++ * the number of interfaces in the list ++ */ ++int ipmr_find_mfc_entry(struct net *net, __be32 origin, __be32 group, ++ u32 max_dest_cnt, u32 dest_dev[]) ++{ ++ int vifi, dest_if_count = 0; ++ struct mr_table *mrt; ++ struct mfc_cache *cache; ++ ++ mrt = ipmr_get_table(net, RT_TABLE_DEFAULT); ++ if (!mrt) ++ return -ENOENT; ++ ++ rcu_read_lock(); ++ cache = ipmr_cache_find(mrt, origin, group); ++ if (!cache) { ++ rcu_read_unlock(); ++ return -ENOENT; ++ } ++ ++ spin_lock(&mrt_lock); ++ for (vifi = 0; vifi < cache->_c.mfc_un.res.maxvif; vifi++) { ++ if (!((cache->_c.mfc_un.res.ttls[vifi] > 0) && ++ (cache->_c.mfc_un.res.ttls[vifi] < 255))) { ++ continue; ++ } ++ ++ /* We have another valid destination interface entry. Check if ++ * the number of the destination interfaces for the route is ++ * exceeding the size of the array given to us ++ */ ++ if (dest_if_count == max_dest_cnt) { ++ spin_unlock(&mrt_lock); ++ rcu_read_unlock(); ++ return -EINVAL; ++ } ++ ++ if (!VIF_EXISTS(mrt, vifi)) { ++ spin_unlock(&mrt_lock); ++ rcu_read_unlock(); ++ return -EINVAL; ++ } ++ ++ dest_dev[dest_if_count] = mrt->vif_table[vifi].dev->ifindex; ++ dest_if_count++; ++ } ++ spin_unlock(&mrt_lock); ++ rcu_read_unlock(); ++ ++ return dest_if_count; ++} ++EXPORT_SYMBOL(ipmr_find_mfc_entry); ++ ++/* ipmr_mfc_stats_update() ++ * Update the MFC/VIF statistics for offloaded flows ++ */ ++int ipmr_mfc_stats_update(struct net *net, __be32 origin, __be32 group, ++ u64 pkts_in, u64 bytes_in, ++ u64 pkts_out, u64 bytes_out) ++{ ++ int vif, vifi; ++ struct mr_table *mrt; ++ struct mfc_cache *cache; ++ ++ mrt = ipmr_get_table(net, RT_TABLE_DEFAULT); ++ if (!mrt) ++ return -ENOENT; ++ ++ rcu_read_lock(); ++ cache = ipmr_cache_find(mrt, origin, group); ++ if (!cache) { ++ rcu_read_unlock(); ++ return -ENOENT; ++ } ++ ++ vif = cache->_c.mfc_parent; ++ ++ spin_lock(&mrt_lock); ++ if (!VIF_EXISTS(mrt, vif)) { ++ spin_unlock(&mrt_lock); ++ rcu_read_unlock(); ++ return -EINVAL; ++ } ++ ++ mrt->vif_table[vif].pkt_in += pkts_in; ++ mrt->vif_table[vif].bytes_in += bytes_in; ++ cache->_c.mfc_un.res.pkt += pkts_out; ++ cache->_c.mfc_un.res.bytes += bytes_out; ++ ++ for (vifi = cache->_c.mfc_un.res.minvif; ++ vifi < cache->_c.mfc_un.res.maxvif; vifi++) { ++ if ((cache->_c.mfc_un.res.ttls[vifi] > 0) && ++ (cache->_c.mfc_un.res.ttls[vifi] < 255)) { ++ if (!VIF_EXISTS(mrt, vifi)) { ++ spin_unlock(&mrt_lock); ++ rcu_read_unlock(); ++ return -EINVAL; ++ } ++ mrt->vif_table[vifi].pkt_out += pkts_out; ++ mrt->vif_table[vifi].bytes_out += bytes_out; ++ } ++ } ++ spin_unlock(&mrt_lock); ++ rcu_read_unlock(); ++ ++ return 0; ++} ++EXPORT_SYMBOL(ipmr_mfc_stats_update); ++/* QCA ECM qca-mcs support - End */ ++ + static int __net_init ipmr_rules_init(struct net *net) + { + struct fib_rules_ops *ops; +@@ -1191,6 +1421,10 @@ static int ipmr_mfc_delete(struct mr_tab + call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, c, mrt->id); + mroute_netlink_event(mrt, c, RTM_DELROUTE); + mr_cache_put(&c->_c); ++ /* QCA ECM qca-mcs support - Start */ ++ /* Inform offload modules of the delete event */ ++ ipmr_sync_entry_delete(c->mfc_origin, c->mfc_mcastgrp); ++ /* QCA ECM qca-mcs support - End */ + + return 0; + } +@@ -1221,6 +1455,10 @@ static int ipmr_mfc_add(struct net *net, + call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_REPLACE, c, + mrt->id); + mroute_netlink_event(mrt, c, RTM_NEWROUTE); ++ /* QCA ECM qca-mcs support - Start */ ++ /* Inform offload modules of the update event */ ++ ipmr_sync_entry_update(mrt, c); ++ /* QCA ECM qca-mcs support - End */ + return 0; + } + +--- a/net/ipv6/ip6mr.c ++++ b/net/ipv6/ip6mr.c +@@ -74,6 +74,9 @@ static struct net_device *vif_dev_read(c + /* Special spinlock for queue of unresolved entries */ + static DEFINE_SPINLOCK(mfc_unres_lock); + ++/* Spinlock for offload */ ++static DEFINE_SPINLOCK(lock); /* QCA qca-mcs support */ ++ + /* We return to original Alan's scheme. Hash table of resolved + entries is changed only in process context and protected + with weak lock mrt_lock. Queue of unresolved entries is protected +@@ -101,6 +104,13 @@ static int ip6mr_rtm_dumproute(struct sk + struct netlink_callback *cb); + static void mroute_clean_tables(struct mr_table *mrt, int flags); + static void ipmr_expire_process(struct timer_list *t); ++/* QCA qca-mcs support - Start */ ++static struct mfc6_cache *ip6mr_cache_find(struct mr_table *mrt, ++ const struct in6_addr *origin, ++ const struct in6_addr *mcastgrp); ++static ip6mr_mfc_event_offload_callback_t __rcu ++ ip6mr_mfc_event_offload_callback; ++/* QCA qca-mcs support - End */ + + #ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES + #define ip6mr_for_each_table(mrt, net) \ +@@ -375,6 +385,84 @@ static struct mfc6_cache_cmp_arg ip6mr_m + .mf6c_mcastgrp = IN6ADDR_ANY_INIT, + }; + ++/* QCA qca-mcs support - Start */ ++/* ip6mr_sync_entry_update() ++ * Call the registered offload callback to report an update to a multicast ++ * route entry. The callback receives the list of destination interfaces and ++ * the interface count ++ */ ++static void ip6mr_sync_entry_update(struct mr_table *mrt, ++ struct mfc6_cache *cache) ++{ ++ int vifi, dest_if_count = 0; ++ u32 dest_dev[MAXMIFS]; ++ struct in6_addr mc_origin, mc_group; ++ ip6mr_mfc_event_offload_callback_t offload_update_cb_f; ++ ++ memset(dest_dev, 0, sizeof(dest_dev)); ++ ++ spin_lock(&mrt_lock); ++ ++ for (vifi = 0; vifi < cache->_c.mfc_un.res.maxvif; vifi++) { ++ if (!((cache->_c.mfc_un.res.ttls[vifi] > 0) && ++ (cache->_c.mfc_un.res.ttls[vifi] < 255))) { ++ continue; ++ } ++ ++ if (dest_if_count == MAXMIFS) { ++ spin_unlock(&mrt_lock); ++ return; ++ } ++ ++ if (!VIF_EXISTS(mrt, vifi)) { ++ spin_unlock(&mrt_lock); ++ return; ++ } ++ ++ dest_dev[dest_if_count] = mrt->vif_table[vifi].dev->ifindex; ++ dest_if_count++; ++ } ++ ++ memcpy(&mc_origin, &cache->mf6c_origin, sizeof(struct in6_addr)); ++ memcpy(&mc_group, &cache->mf6c_mcastgrp, sizeof(struct in6_addr)); ++ spin_unlock(&mrt_lock); ++ ++ rcu_read_lock(); ++ offload_update_cb_f = rcu_dereference(ip6mr_mfc_event_offload_callback); ++ ++ if (!offload_update_cb_f) { ++ rcu_read_unlock(); ++ return; ++ } ++ ++ offload_update_cb_f(&mc_group, &mc_origin, dest_if_count, dest_dev, ++ IP6MR_MFC_EVENT_UPDATE); ++ rcu_read_unlock(); ++} ++ ++/* ip6mr_sync_entry_delete() ++ * Call the registered offload callback to inform of a multicast route entry ++ * delete event ++ */ ++static void ip6mr_sync_entry_delete(struct in6_addr *mc_origin, ++ struct in6_addr *mc_group) ++{ ++ ip6mr_mfc_event_offload_callback_t offload_update_cb_f; ++ ++ rcu_read_lock(); ++ offload_update_cb_f = rcu_dereference(ip6mr_mfc_event_offload_callback); ++ ++ if (!offload_update_cb_f) { ++ rcu_read_unlock(); ++ return; ++ } ++ ++ offload_update_cb_f(mc_group, mc_origin, 0, NULL, ++ IP6MR_MFC_EVENT_DELETE); ++ rcu_read_unlock(); ++} ++/* QCA qca-mcs support - End */ ++ + static struct mr_table_ops ip6mr_mr_table_ops = { + .rht_params = &ip6mr_rht_params, + .cmparg_any = &ip6mr_mr_table_ops_cmparg_any, +@@ -697,6 +785,151 @@ static int call_ip6mr_mfc_entry_notifier + &mfc->_c, tb_id, &net->ipv6.ipmr_seq); + } + ++/* QCA qca-mcs support - Start */ ++/* ip6mr_register_mfc_event_offload_callback() ++ * Register the IPv6 multicast update callback for offload modules ++ */ ++bool ip6mr_register_mfc_event_offload_callback( ++ ip6mr_mfc_event_offload_callback_t mfc_offload_cb) ++{ ++ ip6mr_mfc_event_offload_callback_t offload_update_cb_f; ++ ++ rcu_read_lock(); ++ offload_update_cb_f = rcu_dereference(ip6mr_mfc_event_offload_callback); ++ ++ if (offload_update_cb_f) { ++ rcu_read_unlock(); ++ return false; ++ } ++ rcu_read_unlock(); ++ ++ spin_lock(&lock); ++ rcu_assign_pointer(ip6mr_mfc_event_offload_callback, mfc_offload_cb); ++ spin_unlock(&lock); ++ synchronize_rcu(); ++ return true; ++} ++EXPORT_SYMBOL(ip6mr_register_mfc_event_offload_callback); ++ ++/* ip6mr_unregister_mfc_event_offload_callback() ++ * De-register the IPv6 multicast update callback for offload modules ++ */ ++void ip6mr_unregister_mfc_event_offload_callback(void) ++{ ++ spin_lock(&lock); ++ rcu_assign_pointer(ip6mr_mfc_event_offload_callback, NULL); ++ spin_unlock(&lock); ++ synchronize_rcu(); ++} ++EXPORT_SYMBOL(ip6mr_unregister_mfc_event_offload_callback); ++ ++/* ip6mr_find_mfc_entry() ++ * Return the destination interface list for a particular multicast flow, and ++ * the number of interfaces in the list ++ */ ++int ip6mr_find_mfc_entry(struct net *net, struct in6_addr *origin, ++ struct in6_addr *group, u32 max_dest_cnt, ++ u32 dest_dev[]) ++{ ++ int vifi, dest_if_count = 0; ++ struct mr_table *mrt; ++ struct mfc6_cache *cache; ++ ++ mrt = ip6mr_get_table(net, RT6_TABLE_DFLT); ++ if (!mrt) ++ return -ENOENT; ++ ++ spin_lock(&mrt_lock); ++ cache = ip6mr_cache_find(mrt, origin, group); ++ if (!cache) { ++ spin_unlock(&mrt_lock); ++ return -ENOENT; ++ } ++ ++ for (vifi = 0; vifi < cache->_c.mfc_un.res.maxvif; vifi++) { ++ if (!((cache->_c.mfc_un.res.ttls[vifi] > 0) && ++ (cache->_c.mfc_un.res.ttls[vifi] < 255))) { ++ continue; ++ } ++ ++ /* We have another valid destination interface entry. Check if ++ * the number of the destination interfaces for the route is ++ * exceeding the size of the array given to us ++ */ ++ if (dest_if_count == max_dest_cnt) { ++ spin_unlock(&mrt_lock); ++ return -EINVAL; ++ } ++ ++ if (!VIF_EXISTS(mrt, vifi)) { ++ spin_unlock(&mrt_lock); ++ return -EINVAL; ++ } ++ ++ dest_dev[dest_if_count] = mrt->vif_table[vifi].dev->ifindex; ++ dest_if_count++; ++ } ++ spin_unlock(&mrt_lock); ++ ++ return dest_if_count; ++} ++EXPORT_SYMBOL(ip6mr_find_mfc_entry); ++ ++/* ip6mr_mfc_stats_update() ++ * Update the MFC/VIF statistics for offloaded flows ++ */ ++int ip6mr_mfc_stats_update(struct net *net, struct in6_addr *origin, ++ struct in6_addr *group, u64 pkts_in, ++ u64 bytes_in, uint64_t pkts_out, ++ u64 bytes_out) ++{ ++ int vif, vifi; ++ struct mr_table *mrt; ++ struct mfc6_cache *cache; ++ ++ mrt = ip6mr_get_table(net, RT6_TABLE_DFLT); ++ ++ if (!mrt) ++ return -ENOENT; ++ ++ spin_lock(&mrt_lock); ++ cache = ip6mr_cache_find(mrt, origin, group); ++ if (!cache) { ++ spin_unlock(&mrt_lock); ++ return -ENOENT; ++ } ++ ++ vif = cache->_c.mfc_parent; ++ ++ if (!VIF_EXISTS(mrt, vif)) { ++ spin_unlock(&mrt_lock); ++ return -EINVAL; ++ } ++ ++ mrt->vif_table[vif].pkt_in += pkts_in; ++ mrt->vif_table[vif].bytes_in += bytes_in; ++ cache->_c.mfc_un.res.pkt += pkts_out; ++ cache->_c.mfc_un.res.bytes += bytes_out; ++ ++ for (vifi = cache->_c.mfc_un.res.minvif; ++ vifi < cache->_c.mfc_un.res.maxvif; vifi++) { ++ if ((cache->_c.mfc_un.res.ttls[vifi] > 0) && ++ (cache->_c.mfc_un.res.ttls[vifi] < 255)) { ++ if (!VIF_EXISTS(mrt, vifi)) { ++ spin_unlock(&mrt_lock); ++ return -EINVAL; ++ } ++ mrt->vif_table[vifi].pkt_out += pkts_out; ++ mrt->vif_table[vifi].bytes_out += bytes_out; ++ } ++ } ++ ++ spin_unlock(&mrt_lock); ++ return 0; ++} ++EXPORT_SYMBOL(ip6mr_mfc_stats_update); ++/* QCA qca-mcs support - End */ ++ + /* Delete a VIF entry */ + static int mif6_delete(struct mr_table *mrt, int vifi, int notify, + struct list_head *head) +@@ -1221,6 +1454,7 @@ static int ip6mr_mfc_delete(struct mr_ta + int parent) + { + struct mfc6_cache *c; ++ struct in6_addr mc_origin, mc_group; /* QCA qca-mcs support */ + + /* The entries are added/deleted only under RTNL */ + rcu_read_lock(); +@@ -1229,6 +1463,11 @@ static int ip6mr_mfc_delete(struct mr_ta + rcu_read_unlock(); + if (!c) + return -ENOENT; ++ ++ /* QCA qca-mcs support - Start */ ++ memcpy(&mc_origin, &c->mf6c_origin, sizeof(struct in6_addr)); ++ memcpy(&mc_group, &c->mf6c_mcastgrp, sizeof(struct in6_addr)); ++ /* QCA qca-mcs support - End */ + rhltable_remove(&mrt->mfc_hash, &c->_c.mnode, ip6mr_rht_params); + list_del_rcu(&c->_c.list); + +@@ -1236,6 +1475,11 @@ static int ip6mr_mfc_delete(struct mr_ta + FIB_EVENT_ENTRY_DEL, c, mrt->id); + mr6_netlink_event(mrt, c, RTM_DELROUTE); + mr_cache_put(&c->_c); ++ /* QCA qca-mcs support - Start */ ++ /* Inform offload modules of the delete event */ ++ ip6mr_sync_entry_delete(&mc_origin, &mc_group); ++ /* QCA qca-mcs support - End */ ++ + return 0; + } + +@@ -1457,6 +1701,10 @@ static int ip6mr_mfc_add(struct net *net + call_ip6mr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_REPLACE, + c, mrt->id); + mr6_netlink_event(mrt, c, RTM_NEWROUTE); ++ /* QCA qca-mcs support - Start */ ++ /* Inform offload modules of the update event */ ++ ip6mr_sync_entry_update(mrt, c); ++ /* QCA qca-mcs support - End */ + return 0; + } + diff --git a/target/linux/qualcommax/patches-6.6/0605-1-qca-nss-cfi-support.patch b/target/linux/qualcommax/patches-6.6/0605-1-qca-nss-cfi-support.patch new file mode 100644 index 00000000000000..f6a439ba5306a6 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0605-1-qca-nss-cfi-support.patch @@ -0,0 +1,111 @@ +--- a/crypto/authenc.c ++++ b/crypto/authenc.c +@@ -415,6 +415,8 @@ static int crypto_authenc_create(struct + enc->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME) + goto err_free_inst; + ++ inst->alg.base.cra_flags |= (auth_base->cra_flags | ++ enc->base.cra_flags) & CRYPTO_ALG_NOSUPP_SG; + inst->alg.base.cra_priority = enc->base.cra_priority * 10 + + auth_base->cra_priority; + inst->alg.base.cra_blocksize = enc->base.cra_blocksize; +--- a/include/linux/crypto.h ++++ b/include/linux/crypto.h +@@ -86,6 +86,11 @@ + #define CRYPTO_NOLOAD 0x00008000 + + /* ++ * Set this flag if algorithm does not support SG list transforms ++ */ ++#define CRYPTO_ALG_NOSUPP_SG 0x0000c000 ++ ++/* + * The algorithm may allocate memory during request processing, i.e. during + * encryption, decryption, or hashing. Users can request an algorithm with this + * flag unset if they can't handle memory allocation failures. +--- a/net/ipv4/esp4.c ++++ b/net/ipv4/esp4.c +@@ -658,6 +658,7 @@ static int esp_output(struct xfrm_state + struct ip_esp_hdr *esph; + struct crypto_aead *aead; + struct esp_info esp; ++ bool nosupp_sg; + + esp.inplace = true; + +@@ -669,6 +670,11 @@ static int esp_output(struct xfrm_state + aead = x->data; + alen = crypto_aead_authsize(aead); + ++ nosupp_sg = crypto_tfm_alg_type(&aead->base) & CRYPTO_ALG_NOSUPP_SG; ++ if (nosupp_sg && skb_linearize(skb)) { ++ return -ENOMEM; ++ } ++ + esp.tfclen = 0; + if (x->tfcpad) { + struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb); +@@ -890,6 +896,7 @@ static int esp_input(struct xfrm_state * + u8 *iv; + struct scatterlist *sg; + int err = -EINVAL; ++ bool nosupp_sg; + + if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr) + ivlen)) + goto out; +@@ -897,6 +904,12 @@ static int esp_input(struct xfrm_state * + if (elen <= 0) + goto out; + ++ nosupp_sg = crypto_tfm_alg_type(&aead->base) & CRYPTO_ALG_NOSUPP_SG; ++ if (nosupp_sg && skb_linearize(skb)) { ++ err = -ENOMEM; ++ goto out; ++ } ++ + assoclen = sizeof(struct ip_esp_hdr); + seqhilen = 0; + +--- a/net/ipv6/esp6.c ++++ b/net/ipv6/esp6.c +@@ -696,6 +696,7 @@ static int esp6_output(struct xfrm_state + struct ip_esp_hdr *esph; + struct crypto_aead *aead; + struct esp_info esp; ++ bool nosupp_sg; + + esp.inplace = true; + +@@ -707,6 +708,11 @@ static int esp6_output(struct xfrm_state + aead = x->data; + alen = crypto_aead_authsize(aead); + ++ nosupp_sg = crypto_tfm_alg_type(&aead->base) & CRYPTO_ALG_NOSUPP_SG; ++ if (nosupp_sg && skb_linearize(skb)) { ++ return -ENOMEM; ++ } ++ + esp.tfclen = 0; + if (x->tfcpad) { + struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb); +@@ -934,6 +940,7 @@ static int esp6_input(struct xfrm_state + __be32 *seqhi; + u8 *iv; + struct scatterlist *sg; ++ bool nosupp_sg; + + if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr) + ivlen)) { + ret = -EINVAL; +@@ -945,6 +952,12 @@ static int esp6_input(struct xfrm_state + goto out; + } + ++ nosupp_sg = crypto_tfm_alg_type(&aead->base) & CRYPTO_ALG_NOSUPP_SG; ++ if (nosupp_sg && skb_linearize(skb)) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ + assoclen = sizeof(struct ip_esp_hdr); + seqhilen = 0; + diff --git a/target/linux/qualcommax/patches-6.6/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch b/target/linux/qualcommax/patches-6.6/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch new file mode 100644 index 00000000000000..4b9ee21f2f8545 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch @@ -0,0 +1,10 @@ +--- a/net/netfilter/nf_conntrack_ecache.c ++++ b/net/netfilter/nf_conntrack_ecache.c +@@ -266,7 +266,6 @@ void nf_conntrack_register_notifier(stru + mutex_lock(&nf_ct_ecache_mutex); + notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb, + lockdep_is_held(&nf_ct_ecache_mutex)); +- WARN_ON_ONCE(notify); + rcu_assign_pointer(net->ct.nf_conntrack_event_cb, new); + mutex_unlock(&nf_ct_ecache_mutex); + } diff --git a/target/linux/qualcommax/patches-6.6/0611-ipv6-Fix-null-pointer-dereference-in-ipv6-output.patch b/target/linux/qualcommax/patches-6.6/0611-ipv6-Fix-null-pointer-dereference-in-ipv6-output.patch new file mode 100644 index 00000000000000..25f99fc4adef3c --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0611-ipv6-Fix-null-pointer-dereference-in-ipv6-output.patch @@ -0,0 +1,80 @@ +From eee3a7956b943dd3e23a74fbb5bfe89405eb0782 Mon Sep 17 00:00:00 2001 +From: Andrea Righi +Date: Mon, 6 Dec 2021 17:34:47 +0100 +Subject: UBUNTU: SAUCE: ipv6: fix NULL pointer dereference in ip6_output() + +It is possible to trigger a NULL pointer dereference by running the srv6 +net kselftest (tools/testing/selftests/net/srv6_end_dt46_l3vpn_test.sh): + +[ 249.051216] BUG: kernel NULL pointer dereference, address: 0000000000000378 +[ 249.052331] #PF: supervisor read access in kernel mode +[ 249.053137] #PF: error_code(0x0000) - not-present page +[ 249.053960] PGD 0 P4D 0 +[ 249.054376] Oops: 0000 [#1] PREEMPT SMP NOPTI +[ 249.055083] CPU: 1 PID: 21 Comm: ksoftirqd/1 Tainted: G E 5.16.0-rc4 #2 +[ 249.056328] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 +[ 249.057632] RIP: 0010:ip6_forward+0x53c/0xab0 +[ 249.058354] Code: 49 c7 44 24 20 00 00 00 00 48 83 e0 fe 48 8b 40 30 48 3d 70 b2 b5 81 0f 85 b5 04 00 00 e8 7c f2 ff ff 41 89 c5 e9 17 01 00 00 <44> 8b 93 78 03 00 00 45 85 d2 0f 85 92 fb ff ff 49 8b 54 24 10 48 +[ 249.061274] RSP: 0018:ffffc900000cbb30 EFLAGS: 00010246 +[ 249.062042] RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffff8881051d3400 +[ 249.063141] RDX: ffff888104bda000 RSI: 00000000000002c0 RDI: 0000000000000000 +[ 249.064264] RBP: ffffc900000cbbc8 R08: 0000000000000000 R09: 0000000000000000 +[ 249.065376] R10: 0000000000000040 R11: 0000000000000000 R12: ffff888103409800 +[ 249.066498] R13: ffff8881051d3410 R14: ffff888102725280 R15: ffff888103525000 +[ 249.067619] FS: 0000000000000000(0000) GS:ffff88813bc80000(0000) knlGS:0000000000000000 +[ 249.068881] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 249.069777] CR2: 0000000000000378 CR3: 0000000104980000 CR4: 0000000000750ee0 +[ 249.070907] PKRU: 55555554 +[ 249.071337] Call Trace: +[ 249.071730] +[ 249.072070] ? debug_smp_processor_id+0x17/0x20 +[ 249.072807] seg6_input_core+0x2bb/0x2d0 +[ 249.073436] ? _raw_spin_unlock_irqrestore+0x29/0x40 +[ 249.074225] seg6_input+0x3b/0x130 +[ 249.074768] lwtunnel_input+0x5e/0xa0 +[ 249.075357] ip_rcv+0x17b/0x190 +[ 249.075867] ? update_load_avg+0x82/0x600 +[ 249.076514] __netif_receive_skb_one_core+0x86/0xa0 +[ 249.077231] __netif_receive_skb+0x15/0x60 +[ 249.077843] process_backlog+0x97/0x160 +[ 249.078389] __napi_poll+0x31/0x170 +[ 249.078912] net_rx_action+0x229/0x270 +[ 249.079506] __do_softirq+0xef/0x2ed +[ 249.080085] run_ksoftirqd+0x37/0x50 +[ 249.080663] smpboot_thread_fn+0x193/0x230 +[ 249.081312] kthread+0x17a/0x1a0 +[ 249.081847] ? smpboot_register_percpu_thread+0xe0/0xe0 +[ 249.082677] ? set_kthread_struct+0x50/0x50 +[ 249.083340] ret_from_fork+0x22/0x30 +[ 249.083926] +[ 249.090295] ---[ end trace 1998d7ba5965a365 ]--- + +It looks like commit 0857d6f8c759 ("ipv6: When forwarding count rx stats +on the orig netdev") tries to determine the right netdev to account the +rx stats, but in this particular case it's failing and the netdev is +NULL. + +Fallback to the previous method of determining the netdev interface (via +skb->dev) to account the rx stats when the orig netdev can't be +determined. + +Fixes: 0857d6f8c759 ("ipv6: When forwarding count rx stats on the orig netdev") +Signed-off-by: Andrea Righi +(cherry picked from https://lore.kernel.org/lkml/20211206163447.991402-1-andrea.righi@canonical.com/T/#u) +Signed-off-by: Andrea Righi +--- + net/ipv6/ip6_output.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -498,6 +498,9 @@ int ip6_forward(struct sk_buff *skb) + u32 mtu; + + idev = __in6_dev_get_safely(dev_get_by_index_rcu(net, IP6CB(skb)->iif)); ++ if (unlikely(!idev)) ++ idev = __in6_dev_get_safely(skb->dev); ++ + if (net->ipv6.devconf_all->forwarding == 0) + goto error; + diff --git a/target/linux/qualcommax/patches-6.6/9990-1-qca-skb_recycler-support.patch b/target/linux/qualcommax/patches-6.6/9990-1-qca-skb_recycler-support.patch new file mode 100644 index 00000000000000..886bc92fe2e26a --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/9990-1-qca-skb_recycler-support.patch @@ -0,0 +1,396 @@ +diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h +index 624d4a3..5aa8808 100644 +--- a/include/linux/cpuhotplug.h ++++ b/include/linux/cpuhotplug.h +@@ -94,6 +94,7 @@ enum cpuhp_state { + CPUHP_RADIX_DEAD, + CPUHP_PAGE_ALLOC, + CPUHP_NET_DEV_DEAD, ++ CPUHP_SKB_RECYCLER_DEAD, + CPUHP_PCI_XGENE_DEAD, + CPUHP_IOMMU_IOVA_DEAD, + CPUHP_LUSTRE_CFS_DEAD, +diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h +index 83cced8..b6ee509 100644 +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -1065,6 +1065,10 @@ struct sk_buff { + /* only useable after checking ->active_extensions != 0 */ + struct skb_ext *extensions; + #endif ++ ++#ifdef CONFIG_DEBUG_OBJECTS_SKBUFF ++ void *free_addr; ++#endif + }; + + /* if you move pkt_type around you also must adapt those constants */ +@@ -1250,7 +1254,7 @@ static inline void kfree_skb_list(struct sk_buff *segs) + kfree_skb_list_reason(segs, SKB_DROP_REASON_NOT_SPECIFIED); + } + +-#ifdef CONFIG_TRACEPOINTS ++#ifdef CONFIG_SKB_RECYCLER + void consume_skb(struct sk_buff *skb); + #else + static inline void consume_skb(struct sk_buff *skb) +@@ -1262,6 +1266,9 @@ static inline void consume_skb(struct sk_buff *skb) + void __consume_stateless_skb(struct sk_buff *skb); + void __kfree_skb(struct sk_buff *skb); + extern struct kmem_cache *skbuff_cache; ++extern void kfree_skbmem(struct sk_buff *skb); ++extern void skb_release_data(struct sk_buff *skb, enum skb_drop_reason reason, ++ bool napi_safe); + + void kfree_skb_partial(struct sk_buff *skb, bool head_stolen); + bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from, +diff --git a/net/Kconfig b/net/Kconfig +index 61eac93..e0c8bf0 100644 +--- a/net/Kconfig ++++ b/net/Kconfig +@@ -369,6 +369,27 @@ config NET_FLOW_LIMIT + with many clients some protection against DoS by a single (spoofed) + flow that greatly exceeds average workload. + ++config SKB_RECYCLER ++ bool "Generic skb recycling" ++ default y ++ help ++ SKB_RECYCLER is used to implement RX-to-RX skb recycling. ++ This config enables the recycling scheme for bridging and ++ routing workloads. It can reduce skbuff freeing or ++ reallocation overhead. ++ ++config SKB_RECYCLER_MULTI_CPU ++ bool "Cross-CPU recycling for CPU-locked workloads" ++ depends on SMP && SKB_RECYCLER ++ default n ++ ++config ALLOC_SKB_PAGE_FRAG_DISABLE ++ bool "Disable page fragment based skbuff payload allocations" ++ depends on !SKB_RECYCLER ++ default n ++ help ++ Disable page fragment based allocations for skbuff payloads. ++ + menu "Network testing" + + config NET_PKTGEN +diff --git a/net/core/Makefile b/net/core/Makefile +index 5c9fc1f..e90878c 100644 +--- a/net/core/Makefile ++++ b/net/core/Makefile +@@ -41,3 +41,4 @@ obj-$(CONFIG_NET_SOCK_MSG) += skmsg.o + obj-$(CONFIG_BPF_SYSCALL) += sock_map.o + obj-$(CONFIG_BPF_SYSCALL) += bpf_sk_storage.o + obj-$(CONFIG_OF) += of_net.o ++obj-$(CONFIG_SKB_RECYCLER) += skbuff_recycle.o +diff --git a/net/core/dev.c b/net/core/dev.c +index 85a1038..c6994ab 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -6016,10 +6016,16 @@ static int process_backlog(struct napi_struct *napi, int quota) + + napi->weight = READ_ONCE(dev_rx_weight); + while (again) { +- struct sk_buff *skb; ++ struct sk_buff *skb, *next_skb; + + while ((skb = __skb_dequeue(&sd->process_queue))) { + rcu_read_lock(); ++ ++ next_skb = skb_peek(&sd->process_queue); ++ if (likely(next_skb)) { ++ prefetch(next_skb->data); ++ } ++ + __netif_receive_skb(skb); + rcu_read_unlock(); + input_queue_head_incr(sd); +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index bcfa460..eaf8bcb 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -87,6 +87,31 @@ + + #include "dev.h" + #include "sock_destructor.h" ++#include "skbuff_recycle.h" ++ ++struct kmem_cache *skb_data_cache; ++/* ++ * For low memory profile, NSS_SKB_FIXED_SIZE_2K is enabled and ++ * CONFIG_SKB_RECYCLER is disabled. For premium and enterprise profile ++ * CONFIG_SKB_RECYCLER is enabled and NSS_SKB_FIXED_SIZE_2K is disabled. ++ * Irrespective of NSS_SKB_FIXED_SIZE_2K enabled/disabled, the ++ * CONFIG_SKB_RECYCLER and __LP64__ determines the value of SKB_DATA_CACHE_SIZE ++ */ ++#if defined(CONFIG_SKB_RECYCLER) ++/* ++ * 2688 for 64bit arch, 2624 for 32bit arch ++ */ ++#define SKB_DATA_CACHE_SIZE (SKB_DATA_ALIGN(SKB_RECYCLE_SIZE + NET_SKB_PAD) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) ++#else ++/* ++ * 2368 for 64bit arch, 2176 for 32bit arch ++ */ ++#if defined(__LP64__) ++#define SKB_DATA_CACHE_SIZE ((SKB_DATA_ALIGN(1984 + NET_SKB_PAD)) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) ++#else ++#define SKB_DATA_CACHE_SIZE ((SKB_DATA_ALIGN(1856 + NET_SKB_PAD)) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) ++#endif ++#endif + + struct kmem_cache *skbuff_cache __ro_after_init; + static struct kmem_cache *skbuff_fclone_cache __ro_after_init; +@@ -551,21 +576,20 @@ static void *kmalloc_reserve(unsigned int *size, gfp_t flags, int node, + bool *pfmemalloc) + { + bool ret_pfmemalloc = false; +- size_t obj_size; ++ unsigned int obj_size = *size; + void *obj; + + obj_size = SKB_HEAD_ALIGN(*size); +- if (obj_size <= SKB_SMALL_HEAD_CACHE_SIZE && +- !(flags & KMALLOC_NOT_NORMAL_BITS)) { +- obj = kmem_cache_alloc_node(skb_small_head_cache, +- flags | __GFP_NOMEMALLOC | __GFP_NOWARN, +- node); +- *size = SKB_SMALL_HEAD_CACHE_SIZE; ++ if (obj_size > SZ_2K && obj_size <= SKB_DATA_CACHE_SIZE) { ++ obj = kmem_cache_alloc_node(skb_data_cache, ++ flags | __GFP_NOMEMALLOC | __GFP_NOWARN, ++ node); ++ *size = SKB_DATA_CACHE_SIZE; + if (obj || !(gfp_pfmemalloc_allowed(flags))) + goto out; + /* Try again but now we are using pfmemalloc reserves */ + ret_pfmemalloc = true; +- obj = kmem_cache_alloc_node(skb_small_head_cache, flags, node); ++ obj = kmem_cache_alloc_node(skb_data_cache, flags, node); + goto out; + } + +@@ -648,10 +671,12 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, + * aligned memory blocks, unless SLUB/SLAB debug is enabled. + * Both skb->head and skb_shared_info are cache line aligned. + */ ++ size = SKB_DATA_ALIGN(size); ++ size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + data = kmalloc_reserve(&size, gfp_mask, node, &pfmemalloc); + if (unlikely(!data)) + goto nodata; +- /* kmalloc_size_roundup() might give us more room than requested. ++ /* kmalloc_reserve(size) might give us more room than requested. + * Put skb_shared_info exactly at the end of allocated zone, + * to allow max possible filling before reallocation. + */ +@@ -686,7 +711,7 @@ EXPORT_SYMBOL(__alloc_skb); + /** + * __netdev_alloc_skb - allocate an skbuff for rx on a specific device + * @dev: network device to receive on +- * @len: length to allocate ++ * @length: length to allocate + * @gfp_mask: get_free_pages mask, passed to alloc_skb + * + * Allocate a new &sk_buff and assign it a usage count of one. The +@@ -696,29 +721,53 @@ EXPORT_SYMBOL(__alloc_skb); + * + * %NULL is returned if there is no free memory. + */ +-struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int len, +- gfp_t gfp_mask) ++struct sk_buff *__netdev_alloc_skb(struct net_device *dev, ++ unsigned int length, gfp_t gfp_mask) + { +- struct page_frag_cache *nc; + struct sk_buff *skb; ++ unsigned int len = length; ++ ++#ifdef CONFIG_SKB_RECYCLER ++ skb = skb_recycler_alloc(dev, length); ++ if (likely(skb)) ++ return skb; ++ ++ len = SKB_RECYCLE_SIZE; ++ if (unlikely(length > SKB_RECYCLE_SIZE)) ++ len = length; ++ ++ skb = __alloc_skb(len + NET_SKB_PAD, gfp_mask, ++ SKB_ALLOC_RX, NUMA_NO_NODE); ++ if (!skb) ++ goto skb_fail; ++ goto skb_success; ++#else ++ struct page_frag_cache *nc; + bool pfmemalloc; ++ bool page_frag_alloc_enable = true; + void *data; + + len += NET_SKB_PAD; + ++ ++#ifdef CONFIG_ALLOC_SKB_PAGE_FRAG_DISABLE ++ page_frag_alloc_enable = false; ++#endif + /* If requested length is either too small or too big, + * we use kmalloc() for skb->head allocation. + */ + if (len <= SKB_WITH_OVERHEAD(1024) || + len > SKB_WITH_OVERHEAD(PAGE_SIZE) || +- (gfp_mask & (__GFP_DIRECT_RECLAIM | GFP_DMA))) { ++ (gfp_mask & (__GFP_DIRECT_RECLAIM | GFP_DMA)) || ++ !page_frag_alloc_enable) { + skb = __alloc_skb(len, gfp_mask, SKB_ALLOC_RX, NUMA_NO_NODE); + if (!skb) + goto skb_fail; + goto skb_success; + } + +- len = SKB_HEAD_ALIGN(len); ++ len += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); ++ len = SKB_DATA_ALIGN(len); + + if (sk_memalloc_socks()) + gfp_mask |= __GFP_MEMALLOC; +@@ -747,6 +796,7 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int len, + if (pfmemalloc) + skb->pfmemalloc = 1; + skb->head_frag = 1; ++#endif + + skb_success: + skb_reserve(skb, NET_SKB_PAD); +@@ -817,7 +867,8 @@ struct sk_buff *__napi_alloc_skb(struct napi_struct *napi, unsigned int len, + data = page_frag_alloc_1k(&nc->page_small, gfp_mask); + pfmemalloc = NAPI_SMALL_PAGE_PFMEMALLOC(nc->page_small); + } else { +- len = SKB_HEAD_ALIGN(len); ++ len += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); ++ len = SKB_DATA_ALIGN(len); + + data = page_frag_alloc(&nc->page, len, gfp_mask); + pfmemalloc = nc->page.pfmemalloc; +@@ -975,7 +1026,7 @@ static void skb_free_head(struct sk_buff *skb, bool napi_safe) + } + } + +-static void skb_release_data(struct sk_buff *skb, enum skb_drop_reason reason, ++void skb_release_data(struct sk_buff *skb, enum skb_drop_reason reason, + bool napi_safe) + { + struct skb_shared_info *shinfo = skb_shinfo(skb); +@@ -1018,7 +1069,7 @@ static void skb_release_data(struct sk_buff *skb, enum skb_drop_reason reason, + /* + * Free an skbuff by memory without cleaning the state. + */ +-static void kfree_skbmem(struct sk_buff *skb) ++void kfree_skbmem(struct sk_buff *skb) + { + struct sk_buff_fclones *fclones; + +@@ -1282,7 +1333,6 @@ void skb_tx_error(struct sk_buff *skb) + } + EXPORT_SYMBOL(skb_tx_error); + +-#ifdef CONFIG_TRACEPOINTS + /** + * consume_skb - free an skbuff + * @skb: buffer to free +@@ -1291,13 +1341,48 @@ EXPORT_SYMBOL(skb_tx_error); + * Functions identically to kfree_skb, but kfree_skb assumes that the frame + * is being dropped after a failure and notes that + */ ++#ifdef CONFIG_SKB_RECYCLER + void consume_skb(struct sk_buff *skb) + { + if (!skb_unref(skb)) + return; ++ prefetch(&skb->destructor); ++ ++ /*Tian: Not sure if we need to continue using this since ++ * since unref does the work in 5.4 ++ */ ++ ++ /* ++ if (likely(atomic_read(&skb->users) == 1)) ++ smp_rmb(); ++ else if (likely(!atomic_dec_and_test(&skb->users))) ++ return; ++ */ + ++ /* If possible we'd like to recycle any skb rather than just free it, ++ * but in order to do that we need to release any head state too. ++ * We don't want to do this later because we'll be in a pre-emption ++ * disabled state. ++ */ ++ skb_release_head_state(skb); ++ ++ /* Can we recycle this skb? If we can then it will be much faster ++ * for us to recycle this one later than to allocate a new one ++ * from scratch. ++ */ ++ if (likely(skb->head) && likely(skb_recycler_consume(skb))) ++ return; ++ ++#ifdef CONFIG_TRACEPOINTS + trace_consume_skb(skb, __builtin_return_address(0)); +- __kfree_skb(skb); ++#endif ++ /* We're not recycling so now we need to do the rest of what we would ++ * have done in __kfree_skb (above and beyond the skb_release_head_state ++ * that we already did). ++ */ ++ if (likely(skb->head)) ++ skb_release_data(skb, SKB_CONSUMED, false); ++ kfree_skbmem(skb); + } + EXPORT_SYMBOL(consume_skb); + #endif +@@ -2107,6 +2192,8 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, + if (skb_pfmemalloc(skb)) + gfp_mask |= __GFP_MEMALLOC; + ++ size = SKB_DATA_ALIGN(size); ++ size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + data = kmalloc_reserve(&size, gfp_mask, NUMA_NO_NODE, NULL); + if (!data) + goto nodata; +@@ -4854,6 +4941,10 @@ static void skb_extensions_init(void) {} + + void __init skb_init(void) + { ++ skb_data_cache = kmem_cache_create_usercopy("skb_data_cache", ++ SKB_DATA_CACHE_SIZE, ++ 0, SLAB_PANIC, 0, SKB_DATA_CACHE_SIZE, ++ NULL); + skbuff_cache = kmem_cache_create_usercopy("skbuff_head_cache", + sizeof(struct sk_buff), + 0, +@@ -4879,6 +4970,7 @@ void __init skb_init(void) + SKB_SMALL_HEAD_HEADROOM, + NULL); + skb_extensions_init(); ++ skb_recycler_init(); + } + + static int +@@ -6382,6 +6474,8 @@ static int pskb_carve_inside_header(struct sk_buff *skb, const u32 off, + if (skb_pfmemalloc(skb)) + gfp_mask |= __GFP_MEMALLOC; + ++ size = SKB_DATA_ALIGN(size); ++ size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + data = kmalloc_reserve(&size, gfp_mask, NUMA_NO_NODE, NULL); + if (!data) + return -ENOMEM; +@@ -6498,6 +6592,8 @@ static int pskb_carve_inside_nonlinear(struct sk_buff *skb, const u32 off, + if (skb_pfmemalloc(skb)) + gfp_mask |= __GFP_MEMALLOC; + ++ size = SKB_DATA_ALIGN(size); ++ size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + data = kmalloc_reserve(&size, gfp_mask, NUMA_NO_NODE, NULL); + if (!data) + return -ENOMEM; diff --git a/target/linux/qualcommax/patches-6.6/9999-revert-crypto-api-disallow-identical-driver-names.patch b/target/linux/qualcommax/patches-6.6/9999-revert-crypto-api-disallow-identical-driver-names.patch new file mode 100644 index 00000000000000..3f7f58dfee5af2 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/9999-revert-crypto-api-disallow-identical-driver-names.patch @@ -0,0 +1,10 @@ +--- a/crypto/algapi.c ++++ b/crypto/algapi.c +@@ -341,7 +341,6 @@ __crypto_register_alg(struct crypto_alg + } + + if (!strcmp(q->cra_driver_name, alg->cra_name) || +- !strcmp(q->cra_driver_name, alg->cra_driver_name) || + !strcmp(q->cra_name, alg->cra_driver_name)) + goto err; + } diff --git a/target/linux/qualcommax/patches-6.6/9999-silence-UBI-NAND-warnings.patch b/target/linux/qualcommax/patches-6.6/9999-silence-UBI-NAND-warnings.patch new file mode 100644 index 00000000000000..646e683dc8df70 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/9999-silence-UBI-NAND-warnings.patch @@ -0,0 +1,13 @@ +--- a/drivers/mtd/mtdblock.c ++++ b/drivers/mtd/mtdblock.c +@@ -261,10 +261,6 @@ static int mtdblock_open(struct mtd_blkt + return 0; + } + +- if (mtd_type_is_nand(mbd->mtd)) +- pr_warn_ratelimited("%s: MTD device '%s' is NAND, please consider using UBI block devices instead.\n", +- mbd->tr->name, mbd->mtd->name); +- + /* OK, it's not open. Create cache info for it */ + mtdblk->count = 1; + mutex_init(&mtdblk->cache_mutex); From 94b79b74bc69e94d2509a5caa2cd212c9342cd2b Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 24 Mar 2024 22:57:55 -0400 Subject: [PATCH 156/225] nat46: fix build by removing leftover patches --- .../nat46/patches/100-kernel-5.4-compat.patch | 34 ----- .../113-fix_delete_race_condition.patch | 52 ------- ...114-fix-get-release-instance-protect.patch | 51 ------- .../115-export-ip6_update_csm-api.patch | 33 ---- ...7-fix-proc_create-to-file_operations.patch | 43 ------ .../nat46/patches/118-add-nat46_remove.patch | 80 ---------- .../119-upgrade-alloc_nat46_instance.patch | 56 ------- ...ayload-length-wrong-in-fragment-case.patch | 144 ------------------ .../17-add-support-ipv6-udp-checksum-0.patch | 32 ---- .../nat46/patches/900-kernel-6.1-compat.patch | 39 ----- 10 files changed, 564 deletions(-) delete mode 100644 package/kernel/nat46/patches/100-kernel-5.4-compat.patch delete mode 100644 package/kernel/nat46/patches/113-fix_delete_race_condition.patch delete mode 100644 package/kernel/nat46/patches/114-fix-get-release-instance-protect.patch delete mode 100644 package/kernel/nat46/patches/115-export-ip6_update_csm-api.patch delete mode 100644 package/kernel/nat46/patches/117-fix-proc_create-to-file_operations.patch delete mode 100644 package/kernel/nat46/patches/118-add-nat46_remove.patch delete mode 100644 package/kernel/nat46/patches/119-upgrade-alloc_nat46_instance.patch delete mode 100644 package/kernel/nat46/patches/16-fix-l3_payload-length-wrong-in-fragment-case.patch delete mode 100644 package/kernel/nat46/patches/17-add-support-ipv6-udp-checksum-0.patch delete mode 100644 package/kernel/nat46/patches/900-kernel-6.1-compat.patch diff --git a/package/kernel/nat46/patches/100-kernel-5.4-compat.patch b/package/kernel/nat46/patches/100-kernel-5.4-compat.patch deleted file mode 100644 index 6a638e96b5ad67..00000000000000 --- a/package/kernel/nat46/patches/100-kernel-5.4-compat.patch +++ /dev/null @@ -1,34 +0,0 @@ ---- a/nat46/modules/nat46-core.c -+++ b/nat46/modules/nat46-core.c -@@ -17,6 +17,7 @@ - */ - - #include -+#include - - #include "nat46-glue.h" - #include "nat46-core.h" -@@ -1601,7 +1602,11 @@ void nat46_ipv6_input(struct sk_buff *ol - /* Remove any debris in the socket control block */ - memset(IPCB(new_skb), 0, sizeof(struct inet_skb_parm)); - /* Remove netfilter references to IPv6 packet, new netfilter references will be created based on IPv4 packet */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) - nf_reset(new_skb); -+#else -+ nf_reset_ct(new_skb); -+#endif - - /* modify packet: actual IPv6->IPv4 transformation */ - truncSize = v6packet_l3size - sizeof(struct iphdr); /* chop first 20 bytes */ -@@ -1806,7 +1811,11 @@ void nat46_ipv4_input(struct sk_buff *ol - /* Remove any debris in the socket control block */ - memset(IPCB(new_skb), 0, sizeof(struct inet_skb_parm)); - /* Remove netfilter references to IPv4 packet, new netfilter references will be created based on IPv6 packet */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) - nf_reset(new_skb); -+#else -+ nf_reset_ct(new_skb); -+#endif - - /* expand header (add 20 extra bytes at the beginning of sk_buff) */ - pskb_expand_head(new_skb, IPV6V4HDRDELTA + (add_frag_header?8:0), 0, GFP_ATOMIC); diff --git a/package/kernel/nat46/patches/113-fix_delete_race_condition.patch b/package/kernel/nat46/patches/113-fix_delete_race_condition.patch deleted file mode 100644 index add6c36a46b97a..00000000000000 --- a/package/kernel/nat46/patches/113-fix_delete_race_condition.patch +++ /dev/null @@ -1,52 +0,0 @@ -Author: Pavithra R -Date: Wed Aug 5 21:16:50 2020 +0530 - -nat46: fix nat46 crash during stability test - -This patch is propagated from the kernel 4.4 commit -8a2df2e4170f6f9b7eb0930d067e197bfec68129 - -when deleting the same device in a very close time, the first deletion -is not finished yet, the second one will hit the BUG_ON. - -Change-Id: I09ec95a132e925a304b57c35d1cb51619be37229 -Signed-off-by: Pavithra R - ---- a/nat46/modules/nat46-module.c -+++ b/nat46/modules/nat46-module.c -@@ -61,6 +61,7 @@ bool add_dummy_header = 0; - module_param(add_dummy_header, bool, 0); - MODULE_PARM_DESC(add_dummy_header, "Add dummy fragment header"); - -+static DEFINE_MUTEX(add_del_lock); - static struct proc_dir_entry *nat46_proc_entry; - static struct proc_dir_entry *nat46_proc_parent; - -@@ -115,19 +116,27 @@ static ssize_t nat46_proc_write(struct f - if (0 == strcmp(arg_name, "add")) { - devname = get_devname(&tail); - printk(KERN_INFO "nat46: adding device (%s)\n", devname); -+ mutex_lock(&add_del_lock); - nat46_create(devname); -+ mutex_unlock(&add_del_lock); - } else if (0 == strcmp(arg_name, "del")) { - devname = get_devname(&tail); - printk(KERN_INFO "nat46: deleting device (%s)\n", devname); -+ mutex_lock(&add_del_lock); - nat46_destroy(devname); -+ mutex_unlock(&add_del_lock); - } else if (0 == strcmp(arg_name, "config")) { - devname = get_devname(&tail); - printk(KERN_INFO "nat46: configure device (%s) with '%s'\n", devname, tail); -+ mutex_lock(&add_del_lock); - nat46_configure(devname, tail); -+ mutex_unlock(&add_del_lock); - } else if (0 == strcmp(arg_name, "insert")) { - devname = get_devname(&tail); - printk(KERN_INFO "nat46: insert new rule into device (%s) with '%s'\n", devname, tail); -+ mutex_lock(&add_del_lock); - nat46_insert(devname, tail); -+ mutex_unlock(&add_del_lock); - } - } - diff --git a/package/kernel/nat46/patches/114-fix-get-release-instance-protect.patch b/package/kernel/nat46/patches/114-fix-get-release-instance-protect.patch deleted file mode 100644 index 9258f783cd86b9..00000000000000 --- a/package/kernel/nat46/patches/114-fix-get-release-instance-protect.patch +++ /dev/null @@ -1,51 +0,0 @@ -Author: Pavithra R -Date: Thu Aug 13 12:59:50 2020 +0530 - -This patch is propogated from the kernel 4.4 commit -56e2435c782e7cdb5c274ea012557f525d0a3b88 - -nat46: fix race condition in the get and release operation - -when get and release the nat46 instance, it could run into race -condition, use spin_lock protect them. - -Change-Id: I7a38164699a5b856f3407dae592a3d8fc82e7ffe -Signed-off-by: Pavithra R - ---- a/nat46/modules/nat46-glue.c -+++ b/nat46/modules/nat46-glue.c -@@ -18,6 +18,7 @@ - #include "nat46-glue.h" - #include "nat46-core.h" - -+static DEFINE_MUTEX(ref_lock); - int is_valid_nat46(nat46_instance_t *nat46) { - return (nat46 && (nat46->sig == NAT46_SIGNATURE)); - } -@@ -46,20 +47,25 @@ nat46_instance_t *alloc_nat46_instance(i - - nat46_instance_t *get_nat46_instance(struct sk_buff *sk) { - nat46_instance_t *nat46 = netdev_nat46_instance(sk->dev); -+ mutex_lock(&ref_lock); - if (is_valid_nat46(nat46)) { - nat46->refcount++; -+ mutex_unlock(&ref_lock); - return nat46; - } else { -+ mutex_unlock(&ref_lock); - printk("[nat46] get_nat46_instance: Could not find a valid NAT46 instance!"); - return NULL; - } - } - - void release_nat46_instance(nat46_instance_t *nat46) { -+ mutex_lock(&ref_lock); - nat46->refcount--; - if(0 == nat46->refcount) { -- printk("[nat46] release_nat46_instance: freeing nat46 instance with %d pairs\n", nat46->npairs); - nat46->sig = FREED_NAT46_SIGNATURE; -+ printk("[nat46] release_nat46_instance: freeing nat46 instance with %d pairs\n", nat46->npairs); - kfree(nat46); - } -+ mutex_unlock(&ref_lock); - } diff --git a/package/kernel/nat46/patches/115-export-ip6_update_csm-api.patch b/package/kernel/nat46/patches/115-export-ip6_update_csm-api.patch deleted file mode 100644 index 37cb14367e3d22..00000000000000 --- a/package/kernel/nat46/patches/115-export-ip6_update_csm-api.patch +++ /dev/null @@ -1,33 +0,0 @@ -Author: Pavithra R -Date: Tue Sep 22 10:49:35 2020 +0530 - -This patch is propogated from the kernel 4.4 commit -0907c30387c89bbec23f426891a756ca17e421ed - -nat46: export ip6_update_csum api - -export ip6_update_csum for other modules. - -Change-Id: I08de067f7a2d54d687c352154f1a1ab441652445 -Signed-off-by: Pavithra R - ---- a/nat46/modules/nat46-core.c -+++ b/nat46/modules/nat46-core.c -@@ -1972,6 +1972,7 @@ void ip6_update_csum(struct sk_buff * sk - } - } - } -+EXPORT_SYMBOL(ip6_update_csum); - - int ip4_input_not_interested(nat46_instance_t *nat46, struct iphdr *iph, struct sk_buff *old_skb) { - if (old_skb->protocol != htons(ETH_P_IP)) { ---- a/nat46/modules/nat46-core.h -+++ b/nat46/modules/nat46-core.h -@@ -111,6 +111,7 @@ void release_nat46_instance(nat46_instan - - int xlate_6_to_4(struct net_device *dev, struct ipv6hdr *ip6h, uint16_t proto, __u32 *pv4saddr, __u32 *pv4daddr); - int xlate_4_to_6(struct net_device *dev, struct iphdr *hdr4, uint16_t sport, uint16_t dport, void *v6saddr, void *v6daddr); -+void ip6_update_csum(struct sk_buff * skb, struct ipv6hdr * ip6hdr, int do_atomic_frag); - bool nat46_get_rule_config(struct net_device *dev, nat46_xlate_rulepair_t **nat46_rule_pair, int *count); - int nat46_get_npairs(struct net_device *dev); - bool nat46_get_info(struct net_device *dev, nat46_xlate_rulepair_t **nat46_rule_pair, diff --git a/package/kernel/nat46/patches/117-fix-proc_create-to-file_operations.patch b/package/kernel/nat46/patches/117-fix-proc_create-to-file_operations.patch deleted file mode 100644 index b50d32feb0d4be..00000000000000 --- a/package/kernel/nat46/patches/117-fix-proc_create-to-file_operations.patch +++ /dev/null @@ -1,43 +0,0 @@ ---- a/nat46/modules/nat46-module.c -+++ b/nat46/modules/nat46-module.c -@@ -15,6 +15,7 @@ - * - */ - -+#include - #include - #include - #include -@@ -82,7 +83,7 @@ static char *get_devname(char **ptail) - { - const int maxlen = IFNAMSIZ-1; - char *devname = get_next_arg(ptail); -- if(strlen(devname) > maxlen) { -+ if(devname && (strlen(devname) > maxlen)) { - printk(KERN_INFO "nat46: '%s' is " - "longer than %d chars, truncating\n", devname, maxlen); - devname[maxlen] = 0; -@@ -144,6 +145,7 @@ static ssize_t nat46_proc_write(struct f - return count; - } - -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5,6,0) - static const struct file_operations nat46_proc_fops = { - .owner = THIS_MODULE, - .open = nat46_proc_open, -@@ -152,6 +154,15 @@ static const struct file_operations nat4 - .release = single_release, - .write = nat46_proc_write, - }; -+#else -+static const struct proc_ops nat46_proc_fops = { -+ .proc_open = nat46_proc_open, -+ .proc_read = seq_read, -+ .proc_lseek = seq_lseek, -+ .proc_release = single_release, -+ .proc_write = nat46_proc_write, -+}; -+#endif - - - int create_nat46_proc_entry(void) { diff --git a/package/kernel/nat46/patches/118-add-nat46_remove.patch b/package/kernel/nat46/patches/118-add-nat46_remove.patch deleted file mode 100644 index 424939f29013e7..00000000000000 --- a/package/kernel/nat46/patches/118-add-nat46_remove.patch +++ /dev/null @@ -1,80 +0,0 @@ ---- a/nat46/modules/nat46-module.c -+++ b/nat46/modules/nat46-module.c -@@ -138,6 +138,12 @@ static ssize_t nat46_proc_write(struct f - mutex_lock(&add_del_lock); - nat46_insert(devname, tail); - mutex_unlock(&add_del_lock); -+ } else if (0 == strcmp(arg_name, "remove")) { -+ devname = get_devname(&tail); -+ printk(KERN_INFO "nat46: remove a rule from the device (%s) with '%s'\n", devname, tail); -+ mutex_lock(&add_del_lock); -+ nat46_remove(devname, tail); -+ mutex_unlock(&add_del_lock); - } - } - ---- a/nat46/modules/nat46-netdev.c -+++ b/nat46/modules/nat46-netdev.c -@@ -337,6 +337,46 @@ int nat46_configure(char *devname, char - } - } - -+int nat46_remove(char *devname, char *buf) { -+ int ret = -1; -+ char config_remove[NAT46_CFG_BUFLEN]; -+ struct net_device *dev; -+ nat46_instance_t *nat46; -+ nat46_instance_t *nat46_remove; -+ int result_rem; -+ int i; -+ -+ if((dev = find_dev(devname)) == NULL || -+ (nat46 = netdev_nat46_instance(dev)) == NULL || -+ (nat46_remove = alloc_nat46_instance(1, NULL, -1, -1, -1)) == NULL) { -+ return ret; -+ } -+ -+ if(nat46_set_ipair_config(nat46_remove, 0, buf, NAT46_CFG_BUFLEN) < 0) { -+ release_nat46_instance(nat46_remove); -+ return ret; -+ } -+ -+ result_rem = nat46_get_ipair_config(nat46_remove, 0, config_remove, NAT46_CFG_BUFLEN); -+ for(i = 0; i < nat46->npairs; i++) { -+ char config[NAT46_CFG_BUFLEN]; -+ int result = nat46_get_ipair_config(nat46, i, config, NAT46_CFG_BUFLEN); -+ -+ if (result_rem == result && strncmp(config_remove, config, result_rem) == 0) { -+ nat46_instance_t *nat46_new = alloc_nat46_instance(nat46->npairs-1, nat46, 0, 0, i); -+ if(nat46_new) { -+ netdev_nat46_set_instance(dev, nat46_new); -+ ret = 0; -+ } else { -+ printk("Could not remove the rule from device %s\n", devname); -+ } -+ break; -+ } -+ } -+ release_nat46_instance(nat46_remove); -+ return ret; -+} -+ - void nat64_show_all_configs(struct seq_file *m) { - struct net_device *dev; - read_lock(&dev_base_lock); ---- a/nat46/modules/nat46-netdev.h -+++ b/nat46/modules/nat46-netdev.h -@@ -14,11 +14,13 @@ - */ - - #define NAT46_DEVICE_SIGNATURE 0x544e36dd -+#define NAT46_CFG_BUFLEN 200 - - int nat46_create(char *devname); - int nat46_destroy(char *devname); - int nat46_insert(char *devname, char *buf); - int nat46_configure(char *devname, char *buf); -+int nat46_remove(char *devname, char *buf); - void nat46_destroy_all(void); - void nat64_show_all_configs(struct seq_file *m); - void nat46_netdev_count_xmit(struct sk_buff *skb, struct net_device *dev); diff --git a/package/kernel/nat46/patches/119-upgrade-alloc_nat46_instance.patch b/package/kernel/nat46/patches/119-upgrade-alloc_nat46_instance.patch deleted file mode 100644 index b86369281c7fd1..00000000000000 --- a/package/kernel/nat46/patches/119-upgrade-alloc_nat46_instance.patch +++ /dev/null @@ -1,56 +0,0 @@ ---- a/nat46/modules/nat46-core.h -+++ b/nat46/modules/nat46-core.h -@@ -106,7 +106,7 @@ int nat46_get_config(nat46_instance_t *n - char *get_next_arg(char **ptail); - nat46_instance_t *get_nat46_instance(struct sk_buff *sk); - --nat46_instance_t *alloc_nat46_instance(int npairs, nat46_instance_t *old, int from_ipair, int to_ipair); -+nat46_instance_t *alloc_nat46_instance(int npairs, nat46_instance_t *old, int from_ipair, int to_ipair, int remove_ipair); - void release_nat46_instance(nat46_instance_t *nat46); - - int xlate_6_to_4(struct net_device *dev, struct ipv6hdr *ip6h, uint16_t proto, __u32 *pv4saddr, __u32 *pv4daddr); ---- a/nat46/modules/nat46-glue.c -+++ b/nat46/modules/nat46-glue.c -@@ -23,7 +23,7 @@ int is_valid_nat46(nat46_instance_t *nat - return (nat46 && (nat46->sig == NAT46_SIGNATURE)); - } - --nat46_instance_t *alloc_nat46_instance(int npairs, nat46_instance_t *old, int from_ipair, int to_ipair) { -+nat46_instance_t *alloc_nat46_instance(int npairs, nat46_instance_t *old, int from_ipair, int to_ipair, int remove_ipair) { - nat46_instance_t *nat46 = kzalloc(sizeof(nat46_instance_t) + npairs*sizeof(nat46_xlate_rulepair_t), GFP_KERNEL); - if (!nat46) { - printk("[nat46] make_nat46_instance: can not alloc a nat46 instance with %d pairs\n", npairs); -@@ -37,8 +37,11 @@ nat46_instance_t *alloc_nat46_instance(i - if (old) { - nat46->debug = old->debug; - for(; (from_ipair >= 0) && (to_ipair >= 0) && -- (from_ipair < old->npairs) && (to_ipair < nat46->npairs); from_ipair++, to_ipair++) { -- nat46->pairs[to_ipair] = old->pairs[from_ipair]; -+ (from_ipair < old->npairs) && (to_ipair < nat46->npairs); from_ipair++) { -+ if (from_ipair != remove_ipair) { -+ nat46->pairs[to_ipair] = old->pairs[from_ipair]; -+ to_ipair++; -+ } - } - } - return nat46; ---- a/nat46/modules/nat46-netdev.c -+++ b/nat46/modules/nat46-netdev.c -@@ -155,7 +155,7 @@ static void netdev_nat46_set_instance(st - static void nat46_netdev_setup(struct net_device *dev) - { - nat46_netdev_priv_t *priv = netdev_priv(dev); -- nat46_instance_t *nat46 = alloc_nat46_instance(1, NULL, -1, -1); -+ nat46_instance_t *nat46 = alloc_nat46_instance(1, NULL, -1, -1, -1); - - memset(priv, 0, sizeof(*priv)); - priv->sig = NAT46_DEVICE_SIGNATURE; -@@ -316,7 +316,7 @@ int nat46_insert(char *devname, char *bu - return ret; - } - -- nat46_new = alloc_nat46_instance(nat46->npairs+1, nat46, 0, 1); -+ nat46_new = alloc_nat46_instance(nat46->npairs+1, nat46, 0, 1, -1); - if(nat46_new) { - netdev_nat46_set_instance(dev, nat46_new); - ret = nat46_set_ipair_config(nat46_new, 0, buf, strlen(buf)); diff --git a/package/kernel/nat46/patches/16-fix-l3_payload-length-wrong-in-fragment-case.patch b/package/kernel/nat46/patches/16-fix-l3_payload-length-wrong-in-fragment-case.patch deleted file mode 100644 index 22828f262a4847..00000000000000 --- a/package/kernel/nat46/patches/16-fix-l3_payload-length-wrong-in-fragment-case.patch +++ /dev/null @@ -1,144 +0,0 @@ -Author: Ken Zhu -Date: Fri Mar 26 12:27:17 2021 -0700 - - [nat46]: fix icmp checksum error based on the correct packet length - - UDP/TCP checksum includes the pseudo header in addition to the palyload. - But in nat46 case, their length in the pseudo header could be ignored - since it keeps unchanged between IPv4/IPv6 transition. - - ICMPv6 checksum includes pseudo IPV6 header in addition to packet payload - while ICMPv4 does not counter in the pseudo header. - the length of pseudo header should count in all fragmented payload. - - The change get the length by reassembling the fragments. - - Change-Id: I56e59958aa21eed5b595ae1a9ab02285dba2185b - Signed-off-by: Ken Zhu ---- a/nat46/modules/nat46-core.c -+++ b/nat46/modules/nat46-core.c -@@ -18,6 +18,8 @@ - - #include - #include -+#include -+#include - - #include "nat46-glue.h" - #include "nat46-core.h" -@@ -1751,7 +1753,8 @@ void nat46_ipv6_input(struct sk_buff *ol - - struct iphdr * iph; - __u32 v4saddr, v4daddr; -- struct sk_buff * new_skb = 0; -+ struct sk_buff *new_skb = NULL; -+ struct sk_buff *reasm_skb = NULL; - int truncSize = 0; - int tailTruncSize = 0; - int v6packet_l3size = sizeof(*ip6h); -@@ -1802,6 +1805,46 @@ void nat46_ipv6_input(struct sk_buff *ol - frag_id = fold_ipv6_frag_id(fh->identification); - nat46debug(2, "Not first fragment, frag_off: %04X, frag id: %04X orig frag_off: %04X", ntohs(frag_off), frag_id, ntohs(fh->frag_off)); - } -+ -+ /* ICMPv6 counts the pseudo ipv6 header into its checksum, but ICMP doesn't -+ * but the length filed of the pseudo header count in all fragmented -+ * packets, so we need gather the framented packets into one packet to -+ * get the l3 payload length. -+ */ -+ if (proto == NEXTHDR_ICMP) { -+ struct sk_buff *skb = skb_get(old_skb); -+ int err; -+ if (skb == NULL) { -+ goto done; -+ } -+ -+ err = nf_ct_frag6_gather(dev_net(old_skb->dev), skb, IP6_DEFRAG_LOCAL_DELIVER); -+ -+ /* EINPROGRESS means the skb was queued but the gather not finished yet */ -+ if (err == -EINPROGRESS) { -+ goto done; -+ } -+ -+ reasm_skb = skb; -+ /* other than EINPROGRESS error returned means the skb wasn't queued -+ * 0 returned means that all fragments are all gathered -+ * and the original skb was queued -+ */ -+ if (err != 0) { -+ goto done; -+ } -+ -+ /* Use the reassembly packet as the input */ -+ ip6h = ipv6_hdr(reasm_skb); -+ proto = ip6h->nexthdr; -+ v6packet_l3size = sizeof(*ip6h); -+ -+ /* No fragment header in the re-assembly packet */ -+ frag_off = 0; -+ l3_infrag_payload_len = ntohs(ip6h->payload_len); -+ old_skb = reasm_skb; -+ check_for_l4 = 1; -+ } - } - } else { - frag_off = htons(IP_DF); -@@ -1850,20 +1893,28 @@ void nat46_ipv6_input(struct sk_buff *ol - /* CHECKSUMS UPDATE */ - case NEXTHDR_TCP: { - struct tcphdr *th = add_offset(ip6h, v6packet_l3size); -- u16 sum1 = csum_ipv6_unmagic(nat46, &ip6h->saddr, &ip6h->daddr, l3_infrag_payload_len, NEXTHDR_TCP, th->check); -- u16 sum2 = csum_tcpudp_remagic(v4saddr, v4daddr, l3_infrag_payload_len, NEXTHDR_TCP, sum1); -+ -+ /* TCP payload length won't change, needn't unmagic its value. */ -+ u16 sum1 = csum_ipv6_unmagic(nat46, &ip6h->saddr, &ip6h->daddr, 0, NEXTHDR_TCP, th->check); -+ u16 sum2 = csum_tcpudp_remagic(v4saddr, v4daddr, 0, NEXTHDR_TCP, sum1); - th->check = sum2; - break; - } - case NEXTHDR_UDP: { - struct udphdr *udp = add_offset(ip6h, v6packet_l3size); -- u16 sum1 = csum_ipv6_unmagic(nat46, &ip6h->saddr, &ip6h->daddr, l3_infrag_payload_len, NEXTHDR_UDP, udp->check); -- u16 sum2 = csum_tcpudp_remagic(v4saddr, v4daddr, l3_infrag_payload_len, NEXTHDR_UDP, sum1); -+ -+ /* UDP payload length won't change, needn't unmagic its value. */ -+ u16 sum1 = csum_ipv6_unmagic(nat46, &ip6h->saddr, &ip6h->daddr, 0, NEXTHDR_UDP, udp->check); -+ u16 sum2 = csum_tcpudp_remagic(v4saddr, v4daddr, 0, NEXTHDR_UDP, sum1); - udp->check = sum2; - break; - } - case NEXTHDR_ICMP: { - struct icmp6hdr *icmp6h = add_offset(ip6h, v6packet_l3size); -+ -+ /* ICMPv6 count the pseudo IPv6 header into its checksum, but icmp -+ * doesn't, unmagic the whole the pseudo IPv6 header from the checksum. -+ */ - u16 sum1 = csum_ipv6_unmagic(nat46, &ip6h->saddr, &ip6h->daddr, l3_infrag_payload_len, NEXTHDR_ICMP, icmp6h->icmp6_cksum); - icmp6h->icmp6_cksum = sum1; - nat46debug_dump(nat46, 10, icmp6h, l3_infrag_payload_len); -@@ -1909,10 +1960,6 @@ void nat46_ipv6_input(struct sk_buff *ol - fill_v4hdr_from_v6hdr(iph, ip6h, v4saddr, v4daddr, frag_id, frag_off, proto, l3_infrag_payload_len); - new_skb->protocol = htons(ETH_P_IP); - -- if (ntohs(iph->tot_len) >= 2000) { -- nat46debug(0, "Too big IP len: %d", ntohs(iph->tot_len)); -- } -- - nat46debug(5, "about to send v4 packet, flags: %02x", IPCB(new_skb)->flags); - nat46_netdev_count_xmit(new_skb, old_skb->dev); - -@@ -1924,11 +1971,12 @@ void nat46_ipv6_input(struct sk_buff *ol - /* TBD: should copy be released here? */ - - done: -+ if (reasm_skb) { -+ kfree_skb(reasm_skb); -+ } - release_nat46_instance(nat46); - } - -- -- - void ip6_update_csum(struct sk_buff * skb, struct ipv6hdr * ip6hdr, int do_atomic_frag) - { - u32 sum1=0; diff --git a/package/kernel/nat46/patches/17-add-support-ipv6-udp-checksum-0.patch b/package/kernel/nat46/patches/17-add-support-ipv6-udp-checksum-0.patch deleted file mode 100644 index 142a2a89c84354..00000000000000 --- a/package/kernel/nat46/patches/17-add-support-ipv6-udp-checksum-0.patch +++ /dev/null @@ -1,32 +0,0 @@ -Author: Ken Zhu -Date: Wed Feb 17 13:37:15 2021 -0800 - - nat46: keep ipv4 checksum zero when incoming ipv6 UDP checksum is zero - - When an incoming ipv6 UDP packet has 0 checksum, the ipv4 checksum is - kept zero after translation. - - Change-Id: I8ddd0c586e5cfbd5a57dc5632e93543d6db5c312 - Signed-off-by: Ken Zhu - ---- a/nat46/modules/nat46-core.c -+++ b/nat46/modules/nat46-core.c -@@ -1903,10 +1903,14 @@ void nat46_ipv6_input(struct sk_buff *ol - case NEXTHDR_UDP: { - struct udphdr *udp = add_offset(ip6h, v6packet_l3size); - -- /* UDP payload length won't change, needn't unmagic its value. */ -- u16 sum1 = csum_ipv6_unmagic(nat46, &ip6h->saddr, &ip6h->daddr, 0, NEXTHDR_UDP, udp->check); -- u16 sum2 = csum_tcpudp_remagic(v4saddr, v4daddr, 0, NEXTHDR_UDP, sum1); -- udp->check = sum2; -+ /* UDP payload length won't change, needn't unmagic its value. -+ * UDP checksum zero then skip the calculation of the checksum. -+ */ -+ if (udp->check) { -+ u16 sum1 = csum_ipv6_unmagic(nat46, &ip6h->saddr, &ip6h->daddr, 0, NEXTHDR_UDP, udp->check); -+ u16 sum2 = csum_tcpudp_remagic(v4saddr, v4daddr, 0, NEXTHDR_UDP, sum1); -+ udp->check = sum2; -+ } - break; - } - case NEXTHDR_ICMP: { diff --git a/package/kernel/nat46/patches/900-kernel-6.1-compat.patch b/package/kernel/nat46/patches/900-kernel-6.1-compat.patch deleted file mode 100644 index 79cf653df9787d..00000000000000 --- a/package/kernel/nat46/patches/900-kernel-6.1-compat.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- a/nat46/modules/nat46-netdev.c -+++ b/nat46/modules/nat46-netdev.c -@@ -92,8 +92,8 @@ static netdev_tx_t nat46_netdev_xmit(str - struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats); - - u64_stats_update_begin(&tstats->syncp); -- tstats->rx_packets++; -- tstats->rx_bytes += skb->len; -+ u64_stats_inc(&tstats->rx_packets); -+ u64_stats_add(&tstats->rx_bytes, skb->len); - u64_stats_update_end(&tstats->syncp); - put_cpu_ptr(tstats); - if(ETH_P_IP == ntohs(skb->protocol)) { -@@ -110,8 +110,8 @@ void nat46_netdev_count_xmit(struct sk_b - struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats); - - u64_stats_update_begin(&tstats->syncp); -- tstats->tx_packets++; -- tstats->tx_bytes += skb->len; -+ u64_stats_inc(&tstats->tx_packets); -+ u64_stats_add(&tstats->tx_bytes, skb->len); - u64_stats_update_end(&tstats->syncp); - put_cpu_ptr(tstats); - } -@@ -122,10 +122,10 @@ void nat46_update_stats(struct net_devic - struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats); - - u64_stats_update_begin(&tstats->syncp); -- tstats->rx_packets += rx_packets; -- tstats->rx_bytes += rx_bytes; -- tstats->tx_packets += tx_packets; -- tstats->tx_bytes += tx_bytes; -+ u64_stats_add(&tstats->rx_packets, rx_packets); -+ u64_stats_add(&tstats->rx_bytes, rx_bytes); -+ u64_stats_add(&tstats->tx_packets, tx_packets); -+ u64_stats_add(&tstats->tx_bytes, tx_bytes); - dev->stats.rx_dropped += rx_dropped; - dev->stats.tx_dropped += tx_dropped; - u64_stats_update_end(&tstats->syncp); From c14902e786eb4018109ad422ae392b91864a6ad7 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 24 Mar 2024 23:20:41 -0400 Subject: [PATCH 157/225] ath11k_nss: set pbuf to 'auto' Since SKB recycler was merged into main nss-wifi branch, it is not necessary to manually tinker with pbuf script. Memory is now properly managed between NSS driver allocating/deallocating SKBs. For optimal wifi performance, especially upload, it is advised to leave the script to 'auto'. Users who use sysupgrade should manually set the uci config '/etc/config/pbuf' as it will not overwrite existing configuration. --- package/kernel/mac80211/files/pbuf.uci | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/kernel/mac80211/files/pbuf.uci b/package/kernel/mac80211/files/pbuf.uci index 2b277e11f02f4d..4e01048e9bee0e 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' From 09c9841ca20fd09b21c8304ef7e3ed6ca632b148 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 24 Mar 2024 23:36:09 -0400 Subject: [PATCH 158/225] kernel/modules: Remove kernel 5.15 dep kmod-asn1-encoder --- package/kernel/linux/modules/other.mk | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package/kernel/linux/modules/other.mk b/package/kernel/linux/modules/other.mk index c63523b3d446aa..e227fd6a0f98ad 100644 --- a/package/kernel/linux/modules/other.mk +++ b/package/kernel/linux/modules/other.mk @@ -1167,8 +1167,7 @@ $(eval $(call KernelPackage,keys-encrypted)) define KernelPackage/keys-trusted SUBMENU:=$(OTHER_MENU) TITLE:=TPM trusted keys on kernel keyring - DEPENDS:=@KERNEL_KEYS +(LINUX_5_15):kmod-asn1-encoder +kmod-crypto-hash \ - +kmod-crypto-hmac +kmod-crypto-sha1 +kmod-tpm + DEPENDS:=@KERNEL_KEYS +kmod-crypto-hash +kmod-crypto-hmac +kmod-crypto-sha1 +kmod-tpm KCONFIG:=CONFIG_TRUSTED_KEYS FILES:= $(LINUX_DIR)/security/keys/trusted-keys/trusted.ko AUTOLOAD:=$(call AutoLoad,01,trusted-keys,1) From f461837821c031c5b8821dc92de61dc1d4d3662d Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 24 Mar 2024 23:37:32 -0400 Subject: [PATCH 159/225] cryptodev-linux: Add hooks for QCA NSS --- package/kernel/cryptodev-linux/Makefile | 11 ++- .../patches/0005-add-qca-nss.patch | 99 +++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 package/kernel/cryptodev-linux/patches/0005-add-qca-nss.patch diff --git a/package/kernel/cryptodev-linux/Makefile b/package/kernel/cryptodev-linux/Makefile index 0b794a3cd9801f..79d342855e9deb 100644 --- a/package/kernel/cryptodev-linux/Makefile +++ b/package/kernel/cryptodev-linux/Makefile @@ -41,13 +41,22 @@ define KernelPackage/cryptodev/description hardware ciphers by user-space applications. endef +ifneq ($(CONFIG_PACKAGE_kmod-crypto-qce),) +EXTRA_CFLAGS+=-DQCA +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-crypto),) +EXTRA_CFLAGS+=-DQCANSS +endif + define Build/Configure endef define Build/Compile $(MAKE) -C $(PKG_BUILD_DIR) \ $(KERNEL_MAKE_FLAGS) \ - KERNEL_DIR="$(LINUX_DIR)" + KERNEL_DIR="$(LINUX_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" endef define Build/InstallDev diff --git a/package/kernel/cryptodev-linux/patches/0005-add-qca-nss.patch b/package/kernel/cryptodev-linux/patches/0005-add-qca-nss.patch new file mode 100644 index 00000000000000..4f467a18773467 --- /dev/null +++ b/package/kernel/cryptodev-linux/patches/0005-add-qca-nss.patch @@ -0,0 +1,99 @@ +--- a/ioctl.c ++++ b/ioctl.c +@@ -829,29 +829,37 @@ static inline void tfm_info_to_alg_info( + "%s", crypto_tfm_alg_driver_name(tfm)); + } + +-#ifndef CRYPTO_ALG_KERN_DRIVER_ONLY ++#if defined(QCANSS) || defined(QCA) || defined(MT7621) || defined(MT7622) || defined(LANTIQ) || defined(BCM675X) || defined(BCM49XX) || defined(MT798X) + static unsigned int is_known_accelerated(struct crypto_tfm *tfm) + { + const char *name = crypto_tfm_alg_driver_name(tfm); + + if (name == NULL) +- return 1; /* assume accelerated */ ++ return 0; + + /* look for known crypto engine names */ +- if (strstr(name, "-talitos") || +- !strncmp(name, "mv-", 3) || +- !strncmp(name, "atmel-", 6) || +- strstr(name, "geode") || +- strstr(name, "hifn") || +- strstr(name, "-ixp4xx") || +- strstr(name, "-omap") || +- strstr(name, "-picoxcell") || +- strstr(name, "-s5p") || +- strstr(name, "-ppc4xx") || +- strstr(name, "-caam") || +- strstr(name, "-n2")) ++#if defined(QCANSS) ++ if (!strncmp(name, "nss-", 4)) + return 1; +- ++#elif defined(QCA) ++ if (!strncmp(name, "qcrypto", 7)) ++ return 1; ++#elif defined(MT7621) ++ if (strstr(name, "eip93")) ++ return 1; ++#elif defined(MT7622) ++ if (strstr(name, "mtk")) ++ return 1; ++#elif defined(MT798X) ++ if (strstr(name, "safexcel-")) ++ return 1; ++#elif defined(LANTIQ) ++ if (strstr(name, "ltq-crypto")) ++ return 1; ++#elif defined(BCM675X) || defined(BCM49XX) ++ if (strstr(name, "-iproc")) ++ return 1; ++#endif + return 0; + } + #endif +@@ -876,22 +884,22 @@ static int get_session_info(struct fcryp + else + tfm = crypto_aead_tfm(ses_ptr->cdata.async.as); + tfm_info_to_alg_info(&siop->cipher_info, tfm); +-#ifdef CRYPTO_ALG_KERN_DRIVER_ONLY +- if (tfm->__crt_alg->cra_flags & CRYPTO_ALG_KERN_DRIVER_ONLY) ++#if defined(QCANSS) || defined(QCA) || defined(MT7621) || defined(MT7622) || defined(LANTIQ) || defined(BCM675X) || defined(BCM49XX) || defined(MT798X) ++ if (is_known_accelerated(tfm)) + siop->flags |= SIOP_FLAG_KERNEL_DRIVER_ONLY; + #else +- if (is_known_accelerated(tfm)) ++ if (tfm->__crt_alg->cra_flags & CRYPTO_ALG_KERN_DRIVER_ONLY) + siop->flags |= SIOP_FLAG_KERNEL_DRIVER_ONLY; + #endif + } + if (ses_ptr->hdata.init) { + tfm = crypto_ahash_tfm(ses_ptr->hdata.async.s); + tfm_info_to_alg_info(&siop->hash_info, tfm); +-#ifdef CRYPTO_ALG_KERN_DRIVER_ONLY +- if (tfm->__crt_alg->cra_flags & CRYPTO_ALG_KERN_DRIVER_ONLY) ++#if defined(QCANSS) || defined(QCA) || defined(MT7621) || defined(MT7622) || defined(LANTIQ) || defined(BCM675X) || defined(BCM49XX) || defined(MT798X) ++ if (is_known_accelerated(tfm)) + siop->flags |= SIOP_FLAG_KERNEL_DRIVER_ONLY; + #else +- if (is_known_accelerated(tfm)) ++ if (tfm->__crt_alg->cra_flags & CRYPTO_ALG_KERN_DRIVER_ONLY) + siop->flags |= SIOP_FLAG_KERNEL_DRIVER_ONLY; + #endif + } +--- a/main.c ++++ b/main.c +@@ -168,6 +168,12 @@ __crypto_run_zc(struct csession *ses_ptr + struct crypt_op *cop = &kcop->cop; + int ret = 0; + ++#if defined(QCANSS) ++//openssl bug!!! ++ if (unlikely(cop->src != cop->dst)) { ++ return __crypto_run_std(ses_ptr, cop); ++ } ++#endif + ret = get_userbuf(ses_ptr, cop->src, cop->len, cop->dst, cop->len, + kcop->task, kcop->mm, &src_sg, &dst_sg); + if (unlikely(ret)) { From 65f261c196df801329efa376c8971c3edbb2e5ef Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 25 Mar 2024 00:07:45 -0400 Subject: [PATCH 160/225] feeds: NSS: point to 6.x branch This will now be the default NSS branch, and will cover both kernel 6.1 and 6.6 related changes going forward. --- feeds.conf.default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feeds.conf.default b/feeds.conf.default index 4527c3215a827e..68c55d271c0819 100644 --- a/feeds.conf.default +++ b/feeds.conf.default @@ -2,7 +2,7 @@ src-git packages https://git.openwrt.org/feed/packages.git src-git luci https://git.openwrt.org/project/luci.git src-git routing https://git.openwrt.org/feed/routing.git src-git telephony https://git.openwrt.org/feed/telephony.git -src-git nss_packages https://github.com/qosmio/nss-packages.git;NSS-12.4-K6.1 +src-git nss_packages https://github.com/qosmio/nss-packages.git;NSS-12.4-K6.x src-git sqm_scripts_nss https://github.com/qosmio/sqm-scripts-nss.git #src-git video https://github.com/openwrt/video.git #src-git targets https://github.com/openwrt/targets.git From 56b6a67d0c8e0b517cef1a986aa4e216e7720bb2 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 25 Mar 2024 01:04:37 -0400 Subject: [PATCH 161/225] qualcommax: NSS: fix up 'nss_region' --- .../0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/linux/qualcommax/patches-6.6/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch b/target/linux/qualcommax/patches-6.6/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch index 7d43b602c76e7a..7f95b0110c9ec5 100644 --- a/target/linux/qualcommax/patches-6.6/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch +++ b/target/linux/qualcommax/patches-6.6/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch @@ -23,7 +23,7 @@ Signed-off-by: Robert Marko #size-cells = <2>; ranges; -+ nss_region@40000000 { ++ nss_region: nss@40000000 { + no-map; + reg = <0x0 0x40000000 0x0 0x01000000>; + }; From 9b7a684365a64cfb061f05aa2ee4bc3c7141be79 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 25 Mar 2024 13:11:14 -0400 Subject: [PATCH 162/225] qca-nss-dp: switch to follow upstream version. On qca-nss-dp version 12.4.5.r3 and higher, most of the changes are geared towards edma v2 vs. v1. In this case 'higher' isn't always better. Swich back to upstream's version to avoid merge conflicts. --- package/kernel/qca-nss-dp/Makefile | 8 ++++---- ...-a-phy-handle-property-to-connect-to-.patch | 18 ++++++++++-------- ...dp-allow-setting-netdev-name-from-DTS.patch | 2 +- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/package/kernel/qca-nss-dp/Makefile b/package/kernel/qca-nss-dp/Makefile index 8acdc918aaac56..f9e992f246af2f 100644 --- a/package/kernel/qca-nss-dp/Makefile +++ b/package/kernel/qca-nss-dp/Makefile @@ -1,13 +1,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=qca-nss-dp -PKG_RELEASE:=3 +PKG_RELEASE:=2 PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-dp.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2024-02-12 -PKG_SOURCE_VERSION:=bfdd78a8570dc14e1c91d312c5d775cecf49149c -PKG_MIRROR_HASH:=2a546657b6bdf810f7bf5bb94ac50fd1cfcb117fa17bb7aa84ce8119ed7d2be8 +PKG_SOURCE_DATE:=2023-06-06 +PKG_SOURCE_VERSION:=fa67464466f69f00967cc373d1bdd6025f57eb89 +PKG_MIRROR_HASH:=51bf524382a5cb542c2c80d12a91f87b9736de3ac3c1d4a351c97b3502d68574 PKG_BUILD_PARALLEL:=1 PKG_FLAGS:=nonshared diff --git a/package/kernel/qca-nss-dp/patches/0006-nss_dp_main-Use-a-phy-handle-property-to-connect-to-.patch b/package/kernel/qca-nss-dp/patches/0006-nss_dp_main-Use-a-phy-handle-property-to-connect-to-.patch index a82487a4a0375e..0432b82dda3f5c 100644 --- a/package/kernel/qca-nss-dp/patches/0006-nss_dp_main-Use-a-phy-handle-property-to-connect-to-.patch +++ b/package/kernel/qca-nss-dp/patches/0006-nss_dp_main-Use-a-phy-handle-property-to-connect-to-.patch @@ -26,7 +26,7 @@ Signed-off-by: Robert Marko --- a/include/nss_dp_dev.h +++ b/include/nss_dp_dev.h -@@ -228,13 +228,10 @@ struct nss_dp_dev { +@@ -202,13 +202,10 @@ struct nss_dp_dev { unsigned long drv_flags; /* Driver specific feature flags */ /* Phy related stuff */ @@ -43,7 +43,7 @@ Signed-off-by: Robert Marko --- a/nss_dp_main.c +++ b/nss_dp_main.c -@@ -717,7 +717,7 @@ static int nss_dp_open(struct net_device +@@ -418,7 +418,7 @@ static int nss_dp_open(struct net_device netif_start_queue(netdev); @@ -52,7 +52,7 @@ Signed-off-by: Robert Marko /* Notify data plane link is up */ if (dp_priv->data_plane_ops->link_state(dp_priv->dpc, 1)) { netdev_dbg(netdev, "Data plane set link failed\n"); -@@ -914,6 +914,12 @@ static int32_t nss_dp_of_get_pdata(struc +@@ -615,6 +615,12 @@ static int32_t nss_dp_of_get_pdata(struc return -EFAULT; } @@ -65,7 +65,7 @@ Signed-off-by: Robert Marko if (of_property_read_u32(np, "qcom,mactype", &hal_pdata->mactype)) { pr_err("%s: error reading mactype\n", np->name); return -EFAULT; -@@ -934,18 +940,6 @@ static int32_t nss_dp_of_get_pdata(struc +@@ -635,18 +641,6 @@ static int32_t nss_dp_of_get_pdata(struc return -EFAULT; #endif @@ -84,7 +84,7 @@ Signed-off-by: Robert Marko #if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)) maddr = (uint8_t *)of_get_mac_address(np); #if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 4, 0)) -@@ -1023,56 +1017,6 @@ static int32_t nss_dp_of_get_pdata(struc +@@ -695,56 +689,6 @@ static int32_t nss_dp_of_get_pdata(struc return 0; } @@ -141,7 +141,7 @@ Signed-off-by: Robert Marko #ifdef CONFIG_NET_SWITCHDEV /* * nss_dp_is_phy_dev() -@@ -1131,7 +1075,6 @@ static int32_t nss_dp_probe(struct platf +@@ -803,7 +747,6 @@ static int32_t nss_dp_probe(struct platf struct device_node *np = pdev->dev.of_node; struct nss_gmac_hal_platform_data gmac_hal_pdata; int32_t ret = 0; @@ -149,7 +149,7 @@ Signed-off-by: Robert Marko #if defined(NSS_DP_PPE_SUPPORT) uint32_t vsi_id; fal_port_t port_id; -@@ -1210,20 +1153,12 @@ static int32_t nss_dp_probe(struct platf +@@ -880,22 +823,14 @@ static int32_t nss_dp_probe(struct platf dp_priv->drv_flags |= NSS_DP_PRIV_FLAG(INIT_DONE); @@ -162,12 +162,14 @@ Signed-off-by: Robert Marko - snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, - dp_priv->miibus->id, dp_priv->phy_mdio_addr); - ++ if (dp_priv->phy_node) { + SET_NETDEV_DEV(netdev, &pdev->dev); + - dp_priv->phydev = phy_connect(netdev, phy_id, - &nss_dp_adjust_link, - dp_priv->phy_mii_type); - if (IS_ERR(dp_priv->phydev)) { - netdev_dbg(netdev, "failed to connect to phy device\n"); -+ if (dp_priv->phy_node) { + dp_priv->phydev = of_phy_connect(netdev, dp_priv->phy_node, + &nss_dp_adjust_link, 0, + dp_priv->phy_mii_type); diff --git a/package/kernel/qca-nss-dp/patches/0008-nss-dp-allow-setting-netdev-name-from-DTS.patch b/package/kernel/qca-nss-dp/patches/0008-nss-dp-allow-setting-netdev-name-from-DTS.patch index 3de94ebe531c26..e90bf32ced7707 100644 --- a/package/kernel/qca-nss-dp/patches/0008-nss-dp-allow-setting-netdev-name-from-DTS.patch +++ b/package/kernel/qca-nss-dp/patches/0008-nss-dp-allow-setting-netdev-name-from-DTS.patch @@ -15,7 +15,7 @@ Signed-off-by: Robert Marko --- a/nss_dp_main.c +++ b/nss_dp_main.c -@@ -1074,18 +1074,29 @@ static int32_t nss_dp_probe(struct platf +@@ -746,18 +746,29 @@ static int32_t nss_dp_probe(struct platf struct nss_dp_dev *dp_priv; struct device_node *np = pdev->dev.of_node; struct nss_gmac_hal_platform_data gmac_hal_pdata; From 04afe9e43e014b39d212d54d87ed7f43acf33e49 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 25 Mar 2024 13:18:22 -0400 Subject: [PATCH 163/225] qca-nss-dp: switch to follow upstream version. On qca-nss-dp version 12.4.5.r3 and higher, most of the changes are geared towards edma v2 vs. v1. In this case 'higher' isn't always better. Swich back to upstream's version to avoid merge conflicts. --- package/kernel/qca-nss-dp/Makefile | 8 ++++---- ...-a-phy-handle-property-to-connect-to-.patch | 18 ++++++++++-------- ...dp-allow-setting-netdev-name-from-DTS.patch | 2 +- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/package/kernel/qca-nss-dp/Makefile b/package/kernel/qca-nss-dp/Makefile index 8acdc918aaac56..f9e992f246af2f 100644 --- a/package/kernel/qca-nss-dp/Makefile +++ b/package/kernel/qca-nss-dp/Makefile @@ -1,13 +1,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=qca-nss-dp -PKG_RELEASE:=3 +PKG_RELEASE:=2 PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-dp.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2024-02-12 -PKG_SOURCE_VERSION:=bfdd78a8570dc14e1c91d312c5d775cecf49149c -PKG_MIRROR_HASH:=2a546657b6bdf810f7bf5bb94ac50fd1cfcb117fa17bb7aa84ce8119ed7d2be8 +PKG_SOURCE_DATE:=2023-06-06 +PKG_SOURCE_VERSION:=fa67464466f69f00967cc373d1bdd6025f57eb89 +PKG_MIRROR_HASH:=51bf524382a5cb542c2c80d12a91f87b9736de3ac3c1d4a351c97b3502d68574 PKG_BUILD_PARALLEL:=1 PKG_FLAGS:=nonshared diff --git a/package/kernel/qca-nss-dp/patches/0006-nss_dp_main-Use-a-phy-handle-property-to-connect-to-.patch b/package/kernel/qca-nss-dp/patches/0006-nss_dp_main-Use-a-phy-handle-property-to-connect-to-.patch index a82487a4a0375e..af65f7a24ed160 100644 --- a/package/kernel/qca-nss-dp/patches/0006-nss_dp_main-Use-a-phy-handle-property-to-connect-to-.patch +++ b/package/kernel/qca-nss-dp/patches/0006-nss_dp_main-Use-a-phy-handle-property-to-connect-to-.patch @@ -26,7 +26,7 @@ Signed-off-by: Robert Marko --- a/include/nss_dp_dev.h +++ b/include/nss_dp_dev.h -@@ -228,13 +228,10 @@ struct nss_dp_dev { +@@ -202,13 +202,10 @@ struct nss_dp_dev { unsigned long drv_flags; /* Driver specific feature flags */ /* Phy related stuff */ @@ -43,7 +43,7 @@ Signed-off-by: Robert Marko --- a/nss_dp_main.c +++ b/nss_dp_main.c -@@ -717,7 +717,7 @@ static int nss_dp_open(struct net_device +@@ -418,7 +418,7 @@ static int nss_dp_open(struct net_device netif_start_queue(netdev); @@ -52,7 +52,7 @@ Signed-off-by: Robert Marko /* Notify data plane link is up */ if (dp_priv->data_plane_ops->link_state(dp_priv->dpc, 1)) { netdev_dbg(netdev, "Data plane set link failed\n"); -@@ -914,6 +914,12 @@ static int32_t nss_dp_of_get_pdata(struc +@@ -615,6 +615,12 @@ static int32_t nss_dp_of_get_pdata(struc return -EFAULT; } @@ -65,7 +65,7 @@ Signed-off-by: Robert Marko if (of_property_read_u32(np, "qcom,mactype", &hal_pdata->mactype)) { pr_err("%s: error reading mactype\n", np->name); return -EFAULT; -@@ -934,18 +940,6 @@ static int32_t nss_dp_of_get_pdata(struc +@@ -635,18 +641,6 @@ static int32_t nss_dp_of_get_pdata(struc return -EFAULT; #endif @@ -84,7 +84,7 @@ Signed-off-by: Robert Marko #if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)) maddr = (uint8_t *)of_get_mac_address(np); #if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 4, 0)) -@@ -1023,56 +1017,6 @@ static int32_t nss_dp_of_get_pdata(struc +@@ -695,56 +689,6 @@ static int32_t nss_dp_of_get_pdata(struc return 0; } @@ -141,7 +141,7 @@ Signed-off-by: Robert Marko #ifdef CONFIG_NET_SWITCHDEV /* * nss_dp_is_phy_dev() -@@ -1131,7 +1075,6 @@ static int32_t nss_dp_probe(struct platf +@@ -803,7 +747,6 @@ static int32_t nss_dp_probe(struct platf struct device_node *np = pdev->dev.of_node; struct nss_gmac_hal_platform_data gmac_hal_pdata; int32_t ret = 0; @@ -149,7 +149,7 @@ Signed-off-by: Robert Marko #if defined(NSS_DP_PPE_SUPPORT) uint32_t vsi_id; fal_port_t port_id; -@@ -1210,20 +1153,12 @@ static int32_t nss_dp_probe(struct platf +@@ -880,22 +823,14 @@ static int32_t nss_dp_probe(struct platf dp_priv->drv_flags |= NSS_DP_PRIV_FLAG(INIT_DONE); @@ -162,12 +162,14 @@ Signed-off-by: Robert Marko - snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, - dp_priv->miibus->id, dp_priv->phy_mdio_addr); - ++ if (dp_priv->phy_node) { + SET_NETDEV_DEV(netdev, &pdev->dev); + - dp_priv->phydev = phy_connect(netdev, phy_id, - &nss_dp_adjust_link, - dp_priv->phy_mii_type); - if (IS_ERR(dp_priv->phydev)) { - netdev_dbg(netdev, "failed to connect to phy device\n"); -+ if (dp_priv->phy_node) { + dp_priv->phydev = of_phy_connect(netdev, dp_priv->phy_node, + &nss_dp_adjust_link, 0, + dp_priv->phy_mii_type); diff --git a/package/kernel/qca-nss-dp/patches/0008-nss-dp-allow-setting-netdev-name-from-DTS.patch b/package/kernel/qca-nss-dp/patches/0008-nss-dp-allow-setting-netdev-name-from-DTS.patch index 3de94ebe531c26..e90bf32ced7707 100644 --- a/package/kernel/qca-nss-dp/patches/0008-nss-dp-allow-setting-netdev-name-from-DTS.patch +++ b/package/kernel/qca-nss-dp/patches/0008-nss-dp-allow-setting-netdev-name-from-DTS.patch @@ -15,7 +15,7 @@ Signed-off-by: Robert Marko --- a/nss_dp_main.c +++ b/nss_dp_main.c -@@ -1074,18 +1074,29 @@ static int32_t nss_dp_probe(struct platf +@@ -746,18 +746,29 @@ static int32_t nss_dp_probe(struct platf struct nss_dp_dev *dp_priv; struct device_node *np = pdev->dev.of_node; struct nss_gmac_hal_platform_data gmac_hal_pdata; From cc36b9ddd5884a80f11b2b8b223b6c54f8df1c2e Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 25 Mar 2024 13:30:17 -0400 Subject: [PATCH 164/225] firewall4: make fullconenat-nft optional depends --- package/network/config/firewall4/Makefile | 8 +-- .../001-firewall4-Add-fullcone-support.patch | 54 +++++++++---------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/package/network/config/firewall4/Makefile b/package/network/config/firewall4/Makefile index f2b565d5dea793..793aef35e7b71f 100644 --- a/package/network/config/firewall4/Makefile +++ b/package/network/config/firewall4/Makefile @@ -23,9 +23,9 @@ define Package/firewall4 TITLE:=OpenWrt 4th gen firewall DEPENDS:= \ +kmod-nft-core +kmod-nft-fib +kmod-nft-offload \ - +kmod-nft-nat +kmod-nft-fullcone \ - +nftables-json \ - +ucode +ucode-mod-fs +ucode-mod-ubus +ucode-mod-uci + +kmod-nft-nat +nftables-json \ + +ucode +ucode-mod-fs +ucode-mod-ubus +ucode-mod-uci \ + +PACKAGE_kmod-nft-fullcone:kmod-nft-fullcone EXTRA_DEPENDS:=ucode (>=2022.03.22) PROVIDES:=uci-firewall endef @@ -47,4 +47,4 @@ endef define Build/Compile endef -$(eval $(call BuildPackage,firewall4)) \ No newline at end of file +$(eval $(call BuildPackage,firewall4)) diff --git a/package/network/config/firewall4/patches/001-firewall4-Add-fullcone-support.patch b/package/network/config/firewall4/patches/001-firewall4-Add-fullcone-support.patch index 3ed2caef00390f..46ae728786df1b 100644 --- a/package/network/config/firewall4/patches/001-firewall4-Add-fullcone-support.patch +++ b/package/network/config/firewall4/patches/001-firewall4-Add-fullcone-support.patch @@ -26,17 +26,17 @@ Renew: ZiMing Mo option forward REJECT # Uncomment this line to disable ipv6 rules # option disable_ipv6 1 -+ option flow_offloading 1 -+ option fullcone 1 ++ option flow_offloading 0 ++ option fullcone 0 + option fullcone6 0 - + config zone option name lan --- a/root/usr/share/firewall4/templates/ruleset.uc +++ b/root/usr/share/firewall4/templates/ruleset.uc -@@ -316,6 +316,12 @@ table inet fw4 { +@@ -327,6 +327,12 @@ table inet fw4 { {% for (let redirect in fw4.redirects(`dstnat_${zone.name}`)): %} - {%+ include("redirect.uc", { fw4, redirect }) %} + {%+ include("redirect.uc", { fw4, zone, redirect }) %} {% endfor %} +{% if (zone.masq && fw4.default_option("fullcone")): %} + {%+ include("zone-fullcone.uc", { fw4, zone, family: 4, direction: "dstnat" }) %} @@ -46,10 +46,10 @@ Renew: ZiMing Mo +{% endif %} {% fw4.includes('chain-append', `dstnat_${zone.name}`) %} } - -@@ -326,20 +326,26 @@ table inet fw4 { + +@@ -337,20 +343,26 @@ table inet fw4 { {% for (let redirect in fw4.redirects(`srcnat_${zone.name}`)): %} - {%+ include("redirect.uc", { fw4, redirect }) %} + {%+ include("redirect.uc", { fw4, zone, redirect }) %} {% endfor %} -{% if (zone.masq): %} +{% if (zone.masq && !fw4.default_option("fullcone")): %} @@ -75,7 +75,7 @@ Renew: ZiMing Mo +{% endif %} {% fw4.includes('chain-append', `srcnat_${zone.name}`) %} } - + --- /dev/null +++ b/root/usr/share/firewall4/templates/zone-fullcone.uc @@ -0,0 +1,4 @@ @@ -91,10 +91,10 @@ Renew: ZiMing Mo const fs = require("fs"); const uci = require("uci"); const ubus = require("ubus"); -@@ -428,6 +430,25 @@ function nft_try_hw_offload(devices) { +@@ -489,6 +491,25 @@ function nft_try_hw_offload(devices) { return (rc == 0); } - + +function nft_try_fullcone() { + let nft_test = + 'add table inet fw4-fullcone-test; ' + @@ -114,13 +114,13 @@ Renew: ZiMing Mo + return ok; +} + - + return { read_kernel_version: function() { -@@ -778,6 +799,18 @@ return { +@@ -832,6 +853,18 @@ return { warn(`[!] ${msg}\n`); }, - + + myinfo: function(fmt, ...args) { + if (getenv("QUIET")) + return; @@ -136,10 +136,10 @@ Renew: ZiMing Mo get: function(sid, opt) { return this.cursor.get("firewall", sid, opt); }, -@@ -959,6 +992,21 @@ return { +@@ -1013,6 +1046,21 @@ return { } }, - + + myinfo_section: function(s, msg) { + if (s[".name"]) { + if (s.name) @@ -158,7 +158,7 @@ Renew: ZiMing Mo parse_policy: function(val) { return this.parse_enum(val, [ "accept", -@@ -1398,6 +1446,7 @@ return { +@@ -1452,6 +1500,7 @@ return { "dnat", "snat", "masquerade", @@ -166,19 +166,19 @@ Renew: ZiMing Mo "accept", "reject", "drop" -@@ -1865,6 +1914,8 @@ return { +@@ -1923,6 +1972,8 @@ return { } - + let defs = this.parse_options(data, { + fullcone: [ "bool", "0" ], + fullcone6: [ "bool", "0" ], input: [ "policy", "drop" ], output: [ "policy", "drop" ], forward: [ "policy", "drop" ], -@@ -1899,6 +1950,11 @@ return { - +@@ -1957,6 +2008,11 @@ return { + delete defs.syn_flood; - + + if (!nft_try_fullcone()) { + delete defs.fullcone; + warn("nft_try_fullcone failed, disable fullcone globally\n"); @@ -186,11 +186,11 @@ Renew: ZiMing Mo + this.state.defaults = defs; }, - -@@ -2124,10 +2180,23 @@ return { + +@@ -2182,10 +2238,23 @@ return { zone.related_subnets = related_subnets; zone.related_physdevs = related_physdevs; - + - if (zone.masq || zone.masq6) + if (zone.masq) { zone.dflags.snat = true; @@ -207,9 +207,9 @@ Renew: ZiMing Mo + this.myinfo_section(data, "IPv6 fullcone enabled for zone '" + zone.name + "'"); + } + } - + - if ((zone.auto_helper && !(zone.masq || zone.masq6)) || length(zone.helper)) { + if ((zone.auto_helper && !(zone.masq || zone.masq6 || this.state.defaults.fullcone || this.state.defaults.fullcone6)) || length(zone.helper)) { zone.dflags.helper = true; - + for (let helper in (length(zone.helper) ? zone.helper : this.state.helpers)) { From c4c057f7303646cfa88a53e8ebe9d8114c3b3ace Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 25 Mar 2024 13:31:04 -0400 Subject: [PATCH 165/225] ath11k_nss: refresh patches --- ...th11k-fix-for-peer-memory-corruption.patch | 4 +-- ...-adding-support-for-mgmt-frame-stats.patch | 6 ++-- ...91-ath11k-add-mgmt-and-data-ack-rssi.patch | 2 +- ...-ath11k_nss-add-nss-driver-interface.patch | 2 +- .../199-003-ath11k-add-nss-support.patch | 28 +++++++-------- ...-ath11k-Add-support-for-dynamic-vlan.patch | 2 +- ...14-ath11k-qos-null-frame-tx-over-wmi.patch | 8 ++--- ...pport-for-WDS-offload-in-NSS-offload.patch | 28 +++++++-------- ...-dynamic-VLAN-support-in-NSS-offload.patch | 36 +++++++++---------- ...ow-fast-rx-by-bypassing-stats-update.patch | 2 +- .../nss/ath11k/244-ath11k-dp-tx-perf.patch | 4 +-- .../patches/nss/ath11k/270-iphone-issue.patch | 2 +- .../300-ath11k-nss-mesh-offload-support.patch | 8 ++--- ...lookup-failure-in-mgmt-tx-completion.patch | 2 +- ...30-ath11k-sync-wds_ast_entry-updates.patch | 4 +-- ...TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch | 2 +- ...rt-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch | 2 +- ...-fix-clear-peer-keys-during-disassoc.patch | 4 +-- ...ix-mutex-dead-lock-and-q6-dump-crash.patch | 4 +-- ...agement-frames-to-firmware-before-wa.patch | 7 +--- ...th11k-Advertise-TX_QUEUE-mac-hw-flag.patch | 2 +- ...oid-memset-of-ppdu-info-for-next-skb.patch | 6 ++-- ...a_map_single-to-virt_to_phys-in-rx-r.patch | 4 +-- ...11k-remove-invalid-peer-create-logic.patch | 4 +-- ...th11k-rename-ath11k_start_vdev_delay.patch | 6 ++-- ...ation-of-ath11k_mac_start_vdev_delay.patch | 8 ++--- ...ailure-due-to-unexpected-peer-delete.patch | 16 ++++----- ...k-make-debugfs-sta-htt-stats-modular.patch | 6 ++-- ...11k-Disable-rx_header-tlv-for-2K-SKB.patch | 36 +++++++++---------- ...d-ampdu-id-in-802.11-radiotap-header.patch | 6 ++-- ...999-336-0001-ath11k-idr-optimization.patch | 10 +++--- .../999-336-0002-ath11k-Use-idr_replace.patch | 22 ++++++------ ...k-skb_headroom-before-using-skb_push.patch | 24 ++++++------- ...-when-using-encapsulation-offloading.patch | 2 +- .../199-001-mac80211-add-nss-support.patch | 26 +++++++------- ...t-callback-when-hwencap-enable-in-st.patch | 2 +- ...03-mac80211-ath11k-fw-dynamic-muedca.patch | 4 +-- ...-ath11k-Add-support-for-dynamic-vlan.patch | 4 +-- ...07-mac80211-add-nss-redirect-support.patch | 6 ++-- ...N-iftype-support-on-NSS-offload-case.patch | 6 ++-- ...-dynamic-VLAN-support-on-NSS-offload.patch | 6 ++-- .../nss/subsys/245-compilation_fix.patch | 10 +++--- .../300-ath11k-nss-mesh-offload-support.patch | 30 ++++++++-------- ...TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch | 4 +-- ...-0005-mac80211-simple-tx-for-AP-mode.patch | 4 +-- ...mac80211-fix-unconditional-sta-usage.patch | 4 +-- ...unused-RX_FLAGS-from-mac80211_rx_fla.patch | 4 +-- ...ncapsulation-of-EAPOL-frames-if-OFFL.patch | 24 ++++++------- ...fix-RCU-stall-in-mesh-fast-xmit-path.patch | 2 +- ...id-last_rate-for-rx_bitrate-from-cpu.patch | 12 +++---- ...se-HW-checksum-offload-only-for-ethm.patch | 4 +-- ...1-Add-mac-hw-flag-to-avoid-queue-skb.patch | 24 ++++++------- 52 files changed, 240 insertions(+), 245 deletions(-) diff --git a/package/kernel/mac80211/patches/nss/ath11k/033-ath11k-fix-for-peer-memory-corruption.patch b/package/kernel/mac80211/patches/nss/ath11k/033-ath11k-fix-for-peer-memory-corruption.patch index 5c9c723913b09a..3808a7697abfed 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/033-ath11k-fix-for-peer-memory-corruption.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/033-ath11k-fix-for-peer-memory-corruption.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -4178,22 +4178,28 @@ static int ath11k_clear_peer_keys(struct +@@ -4180,22 +4180,28 @@ static int ath11k_clear_peer_keys(struct int ret; int i; u32 flags = 0; @@ -35,7 +35,7 @@ DISABLE_KEY, addr, flags); if (ret < 0 && first_errno == 0) first_errno = ret; -@@ -4201,10 +4207,6 @@ static int ath11k_clear_peer_keys(struct +@@ -4203,10 +4209,6 @@ static int ath11k_clear_peer_keys(struct if (ret < 0) ath11k_warn(ab, "failed to remove peer key %d: %d\n", i, ret); diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index c069cc8ff9f58a..c3999d489a15ba 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -128,7 +128,7 @@ debugfs_create_file("dfs_simulate_radar", 0200, --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6148,9 +6148,9 @@ static int ath11k_mac_mgmt_tx(struct ath +@@ -6150,9 +6150,9 @@ static int ath11k_mac_mgmt_tx(struct ath */ if (is_prb_rsp && atomic_read(&ar->num_pending_mgmt_tx) > ATH11K_PRB_RSP_DROP_THRESHOLD) { @@ -140,7 +140,7 @@ } if (skb_queue_len_lockless(q) >= ATH11K_TX_MGMT_NUM_PENDING_MAX) { -@@ -6176,9 +6176,11 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6178,9 +6178,11 @@ static void ath11k_mac_op_tx(struct ieee struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_key_conf *key = info->control.hw_key; @@ -152,7 +152,7 @@ int ret; memset(skb_cb, 0, sizeof(*skb_cb)); -@@ -6192,12 +6194,21 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6194,12 +6196,21 @@ static void ath11k_mac_op_tx(struct ieee if (info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { skb_cb->flags |= ATH11K_SKB_HW_80211_ENCAP; } else if (ieee80211_is_mgmt(hdr->frame_control)) { diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 22cdb4dccb4d5d..7c8f0c952bd983 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -9579,6 +9579,8 @@ static int __ath11k_mac_register(struct +@@ -9573,6 +9573,8 @@ static int __ath11k_mac_register(struct wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 851e4ed0225a95..a7d861324fcc4c 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -2995,7 +2995,7 @@ Signed-off-by: Sriram R int ath11k_dp_pdev_reo_setup(struct ath11k_base *ab); --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6367,6 +6367,16 @@ static int ath11k_mac_op_start(struct ie +@@ -6369,6 +6369,16 @@ static int ath11k_mac_op_start(struct ie goto err; } diff --git a/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch b/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch index 2234cb6bc4cc1d..7eb5fa8d3c4b6d 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch @@ -585,7 +585,7 @@ Signed-off-by: Sriram R static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, -@@ -4295,6 +4339,26 @@ static int ath11k_mac_op_set_key(struct +@@ -4297,6 +4341,26 @@ static int ath11k_mac_op_set_key(struct spin_lock_bh(&ab->base_lock); peer = ath11k_peer_find(ab, arvif->vdev_id, peer_addr); @@ -612,7 +612,7 @@ Signed-off-by: Sriram R if (peer && cmd == SET_KEY) { peer->keys[key->keyidx] = key; if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { -@@ -4333,9 +4397,8 @@ static int ath11k_mac_op_set_key(struct +@@ -4335,9 +4399,8 @@ static int ath11k_mac_op_set_key(struct break; } } @@ -623,7 +623,7 @@ Signed-off-by: Sriram R exit: mutex_unlock(&ar->conf_mutex); return ret; -@@ -6216,10 +6279,14 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6218,10 +6281,14 @@ static void ath11k_mac_op_tx(struct ieee if (control->sta) arsta = ath11k_sta_to_arsta(control->sta); @@ -639,7 +639,7 @@ Signed-off-by: Sriram R } } -@@ -6241,6 +6308,8 @@ static int ath11k_mac_config_mon_status_ +@@ -6243,6 +6310,8 @@ static int ath11k_mac_config_mon_status_ if (enable) { tlv_filter = ath11k_mac_mon_status_filter_default; @@ -648,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 +6608,7 @@ static int ath11k_mac_setup_vdev_create_ +@@ -6541,7 +6610,7 @@ static int ath11k_mac_setup_vdev_create_ return 0; } @@ -657,7 +657,7 @@ Signed-off-by: Sriram R struct ieee80211_vif *vif) { struct ath11k *ar = hw->priv; -@@ -6585,6 +6654,8 @@ static void ath11k_mac_op_update_vif_off +@@ -6587,6 +6656,8 @@ static void ath11k_mac_op_update_vif_off arvif->vdev_id, ret); vif->offload_flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED; } @@ -666,7 +666,7 @@ Signed-off-by: Sriram R } static bool ath11k_mac_vif_ap_active_any(struct ath11k_base *ab) -@@ -6715,6 +6786,8 @@ static int ath11k_mac_vdev_delete(struct +@@ -6717,6 +6788,8 @@ static int ath11k_mac_vdev_delete(struct reinit_completion(&ar->vdev_delete_done); @@ -675,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 +6928,34 @@ static int ath11k_mac_op_add_interface(s +@@ -6857,7 +6930,34 @@ static int ath11k_mac_op_add_interface(s list_add(&arvif->list, &ar->arvifs); spin_unlock_bh(&ar->data_lock); @@ -711,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 +7079,7 @@ err_peer_del: +@@ -6981,6 +7081,7 @@ err_peer_del: } err_vdev_del: @@ -719,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 +7590,10 @@ ath11k_mac_update_vif_chan(struct ath11k +@@ -7491,6 +7592,10 @@ ath11k_mac_update_vif_chan(struct ath11k arvif->vdev_id, ret); continue; } @@ -730,7 +730,7 @@ Signed-off-by: Sriram R } /* Restart the internal monitor vdev on new channel */ -@@ -8717,6 +8822,8 @@ static void ath11k_mac_op_sta_statistics +@@ -8719,6 +8824,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); @@ -739,7 +739,7 @@ Signed-off-by: Sriram R } #if IS_ENABLED(CONFIG_IPV6) -@@ -9144,6 +9251,7 @@ static const struct ieee80211_ops ath11k +@@ -9138,6 +9245,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, @@ -747,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, -@@ -9529,7 +9637,8 @@ static int __ath11k_mac_register(struct +@@ -9523,7 +9631,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); @@ -757,7 +757,7 @@ Signed-off-by: Sriram R } ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; -@@ -9644,6 +9753,9 @@ static int __ath11k_mac_register(struct +@@ -9638,6 +9747,9 @@ static int __ath11k_mac_register(struct ab->hw_params.bios_sar_capa) ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa; diff --git a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Add-support-for-dynamic-vlan.patch b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Add-support-for-dynamic-vlan.patch index 54a6d1528422db..31bdadb469d5a4 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Add-support-for-dynamic-vlan.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Add-support-for-dynamic-vlan.patch @@ -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 -@@ -9770,6 +9770,9 @@ static int __ath11k_mac_register(struct +@@ -9764,6 +9764,9 @@ static int __ath11k_mac_register(struct */ ar->hw->wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MONITOR); diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 5f31f4ded2358c..e87482e82d834b 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -22,7 +22,7 @@ Signed-off-by: Sowmiya Sree Elavalagan --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6129,6 +6129,16 @@ static int ath11k_mac_mgmt_tx_wmi(struct +@@ -6131,6 +6131,16 @@ static int ath11k_mac_mgmt_tx_wmi(struct ATH11K_SKB_CB(skb)->paddr = paddr; @@ -39,7 +39,7 @@ Signed-off-by: Sowmiya Sree Elavalagan ret = ath11k_wmi_mgmt_send(ar, arvif->vdev_id, buf_id, skb); if (ret) { ath11k_warn(ar->ab, "failed to send mgmt frame: %d\n", ret); -@@ -6196,8 +6206,8 @@ static void ath11k_mgmt_over_wmi_tx_work +@@ -6198,8 +6208,8 @@ static void ath11k_mgmt_over_wmi_tx_work } } @@ -50,7 +50,7 @@ Signed-off-by: Sowmiya Sree Elavalagan { struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue; -@@ -6259,7 +6269,7 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6261,7 +6271,7 @@ static void ath11k_mac_op_tx(struct ieee } else if (ieee80211_is_mgmt(hdr->frame_control)) { frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, hdr->frame_control); is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control); @@ -59,7 +59,7 @@ Signed-off-by: Sowmiya Sree Elavalagan if (ret) { if (ret != -EBUSY) ath11k_warn(ar->ab, "failed to queue management frame %d\n", -@@ -6274,6 +6284,20 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6276,6 +6286,20 @@ static void ath11k_mac_op_tx(struct ieee spin_unlock_bh(&ar->data_lock); } return; diff --git a/package/kernel/mac80211/patches/nss/ath11k/235-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 index 729ee80199b9a2..5143d88a79bde8 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/235-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 @@ -43,7 +43,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 -@@ -4744,6 +4744,11 @@ static void ath11k_sta_rc_update_wk(stru +@@ -4741,6 +4741,11 @@ static void ath11k_sta_rc_update_wk(stru arvif = arsta->arvif; ar = arvif->ar; @@ -55,7 +55,7 @@ Signed-off-by: Sathishkumar Muruganandam if (WARN_ON(ath11k_mac_vif_chan(arvif->vif, &def))) return; -@@ -4915,17 +4920,28 @@ err_rc_bw_changed: +@@ -4912,17 +4917,28 @@ err_rc_bw_changed: static void ath11k_sta_set_4addr_wk(struct work_struct *wk) { struct ath11k *ar; @@ -86,7 +86,7 @@ Signed-off-by: Sathishkumar Muruganandam "setting USE_4ADDR for peer %pM\n", sta->addr); ret = ath11k_wmi_set_peer_param(ar, sta->addr, -@@ -4933,8 +4949,93 @@ static void ath11k_sta_set_4addr_wk(stru +@@ -4930,8 +4946,93 @@ static void ath11k_sta_set_4addr_wk(stru WMI_PEER_USE_4ADDR, 1); if (ret) @@ -181,7 +181,7 @@ Signed-off-by: Sathishkumar Muruganandam } static int ath11k_mac_inc_num_stations(struct ath11k_vif *arvif, -@@ -5264,9 +5365,32 @@ static void ath11k_mac_op_sta_set_4addr( +@@ -5261,9 +5362,32 @@ static void ath11k_mac_op_sta_set_4addr( struct ieee80211_sta *sta, bool enabled) { struct ath11k *ar = hw->priv; @@ -214,7 +214,7 @@ Signed-off-by: Sathishkumar Muruganandam ieee80211_queue_work(ar->hw, &arsta->set_4addr_wk); arsta->use_4addr_set = true; } -@@ -6646,6 +6770,9 @@ static int ath11k_mac_op_update_vif_offl +@@ -6643,6 +6767,9 @@ static int ath11k_mac_op_update_vif_offl u32 param_id, param_value; int ret; @@ -224,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 && -@@ -6866,7 +6993,8 @@ static int ath11k_mac_op_add_interface(s +@@ -6863,7 +6990,8 @@ static int ath11k_mac_op_add_interface(s goto err; } @@ -234,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; -@@ -6886,6 +7014,28 @@ static int ath11k_mac_op_add_interface(s +@@ -6883,6 +7011,28 @@ static int ath11k_mac_op_add_interface(s arvif->vif = vif; INIT_LIST_HEAD(&arvif->list); @@ -263,7 +263,7 @@ Signed-off-by: Sathishkumar Muruganandam INIT_DELAYED_WORK(&arvif->connection_loss_work, ath11k_mac_vif_sta_connection_loss_work); -@@ -6915,6 +7065,7 @@ static int ath11k_mac_op_add_interface(s +@@ -6912,6 +7062,7 @@ static int ath11k_mac_op_add_interface(s fallthrough; case NL80211_IFTYPE_AP: arvif->vdev_type = WMI_VDEV_TYPE_AP; @@ -271,7 +271,7 @@ Signed-off-by: Sathishkumar Muruganandam break; case NL80211_IFTYPE_MONITOR: arvif->vdev_type = WMI_VDEV_TYPE_MONITOR; -@@ -7137,13 +7288,30 @@ static void ath11k_mac_op_remove_interfa +@@ -7134,13 +7285,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; @@ -304,7 +304,7 @@ Signed-off-by: Sathishkumar Muruganandam ath11k_dbg(ab, ATH11K_DBG_MAC, "remove interface (vdev %d)\n", arvif->vdev_id); -@@ -7160,6 +7328,14 @@ static void ath11k_mac_op_remove_interfa +@@ -7157,6 +7325,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); @@ -319,7 +319,7 @@ Signed-off-by: Sathishkumar Muruganandam } ret = ath11k_mac_vdev_delete(ar, arvif); -@@ -7203,8 +7379,7 @@ err_vdev_del: +@@ -7200,8 +7376,7 @@ err_vdev_del: ath11k_debugfs_remove_interface(arvif); @@ -329,7 +329,7 @@ Signed-off-by: Sathishkumar Muruganandam mutex_unlock(&ar->conf_mutex); } -@@ -7264,16 +7439,17 @@ static int ath11k_mac_op_ampdu_action(st +@@ -7261,16 +7436,17 @@ static int ath11k_mac_op_ampdu_action(st struct ieee80211_ampdu_params *params) { struct ath11k *ar = hw->priv; @@ -349,7 +349,7 @@ Signed-off-by: Sathishkumar Muruganandam break; case IEEE80211_AMPDU_TX_START: case IEEE80211_AMPDU_TX_STOP_CONT: -@@ -8796,6 +8972,7 @@ static void ath11k_mac_op_sta_statistics +@@ -8793,6 +8969,7 @@ static void ath11k_mac_op_sta_statistics { struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); struct ath11k *ar = arsta->arvif->ar; @@ -357,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); -@@ -8852,7 +9029,8 @@ static void ath11k_mac_op_sta_statistics +@@ -8849,7 +9026,8 @@ static void ath11k_mac_op_sta_statistics ATH11K_DEFAULT_NOISE_FLOOR; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); diff --git a/package/kernel/mac80211/patches/nss/ath11k/236-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 index 80b8a5fc67d7ea..a38abce7f11727 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/236-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 @@ -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 -@@ -351,6 +351,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; -@@ -723,6 +727,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; -@@ -4172,6 +4203,9 @@ static int ath11k_install_key(struct ath +@@ -4169,6 +4200,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; -@@ -4261,15 +4295,40 @@ static int ath11k_clear_peer_keys(struct +@@ -4258,15 +4292,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; -@@ -4287,17 +4346,38 @@ static int ath11k_mac_op_set_key(struct +@@ -4284,17 +4343,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. */ -@@ -4342,6 +4422,74 @@ static int ath11k_mac_op_set_key(struct +@@ -4339,6 +4419,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); -@@ -4364,6 +4512,27 @@ static int ath11k_mac_op_set_key(struct +@@ -4361,6 +4509,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) { -@@ -4373,18 +4542,23 @@ static int ath11k_mac_op_set_key(struct +@@ -4370,18 +4539,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); } @@ -354,7 +354,7 @@ Signed-off-by: Sathishkumar Muruganandam switch (key->cipher) { case WLAN_CIPHER_SUITE_TKIP: -@@ -5191,6 +5365,33 @@ static u32 ath11k_mac_ieee80211_sta_bw_t +@@ -5188,6 +5362,33 @@ static u32 ath11k_mac_ieee80211_sta_bw_t return bw; } @@ -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, -@@ -5300,6 +5501,34 @@ static int ath11k_mac_op_sta_state(struc +@@ -5297,6 +5498,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) { -@@ -7018,7 +7247,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7015,7 +7244,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; -@@ -7031,6 +7260,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7028,6 +7257,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; } -@@ -7055,6 +7285,20 @@ static int ath11k_mac_op_add_interface(s +@@ -7052,6 +7282,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: -@@ -7095,7 +7339,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7092,7 +7336,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++; -@@ -7254,7 +7498,7 @@ err_peer_del: +@@ -7251,7 +7495,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 } } -@@ -7265,6 +7509,8 @@ err_vdev_del: +@@ -7262,6 +7506,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); -@@ -7362,6 +7608,7 @@ err_vdev_del: +@@ -7359,6 +7605,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, -@@ -9960,8 +10207,11 @@ static int __ath11k_mac_register(struct +@@ -9949,8 +10196,11 @@ static int __ath11k_mac_register(struct ab->hw_params.bios_sar_capa) ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa; diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 61077309338ffb..9887f1ee840445 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -328,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 -@@ -5532,6 +5532,14 @@ static int ath11k_mac_op_sta_state(struc +@@ -5529,6 +5529,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/nss/ath11k/244-ath11k-dp-tx-perf.patch b/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch index 1c9a6ebd1d41ac..4da3f85c06f153 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch @@ -430,7 +430,7 @@ Signed-off-by: P Praneesh --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6669,12 +6669,22 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6666,12 +6666,22 @@ static void ath11k_mac_op_tx(struct ieee if (control->sta) arsta = ath11k_sta_to_arsta(control->sta); @@ -454,7 +454,7 @@ Signed-off-by: P Praneesh ieee80211_free_txskb(ar->hw, skb); return; } -@@ -7622,7 +7632,7 @@ err_vdev_del: +@@ -7619,7 +7629,7 @@ err_vdev_del: idr_for_each(&ar->txmgmt_idr, ath11k_mac_vif_txmgmt_idr_remove, vif); diff --git a/package/kernel/mac80211/patches/nss/ath11k/270-iphone-issue.patch b/package/kernel/mac80211/patches/nss/ath11k/270-iphone-issue.patch index 4260d0e5337451..92006908820793 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/270-iphone-issue.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/270-iphone-issue.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6267,6 +6267,8 @@ static int ath11k_mac_copy_he_cap(struct +@@ -6264,6 +6264,8 @@ static int ath11k_mac_copy_he_cap(struct memcpy(he_cap_elem->phy_cap_info, band_cap->he_cap_phy_info, sizeof(he_cap_elem->phy_cap_info)); 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 index b31809f689548b..611e98a2c2440f 100644 --- 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 @@ -1238,7 +1238,7 @@ Signed-off-by: Vasanthakumar Thiagarajan --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -3474,6 +3474,18 @@ static void ath11k_mac_op_nss_bss_info_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); } @@ -1257,7 +1257,7 @@ Signed-off-by: Vasanthakumar Thiagarajan mutex_unlock(&ar->conf_mutex); } -@@ -9714,6 +9726,28 @@ err_fallback: +@@ -9703,6 +9715,28 @@ err_fallback: return 0; } @@ -1286,7 +1286,7 @@ Signed-off-by: Vasanthakumar Thiagarajan static const struct ieee80211_ops ath11k_ops = { .tx = ath11k_mac_op_tx, .wake_tx_queue = ieee80211_handle_wake_tx_queue, -@@ -9771,6 +9805,9 @@ static const struct ieee80211_ops ath11k +@@ -9760,6 +9794,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, @@ -1296,7 +1296,7 @@ Signed-off-by: Vasanthakumar Thiagarajan }; static void ath11k_mac_update_ch_list(struct ath11k *ar, -@@ -10231,6 +10268,8 @@ static int __ath11k_mac_register(struct +@@ -10220,6 +10257,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); 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 index cb4fba0a2ffdcd..6ece606a4406eb 100644 --- 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 @@ -23,7 +23,7 @@ Signed-off-by: Rameshkumar Sundaram --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -7643,8 +7643,10 @@ err_vdev_del: +@@ -7640,8 +7640,10 @@ err_vdev_del: kfree(arvif->vlan_keyid_map); ath11k_peer_cleanup(ar, arvif->vdev_id); diff --git a/package/kernel/mac80211/patches/nss/ath11k/330-ath11k-sync-wds_ast_entry-updates.patch b/package/kernel/mac80211/patches/nss/ath11k/330-ath11k-sync-wds_ast_entry-updates.patch index 361c9064148acd..01ccc6003fc0cf 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -2212,6 +2212,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); -@@ -2225,6 +2226,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); diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 3c3e436c75ce41..1d8fa21443741e 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -58,7 +58,7 @@ Signed-off-by: Venkateswara Naralasetty 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 -@@ -10154,6 +10154,8 @@ static int __ath11k_mac_register(struct +@@ -10143,6 +10143,8 @@ static int __ath11k_mac_register(struct ieee80211_hw_set(ar->hw, USES_RSS); } diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index dbd8dd904c022d..9a3c95a9df3c40 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -1838,6 +1838,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/nss/ath11k/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 index 15a8afde61ef4f..ee60da053c3d5a 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -4899,12 +4899,6 @@ static int ath11k_station_disassoc(struc +@@ -4896,12 +4896,6 @@ static int ath11k_station_disassoc(struc return ret; } @@ -30,7 +30,7 @@ Signed-off-by: Karthikeyan Kathirvel return 0; } -@@ -5495,6 +5489,17 @@ static int ath11k_mac_op_sta_state(struc +@@ -5492,6 +5486,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/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 index 1f66f72a4a4851..d3f941b47a4164 100644 --- 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 @@ -36,7 +36,7 @@ Signed-off-by: Rajat Soni --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -8001,7 +8001,9 @@ static int ath11k_mac_op_start(struct ie +@@ -6788,7 +6788,9 @@ static int ath11k_mac_op_start(struct ie break; case ATH11K_STATE_RESTARTING: ar->state = ATH11K_STATE_RESTARTED; @@ -48,7 +48,7 @@ Signed-off-by: Rajat Soni case ATH11K_STATE_WEDGED: --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c -@@ -2960,6 +2960,8 @@ static int ath11k_qmi_assign_target_mem_ +@@ -2061,6 +2061,8 @@ static int ath11k_qmi_assign_target_mem_ if (!ab->qmi.target_mem[idx].iaddr) return -EIO; 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 index 7d413afec97b3d..3d13948b148ac2 100644 --- 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 @@ -25,11 +25,9 @@ Signed-off-by: Hari Chandrakanthan drivers/net/wireless/ath/ath11k/mac.c | 2 ++ 1 file changed, 2 insertions(+) -diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c -index 28c9908ef816..dbdb7aa5c498 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -10266,6 +10266,8 @@ static int ath11k_mac_flush_tx_complete(struct ath11k *ar) +@@ -8466,6 +8466,8 @@ static int ath11k_mac_flush_tx_complete( ret = -ETIMEDOUT; } @@ -38,6 +36,3 @@ index 28c9908ef816..dbdb7aa5c498 100644 time_left = wait_event_timeout(ar->txmgmt_empty_waitq, (atomic_read(&ar->num_pending_mgmt_tx) == 0), ATH11K_FLUSH_TIMEOUT); --- -2.7.4 - 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 index 510fbc2448cee7..533ddcad48214d 100644 --- 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 @@ -13,7 +13,7 @@ Signed-off-by: Yuvasree Sivasankaran --- 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 +@@ -10134,6 +10134,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); diff --git a/package/kernel/mac80211/patches/nss/ath11k/457-wifi-ath11k-Avoid-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 index c23b6cb3c858b4..21a92296da38a1 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/457-wifi-ath11k-Avoid-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 -@@ -6090,7 +6090,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))) { -@@ -6108,7 +6110,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,7 +67,7 @@ Signed-off-by: Yuvasree Sivasankaran ppdu_info->peer_id = HAL_INVALID_PEERID; hal_status = ath11k_hal_rx_parse_mon_status(ab, ppdu_info, skb); -@@ -6136,6 +6137,7 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -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); 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 index fe767b6a33de2a..06cee635f3e79b 100644 --- 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 @@ -40,7 +40,7 @@ Signed-off-by: Balamurugan Selvarajan --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -427,9 +427,9 @@ int ath11k_dp_rxbufs_replenish(struct at +@@ -392,9 +392,9 @@ int ath11k_dp_rxbufs_replenish(struct at skb->data); } @@ -53,7 +53,7 @@ Signed-off-by: Balamurugan Selvarajan if (dma_mapping_error(ab->dev, paddr)) goto fail_free_skb; -@@ -465,8 +465,8 @@ fail_idr_remove: +@@ -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: 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 index b471fb326a5b48..157da104f1a4ee 100644 --- 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 @@ -26,7 +26,7 @@ Acked-by: Jeff Johnson --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -8221,7 +8221,6 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -8220,7 +8220,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; @@ -34,7 +34,7 @@ Acked-by: Jeff Johnson mutex_lock(&ar->conf_mutex); -@@ -8244,21 +8243,6 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -8243,21 +8242,6 @@ ath11k_mac_op_assign_vif_chanctx(struct goto out; } 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 index 2fb2cdfd429b11..cbf643d1adaddc 100644 --- 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 @@ -19,7 +19,7 @@ Acked-by: Jeff Johnson --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -261,8 +261,8 @@ static const u32 ath11k_smps_map[] = { +@@ -256,8 +256,8 @@ static const u32 ath11k_smps_map[] = { [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE, }; @@ -30,7 +30,7 @@ Acked-by: Jeff Johnson enum nl80211_he_ru_alloc ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc(u16 ru_phy) { -@@ -5319,7 +5319,7 @@ static int ath11k_mac_station_add(struct +@@ -5316,7 +5316,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) { @@ -39,7 +39,7 @@ Acked-by: Jeff Johnson if (ret) { ath11k_warn(ab, "failed to delay vdev start: %d\n", ret); goto free_tx_stats; -@@ -8164,8 +8164,8 @@ unlock: +@@ -8163,8 +8163,8 @@ unlock: mutex_unlock(&ar->conf_mutex); } 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 index 4d83d0f0ed9029..732aed9dc5231b 100644 --- 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 @@ -18,7 +18,7 @@ Acked-by: Jeff Johnson --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -261,9 +261,6 @@ static const u32 ath11k_smps_map[] = { +@@ -256,9 +256,6 @@ static const u32 ath11k_smps_map[] = { [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE, }; @@ -28,7 +28,7 @@ Acked-by: Jeff Johnson enum nl80211_he_ru_alloc ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc(u16 ru_phy) { enum nl80211_he_ru_alloc ret; -@@ -5249,100 +5246,6 @@ static void ath11k_mac_dec_num_stations( +@@ -5246,100 +5243,6 @@ static void ath11k_mac_dec_num_stations( ar->num_stations--; } @@ -129,7 +129,7 @@ Acked-by: Jeff Johnson static u32 ath11k_mac_ieee80211_sta_bw_to_wmi(struct ath11k *ar, struct ieee80211_sta *sta) { -@@ -5398,187 +5301,6 @@ static int ath11k_mac_cfg_dyn_vlan(struc +@@ -5395,187 +5298,6 @@ static int ath11k_mac_cfg_dyn_vlan(struc return ret; } @@ -317,7 +317,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) -@@ -9739,6 +9461,281 @@ ath11k_mac_op_config_mesh_offload_path(s +@@ -9732,6 +9454,281 @@ ath11k_mac_op_config_mesh_offload_path(s } #endif 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 index d1b462519c91e8..5c847ff05a8f5d 100644 --- 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 @@ -52,7 +52,7 @@ Acked-by: Jeff Johnson --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -7933,6 +7933,30 @@ static int ath11k_mac_start_vdev_delay(s +@@ -7932,6 +7932,30 @@ static int ath11k_mac_start_vdev_delay(s return 0; } @@ -83,7 +83,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -@@ -7977,15 +8001,17 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -7976,15 +8000,17 @@ ath11k_mac_op_assign_vif_chanctx(struct goto out; } @@ -109,7 +109,7 @@ Acked-by: Jeff Johnson if (arvif->vdev_type != WMI_VDEV_TYPE_MONITOR && test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags)) { -@@ -8025,8 +8051,6 @@ ath11k_mac_op_unassign_vif_chanctx(struc +@@ -8024,8 +8050,6 @@ ath11k_mac_op_unassign_vif_chanctx(struc "chanctx unassign ptr %p vdev_id %i\n", ctx, arvif->vdev_id); @@ -118,7 +118,7 @@ Acked-by: Jeff Johnson if (ab->hw_params.vdev_start_delay && arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { spin_lock_bh(&ab->base_lock); -@@ -8050,24 +8074,13 @@ ath11k_mac_op_unassign_vif_chanctx(struc +@@ -8049,24 +8073,13 @@ ath11k_mac_op_unassign_vif_chanctx(struc return; } @@ -149,7 +149,7 @@ Acked-by: Jeff Johnson } if (ab->hw_params.vdev_start_delay && -@@ -9555,6 +9568,46 @@ exit: +@@ -9548,6 +9561,46 @@ exit: return ret; } @@ -196,7 +196,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, -@@ -9590,31 +9643,15 @@ static int ath11k_mac_op_sta_state(struc +@@ -9583,31 +9636,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)) { @@ -233,7 +233,7 @@ Acked-by: Jeff Johnson 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); -@@ -9625,12 +9662,6 @@ static int ath11k_mac_op_sta_state(struc +@@ -9618,12 +9655,6 @@ static int ath11k_mac_op_sta_state(struc } spin_unlock_bh(&ar->ab->base_lock); mutex_unlock(&ar->ab->tbl_mtx_lock); @@ -246,7 +246,7 @@ Acked-by: Jeff Johnson } 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 +@@ -10195,6 +10226,8 @@ static int __ath11k_mac_register(struct wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); 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 index 2362820dc9e838..52259c35b2a03e 100644 --- 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 @@ -153,7 +153,7 @@ #include "hw.h" #include "peer.h" #include "mac.h" -@@ -551,7 +553,9 @@ static void ath11k_dp_tx_cache_peer_stat +@@ -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; @@ -163,7 +163,7 @@ enum hal_tx_rate_stats_pkt_type pkt_type; enum hal_tx_rate_stats_sgi sgi; enum hal_tx_rate_stats_bw bw; -@@ -640,8 +644,10 @@ void ath11k_dp_tx_update_txcompl(struct +@@ -639,8 +643,10 @@ void ath11k_dp_tx_update_txcompl(struct ath11k_mac_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones); } @@ -176,7 +176,7 @@ spin_unlock_bh(&ab->base_lock); --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -9812,7 +9812,7 @@ static const struct ieee80211_ops ath11k +@@ -9805,7 +9805,7 @@ static const struct ieee80211_ops ath11k .set_wakeup = ath11k_wow_op_set_wakeup, #endif diff --git a/package/kernel/mac80211/patches/nss/ath11k/999-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 index 85562dc463a211..dbe6ce111a2f97 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/999-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 @@ -49,7 +49,7 @@ Signed-off-by: Ramya Gnanasekar * |-------------------------------------------------------------------| * | rsvd2 | ring_buffer_size | * |-------------------------------------------------------------------| -@@ -686,6 +691,14 @@ enum htt_stats_internal_ppdu_frametype { +@@ -686,6 +687,14 @@ enum htt_stats_internal_ppdu_frametype { * |-------------------------------------------------------------------| * | tlv_filter_in_flags | * |-------------------------------------------------------------------| @@ -64,7 +64,7 @@ Signed-off-by: Ramya Gnanasekar * Where: * PS = pkt_swap * SS = status_swap -@@ -699,7 +712,10 @@ enum htt_stats_internal_ppdu_frametype { +@@ -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 @@ -76,7 +76,7 @@ Signed-off-by: Ramya Gnanasekar * dword1 - b'0:16 - ring_buffer_size: size of buffers referenced by rx ring, * in byte units. * Valid only for HW_TO_SW_RING and SW_TO_HW_RING -@@ -728,6 +744,42 @@ enum htt_stats_internal_ppdu_frametype { +@@ -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 @@ -119,7 +119,7 @@ Signed-off-by: Ramya Gnanasekar */ #define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) -@@ -735,8 +787,16 @@ enum htt_stats_internal_ppdu_frametype { +@@ -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) @@ -136,7 +136,7 @@ Signed-off-by: Ramya Gnanasekar enum htt_rx_filter_tlv_flags { HTT_RX_FILTER_TLV_FLAGS_MPDU_START = BIT(0), -@@ -1040,6 +1100,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) @@ -151,7 +151,7 @@ Signed-off-by: Ramya Gnanasekar struct htt_rx_ring_selection_cfg_cmd { u32 info0; u32 info1; -@@ -1048,6 +1116,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; @@ -162,7 +162,7 @@ Signed-off-by: Ramya Gnanasekar } __packed; struct htt_rx_ring_tlv_filter { -@@ -1056,6 +1128,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 */ @@ -375,7 +375,7 @@ Signed-off-by: Ramya Gnanasekar hdr = (struct ieee80211_hdr *)first_hdr; hdr_len = ieee80211_hdrlen(hdr->frame_control); -@@ -3097,6 +3204,20 @@ static int ath11k_dp_rx_process_msdu(str +@@ -3096,6 +3203,20 @@ static int ath11k_dp_rx_process_msdu(str goto free_out; } @@ -396,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); -@@ -3109,8 +3230,9 @@ static int ath11k_dp_rx_process_msdu(str +@@ -3108,8 +3229,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); @@ -408,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; -@@ -4069,6 +4191,7 @@ static int ath11k_dp_rx_h_verify_tkip_mi +@@ -4068,6 +4190,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); @@ -416,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; -@@ -4349,8 +4472,8 @@ static void ath11k_dp_rx_h_sort_frags(st +@@ -4348,8 +4471,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) { @@ -426,7 +426,7 @@ Signed-off-by: Ramya Gnanasekar u8 *ehdr; u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; -@@ -4580,8 +4703,9 @@ ath11k_dp_process_rx_err_buf(struct ath1 +@@ -4579,8 +4702,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); @@ -438,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); -@@ -5206,6 +5330,47 @@ void ath11k_dp_rx_pdev_free(struct ath11 +@@ -5205,6 +5329,47 @@ void ath11k_dp_rx_pdev_free(struct ath11 ath11k_dp_rxdma_pdev_buf_free(ar); } @@ -486,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; -@@ -5299,6 +5464,12 @@ config_refill_ring: +@@ -5298,6 +5463,12 @@ config_refill_ring: } } @@ -501,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 -@@ -1264,6 +1264,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)); @@ -510,7 +510,7 @@ Signed-off-by: Ramya Gnanasekar cmd->info1 = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE, rx_buf_size); -@@ -1273,6 +1275,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; @@ -537,7 +537,7 @@ Signed-off-by: Ramya Gnanasekar ret = ath11k_htc_send(&ab->htc, ab->dp.eid, skb); if (ret) goto err_free; -@@ -1351,6 +1373,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; @@ -933,7 +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 -@@ -6455,6 +6455,7 @@ static int ath11k_mac_config_mon_status_ +@@ -6452,6 +6452,7 @@ static int ath11k_mac_config_mon_status_ tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar); } 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 index 1f554ae95ccc69..241edd1f68f799 100644 --- 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 @@ -25,7 +25,7 @@ Signed-off-by: P Praneesh --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -5994,6 +5994,7 @@ static void ath11k_update_radiotap(struc +@@ -5993,6 +5993,7 @@ static void ath11k_update_radiotap(struc { struct ieee80211_supported_band *sband; u8 *ptr = NULL; @@ -33,7 +33,7 @@ Signed-off-by: P Praneesh rxs->flag |= RX_FLAG_MACTIME_START; rxs->signal = ppduinfo->rssi_comb + ATH11K_DEFAULT_NOISE_FLOOR; -@@ -6001,6 +6002,11 @@ static void ath11k_update_radiotap(struc +@@ -6000,6 +6001,11 @@ static void ath11k_update_radiotap(struc if (ppduinfo->nss) rxs->nss = ppduinfo->nss; @@ -128,7 +128,7 @@ Signed-off-by: P Praneesh struct hal_rx_rxpcu_classification_overview { --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h -@@ -306,6 +306,7 @@ struct ath11k_hw_ops { +@@ -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); 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 index 499f720caba8cb..1f68d1a79119af 100644 --- 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 @@ -28,7 +28,7 @@ Signed-off-by: Tamizh Chelvam } --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -3336,18 +3336,16 @@ try_again: +@@ -3383,18 +3383,16 @@ try_again: ar = ab->pdevs[mac_id].ar; rx_ring = &ar->dp.rx_refill_buf_ring; spin_lock_bh(&rx_ring->idr_lock); @@ -50,7 +50,7 @@ Signed-off-by: Tamizh Chelvam dma_unmap_single(ab->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu), DMA_FROM_DEVICE); -@@ -4574,17 +4572,14 @@ ath11k_dp_process_rx_err_buf(struct ath1 +@@ -4665,17 +4663,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); @@ -70,7 +70,7 @@ Signed-off-by: Tamizh Chelvam rxcb = ATH11K_SKB_RXCB(msdu); dma_unmap_single(ar->ab->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu), -@@ -5005,18 +5000,16 @@ int ath11k_dp_rx_process_wbm_err(struct +@@ -5081,18 +5076,16 @@ int ath11k_dp_rx_process_wbm_err(struct rx_ring = &ar->dp.rx_refill_buf_ring; spin_lock_bh(&rx_ring->idr_lock); @@ -92,7 +92,7 @@ Signed-off-by: Tamizh Chelvam dma_unmap_single(ab->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu), DMA_FROM_DEVICE); -@@ -5131,16 +5124,14 @@ int ath11k_dp_process_rxdma_err(struct a +@@ -5207,16 +5200,14 @@ int ath11k_dp_process_rxdma_err(struct a msdu_cookies[i]); spin_lock_bh(&rx_ring->idr_lock); @@ -111,7 +111,7 @@ Signed-off-by: Tamizh Chelvam rxcb = ATH11K_SKB_RXCB(skb); dma_unmap_single(ab->dev, rxcb->paddr, -@@ -6399,16 +6390,14 @@ ath11k_dp_rx_full_mon_mpdu_pop(struct at +@@ -6427,16 +6418,14 @@ ath11k_dp_rx_full_mon_mpdu_pop(struct at msdu_list.sw_cookie[i]); spin_lock_bh(&rx_ring->idr_lock); 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 index c5134fca93a867..acf3edc3cd7022 100644 --- 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 @@ -114,7 +114,7 @@ Signed-off-by: Tamizh Chelvam return 0; } -@@ -3346,11 +3365,14 @@ int ath11k_dp_process_rx(struct ath11k_b +@@ -3345,11 +3364,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; @@ -130,7 +130,7 @@ Signed-off-by: Tamizh Chelvam srng = &ab->hal.srng_list[dp->reo_dst_ring[ring_id].ring_id]; -@@ -3385,8 +3407,15 @@ try_again: +@@ -3382,8 +3404,15 @@ try_again: ar = ab->pdevs[mac_id].ar; rx_ring = &ar->dp.rx_refill_buf_ring; @@ -147,7 +147,7 @@ Signed-off-by: Tamizh Chelvam spin_unlock_bh(&rx_ring->idr_lock); if (unlikely(!msdu)) { ath11k_warn(ab, "frame rx with invalid buf_id %d\n", -@@ -3464,9 +3493,12 @@ try_again: +@@ -3461,9 +3490,12 @@ try_again: rx_ring = &ar->dp.rx_refill_buf_ring; ath11k_dp_rxbufs_replenish(ab, i, rx_ring, num_buffs_reaped[i], @@ -161,7 +161,7 @@ Signed-off-by: Tamizh Chelvam return total_msdu_reaped; } -@@ -4831,7 +4864,7 @@ exit: +@@ -4825,7 +4857,7 @@ exit: rx_ring = &ar->dp.rx_refill_buf_ring; ath11k_dp_rxbufs_replenish(ab, i, rx_ring, n_bufs_reaped[i], @@ -170,7 +170,7 @@ Signed-off-by: Tamizh Chelvam } return tot_n_bufs_reaped; -@@ -5047,14 +5080,17 @@ int ath11k_dp_rx_process_wbm_err(struct +@@ -5041,14 +5073,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; @@ -189,7 +189,7 @@ Signed-off-by: Tamizh Chelvam srng = &ab->hal.srng_list[dp->rx_rel_ring.ring_id]; -@@ -5077,9 +5112,15 @@ int ath11k_dp_rx_process_wbm_err(struct +@@ -5074,9 +5109,15 @@ int ath11k_dp_rx_process_wbm_err(struct ar = ab->pdevs[mac_id].ar; rx_ring = &ar->dp.rx_refill_buf_ring; @@ -206,7 +206,7 @@ Signed-off-by: Tamizh Chelvam spin_unlock_bh(&rx_ring->idr_lock); if (!msdu) { ath11k_warn(ab, "frame rx with invalid buf_id %d pdev %d\n", -@@ -5124,7 +5165,7 @@ int ath11k_dp_rx_process_wbm_err(struct +@@ -5121,7 +5162,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], @@ -215,7 +215,7 @@ Signed-off-by: Tamizh Chelvam } rcu_read_lock(); -@@ -5151,6 +5187,8 @@ int ath11k_dp_rx_process_wbm_err(struct +@@ -5143,6 +5184,8 @@ int ath11k_dp_rx_process_wbm_err(struct } rcu_read_unlock(); done: @@ -224,7 +224,7 @@ Signed-off-by: Tamizh Chelvam return total_num_buffs_reaped; } -@@ -5238,7 +5276,7 @@ int ath11k_dp_process_rxdma_err(struct a +@@ -5228,7 +5271,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, @@ -233,7 +233,7 @@ Signed-off-by: Tamizh Chelvam return budget - quota; } -@@ -6184,12 +6222,12 @@ static void ath11k_dp_rx_mon_dest_proces +@@ -6180,12 +6223,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, @@ -248,7 +248,7 @@ Signed-off-by: Tamizh Chelvam } } -@@ -6701,7 +6739,7 @@ next_entry: +@@ -6695,7 +6738,7 @@ next_entry: ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, &dp->rxdma_mon_buf_ring, rx_bufs_used, diff --git a/package/kernel/mac80211/patches/nss/ath11k/999-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 index b58b13eebe1d40..d1b73ca3597606 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/999-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 -@@ -2454,16 +2454,27 @@ static void ath11k_get_dot11_hdr_from_rx +@@ -2452,16 +2452,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; -@@ -2499,6 +2510,7 @@ static void ath11k_dp_rx_h_undecap_nwifi +@@ -2497,6 +2508,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; -@@ -2543,26 +2555,46 @@ static void ath11k_dp_rx_h_undecap_nwifi +@@ -2541,26 +2553,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 -@@ -2671,6 +2703,7 @@ static void ath11k_dp_rx_h_undecap_eth(s +@@ -2669,6 +2701,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}}; -@@ -2680,6 +2713,11 @@ static void ath11k_dp_rx_h_undecap_eth(s +@@ -2678,6 +2711,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); -@@ -2697,6 +2735,11 @@ static void ath11k_dp_rx_h_undecap_eth(s +@@ -2695,6 +2733,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)); -@@ -2705,12 +2748,22 @@ static void ath11k_dp_rx_h_undecap_eth(s +@@ -2703,12 +2746,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,7 @@ Signed-off-by: Tamizh Chelvam Raja memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); exit: -@@ -2731,6 +2784,7 @@ static void ath11k_dp_rx_h_undecap_snap( +@@ -2729,6 +2782,7 @@ static void ath11k_dp_rx_h_undecap_snap( struct ieee80211_hdr *hdr; size_t hdr_len; u8 l3_pad_bytes; @@ -190,7 +190,7 @@ Signed-off-by: Tamizh Chelvam Raja 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( +@@ -2753,12 +2807,22 @@ static void ath11k_dp_rx_h_undecap_snap( hdr_len = ieee80211_hdrlen(hdr->frame_control); if (!(status->flag & RX_FLAG_IV_STRIPPED)) { @@ -217,7 +217,7 @@ Signed-off-by: Tamizh Chelvam Raja memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); } -@@ -2890,7 +2954,7 @@ static void ath11k_dp_rx_h_mpdu(struct a +@@ -2887,7 +2951,7 @@ static void ath11k_dp_rx_h_mpdu(struct a struct ieee80211_rx_status *rx_status, bool *fast_rx) { @@ -226,7 +226,7 @@ Signed-off-by: Tamizh Chelvam Raja enum hal_encrypt_type enctype; bool is_decrypted = false; struct ath11k_skb_rxcb *rxcb; -@@ -3123,10 +3187,16 @@ static void ath11k_dp_rx_deliver_msdu(st +@@ -3120,10 +3184,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; @@ -243,7 +243,7 @@ Signed-off-by: Tamizh Chelvam Raja he = skb_push(msdu, sizeof(known)); memcpy(he, &known, sizeof(known)); status->flag |= RX_FLAG_RADIOTAP_HE; -@@ -3182,6 +3252,7 @@ static void ath11k_dp_rx_deliver_msdu(st +@@ -3179,6 +3249,7 @@ static void ath11k_dp_rx_deliver_msdu(st !(is_mcbc && rx_status->flag & RX_FLAG_DECRYPTED)) rx_status->flag |= RX_FLAG_8023; diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index a5da9e91eae835..86b2f2169bb79f 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -4688,8 +4688,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/nss/subsys/199-001-mac80211-add-nss-support.patch b/package/kernel/mac80211/patches/nss/subsys/199-001-mac80211-add-nss-support.patch index fc8fec0660f352..ecdf4d15c0c896 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 }; /** -@@ -1408,7 +1424,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 -@@ -1416,7 +1432,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) -@@ -1989,6 +2005,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 -@@ -2680,6 +2706,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 { -@@ -2737,6 +2765,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 -@@ -3749,6 +3778,10 @@ struct ieee80211_prep_tx_info { +@@ -3751,6 +3780,10 @@ struct ieee80211_prep_tx_info { * non-MLO connections. * The callback can sleep. * @@ -116,7 +116,7 @@ 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. -@@ -4300,7 +4333,9 @@ struct ieee80211_ops { +@@ -4302,7 +4335,9 @@ struct ieee80211_ops { struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, u64 changed); @@ -127,7 +127,7 @@ Signed-off-by: Sriram R 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, -@@ -4605,7 +4640,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); @@ -225,7 +225,7 @@ Signed-off-by: Sriram R return -EINVAL; --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c -@@ -2370,6 +2370,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; @@ -272,7 +272,7 @@ Signed-off-by: Sriram R info_id = ieee80211_store_ack_skb(local, skb, &info_flags, cookie); -@@ -4641,13 +4655,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 -@@ -2679,7 +2679,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)) -@@ -2729,6 +2729,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); } -@@ -2757,6 +2759,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); diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index fffe171334c9a4..01740e29803580 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -6215,7 +6215,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 index bd9c1c024b1e5d..d4410bd712f669 100644 --- 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 @@ -49,7 +49,7 @@ Signed-off-by: Muna Sinada #endif /* __NET_CFG80211_H */ --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -7361,6 +7361,20 @@ u32 ieee80211_calc_rx_airtime(struct iee +@@ -7363,6 +7363,20 @@ u32 ieee80211_calc_rx_airtime(struct iee int len); /** @@ -158,7 +158,7 @@ Signed-off-by: Muna Sinada #undef TRACE_INCLUDE_PATH --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -20199,6 +20199,42 @@ nla_put_failure: +@@ -20211,6 +20211,42 @@ nla_put_failure: } EXPORT_SYMBOL(cfg80211_update_owe_info_event); diff --git a/package/kernel/mac80211/patches/nss/subsys/207-ath11k-Add-support-for-dynamic-vlan.patch b/package/kernel/mac80211/patches/nss/subsys/207-ath11k-Add-support-for-dynamic-vlan.patch index 15d796071fa077..5ae1ba64bba9d5 100644 --- a/package/kernel/mac80211/patches/nss/subsys/207-ath11k-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, -@@ -4270,6 +4273,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); -@@ -4291,6 +4296,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/nss/subsys/207-mac80211-add-nss-redirect-support.patch b/package/kernel/mac80211/patches/nss/subsys/207-mac80211-add-nss-redirect-support.patch index a4895803b38ba0..38d737dc37d96a 100644 --- a/package/kernel/mac80211/patches/nss/subsys/207-mac80211-add-nss-redirect-support.patch +++ b/package/kernel/mac80211/patches/nss/subsys/207-mac80211-add-nss-redirect-support.patch @@ -209,7 +209,7 @@ Signed-off-by: Sowmiya Sree Elavalagan --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4503,6 +4503,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 -@@ -4516,6 +4545,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; -@@ -4702,6 +4735,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/nss/subsys/235-001-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 index 55e2fff1560fb8..3d543d714122dd 100644 --- a/package/kernel/mac80211/patches/nss/subsys/235-001-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 -@@ -5098,6 +5098,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); @@ -137,7 +137,7 @@ Signed-off-by: Sathishkumar Muruganandam { --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4297,8 +4297,13 @@ void __ieee80211_subif_start_xmit(struct +@@ -4298,8 +4298,13 @@ void __ieee80211_subif_start_xmit(struct sta = NULL; if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { @@ -153,7 +153,7 @@ Signed-off-by: Sathishkumar Muruganandam if (ap_sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED && !is_multicast_ether_addr(skb->data)) { if (sta) -@@ -4688,7 +4693,8 @@ static void ieee80211_8023_xmit(struct i +@@ -4689,7 +4694,8 @@ static void ieee80211_8023_xmit(struct i info->hw_queue = sdata->vif.hw_queue[queue]; diff --git a/package/kernel/mac80211/patches/nss/subsys/236-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 index 803ee900bfdcc1..542ab4e6a93831 100644 --- a/package/kernel/mac80211/patches/nss/subsys/236-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 -@@ -2086,6 +2086,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) -@@ -2105,6 +2107,7 @@ struct ieee80211_key_conf { +@@ -2107,6 +2109,7 @@ struct ieee80211_key_conf { u8 hw_key_idx; s8 keyidx; u16 flags; @@ -102,7 +102,7 @@ Signed-off-by: Sathishkumar Muruganandam key->conf.cipher = cipher; --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4649,16 +4649,25 @@ static void ieee80211_8023_xmit(struct i +@@ -4650,16 +4650,25 @@ static void ieee80211_8023_xmit(struct i struct ieee80211_key *key, struct sk_buff *skb) { struct ieee80211_tx_info *info; diff --git a/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch b/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch index 310256f78d42fb..0e92c0f1332b7d 100644 --- a/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch +++ b/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch @@ -30,7 +30,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran struct ieee80211_local *local; --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4678,19 +4678,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); @@ -64,7 +64,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran } skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); -@@ -4747,7 +4749,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; @@ -73,7 +73,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran struct sta_info *sta; #ifdef CPTCFG_MAC80211_NSS_SUPPORT -@@ -4765,9 +4767,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4766,9 +4768,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 goto out; } @@ -90,7 +90,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran goto skip_offload; key = rcu_dereference(sta->ptk[sta->ptk_idx]); -@@ -4778,6 +4784,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); @@ -98,7 +98,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran ieee80211_8023_xmit(sdata, dev, sta, key, skb); goto out; -@@ -6284,13 +6291,7 @@ start_xmit: +@@ -6285,13 +6292,7 @@ start_xmit: mutex_lock(&local->mtx); local_bh_disable(); diff --git a/package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch b/package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch index 55ad36baf69aa4..337a0982a20c9d 100644 --- a/package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch +++ b/package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch @@ -78,7 +78,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran 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 }; -@@ -2769,6 +2789,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 -@@ -4269,6 +4290,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. -@@ -4652,6 +4675,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); -@@ -7510,4 +7539,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 -@@ -2523,6 +2523,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; -@@ -2539,8 +2540,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)) { -@@ -2554,8 +2558,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)) -@@ -2590,8 +2598,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. -@@ -2633,6 +2645,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); @@ -1221,7 +1221,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran info->ack_frame_id = info_id; info->band = band; -@@ -4274,6 +4284,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; @@ -1229,7 +1229,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran struct ieee80211_sub_if_data *ap_sdata; if (unlikely(!ieee80211_sdata_running(sdata) || skb->len < ETH_HLEN)) { -@@ -4350,9 +4361,15 @@ void __ieee80211_subif_start_xmit(struct +@@ -4351,9 +4362,15 @@ void __ieee80211_subif_start_xmit(struct goto out; } diff --git a/package/kernel/mac80211/patches/nss/subsys/335-0003-ath11k-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 index f78d7ce6e09304..0704e8fcf7da86 100644 --- a/package/kernel/mac80211/patches/nss/subsys/335-0003-ath11k-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 -@@ -2731,6 +2731,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 { -@@ -2790,6 +2792,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, diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index 63373b7751f9eb..314bcbe549af97 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -4761,6 +4761,67 @@ out_free: +@@ -4762,6 +4762,67 @@ out_free: kfree_skb(skb); } @@ -82,7 +82,7 @@ Signed-off-by: Aloka Dixit netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, struct net_device *dev) { -@@ -4800,6 +4861,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/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch b/package/kernel/mac80211/patches/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch index 0cb2a1e95244e3..c8d719006d170f 100644 --- a/package/kernel/mac80211/patches/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch +++ b/package/kernel/mac80211/patches/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch @@ -33,7 +33,7 @@ Signed-off-by: Tamizh Chelvam --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4695,7 +4695,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4696,7 +4696,7 @@ static void ieee80211_8023_xmit(struct i ieee80211_aggr_check(sdata, sta, skb); @@ -42,7 +42,7 @@ Signed-off-by: Tamizh Chelvam tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); if (tid_tx) { -@@ -4746,7 +4746,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4747,7 +4747,7 @@ static void ieee80211_8023_xmit(struct i &info->flags, NULL); dev_sw_netstats_tx_add(dev, skbs, len); diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index 2cb2ebe6f58f76..55380f59d3826c 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -1405,8 +1405,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 -@@ -1478,22 +1476,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), diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index a947728fc661f1..13977ab665862e 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 @@ -44,7 +44,7 @@ Signed-off-by: Aaradhana Sahu /* misc utils */ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, -@@ -4319,7 +4320,7 @@ void __ieee80211_subif_start_xmit(struct +@@ -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]); @@ -53,7 +53,7 @@ Signed-off-by: Aaradhana Sahu rcu_read_unlock(); return; } -@@ -4365,7 +4366,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]); @@ -62,7 +62,7 @@ Signed-off-by: Aaradhana Sahu } else { dev_sw_netstats_tx_add(dev, 1, skb->len); ieee80211_xmit(sdata, sta, skb); -@@ -4663,7 +4664,8 @@ 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, @@ -72,7 +72,7 @@ Signed-off-by: Aaradhana Sahu { struct ieee80211_tx_info *info; struct ethhdr *ehdr = (struct ethhdr *)skb->data; -@@ -4719,6 +4721,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4720,6 +4722,7 @@ static void ieee80211_8023_xmit(struct i info = IEEE80211_SKB_CB(skb); memset(info, 0, sizeof(*info)); @@ -80,7 +80,7 @@ Signed-off-by: Aaradhana Sahu info->hw_queue = sdata->vif.hw_queue[queue]; if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && -@@ -4739,11 +4742,12 @@ static void ieee80211_8023_xmit(struct i +@@ -4740,11 +4743,12 @@ static void ieee80211_8023_xmit(struct i memcpy(IEEE80211_SKB_CB(seg), info, sizeof(*info)); } @@ -96,7 +96,7 @@ Signed-off-by: Aaradhana Sahu dev_sw_netstats_tx_add(dev, skbs, len); if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD) && sta) { -@@ -4763,7 +4767,8 @@ out_free: +@@ -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, @@ -106,7 +106,7 @@ Signed-off-by: Aaradhana Sahu { struct ieee80211_tx_info *info; struct ieee80211_local *local = sdata->local; -@@ -4772,6 +4777,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; @@ -116,7 +116,7 @@ Signed-off-by: Aaradhana Sahu /* * If the skb is shared we need to obtain our own copy. -@@ -4783,11 +4791,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)); @@ -133,7 +133,7 @@ Signed-off-by: Aaradhana Sahu info->flags |= IEEE80211_TX_CTL_HW_80211_ENCAP; info->control.vif = &sdata->vif; -@@ -4821,14 +4831,23 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4822,14 +4832,23 @@ void ieee80211_8023_xmit_ap(struct ieee8 drv_tx(local, &control, skb); } @@ -158,7 +158,7 @@ Signed-off-by: Aaradhana Sahu #ifdef CPTCFG_MAC80211_NSS_SUPPORT ieee80211_xmit_nss_fixup(skb, dev); -@@ -4844,14 +4863,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; } @@ -176,7 +176,7 @@ Signed-off-by: Aaradhana Sahu goto skip_offload; key = rcu_dereference(sta->ptk[sta->ptk_idx]); -@@ -4862,13 +4882,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) { @@ -192,7 +192,7 @@ Signed-off-by: Aaradhana Sahu goto out; skip_offload: -@@ -6374,7 +6394,10 @@ start_xmit: +@@ -6375,7 +6395,10 @@ start_xmit: mutex_lock(&local->mtx); local_bh_disable(); diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index 7ffaf99158b90e..62916f15eddb56 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -2350,7 +2350,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; 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 index 098767aa3f36db..ea83021014ad26 100644 --- 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 @@ -16,7 +16,7 @@ Signed-off-by: Maharaja Kennadyrajan --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c -@@ -2396,7 +2396,7 @@ void ieee80211_sta_update_pending_airtim +@@ -2385,7 +2385,7 @@ void ieee80211_sta_update_pending_airtim } static struct ieee80211_sta_rx_stats * @@ -25,7 +25,7 @@ Signed-off-by: Maharaja Kennadyrajan { struct ieee80211_sta_rx_stats *stats = &sta->deflink.rx_stats; int cpu; -@@ -2409,8 +2409,13 @@ sta_get_last_rx_stats(struct sta_info *s +@@ -2398,8 +2398,13 @@ sta_get_last_rx_stats(struct sta_info *s for_each_possible_cpu(cpu) { struct ieee80211_sta_rx_stats *cpustats; @@ -39,7 +39,7 @@ Signed-off-by: Maharaja Kennadyrajan if (time_after(cpustats->last_rx, stats->last_rx)) stats = cpustats; -@@ -2480,7 +2485,7 @@ static void sta_stats_decode_rate(struct +@@ -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) { @@ -48,16 +48,16 @@ Signed-off-by: Maharaja Kennadyrajan if (rate == STA_STATS_RATE_INVALID) return -EINVAL; -@@ -2680,7 +2685,7 @@ void sta_set_sinfo(struct sta_info *sta, +@@ -2576,7 +2581,7 @@ void sta_set_sinfo(struct sta_info *sta, + int i, ac, cpu; struct ieee80211_sta_rx_stats *last_rxstats; - struct link_sta_info *link_sta = NULL; - last_rxstats = sta_get_last_rx_stats(sta); + last_rxstats = sta_get_last_rx_stats(sta, false); sinfo->generation = sdata->local->sta_generation; -@@ -2924,7 +2929,7 @@ u32 sta_get_expected_throughput(struct s +@@ -2859,7 +2864,7 @@ u32 sta_get_expected_throughput(struct s unsigned long ieee80211_sta_last_active(struct sta_info *sta) { diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index 50466d46c37880..6be28b6ac56663 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 @@ -58,7 +58,7 @@ Signed-off-by: Tamizh Chelvam Raja if (!skb) return true; -@@ -4343,7 +4345,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,7 +67,7 @@ Signed-off-by: Tamizh Chelvam Raja if (!skb) { len = 0; goto out; -@@ -4714,7 +4716,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4715,7 +4717,7 @@ static void ieee80211_8023_xmit(struct i } } 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 index b76692a6f9500c..c2846abf7e5961 100644 --- 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 @@ -23,7 +23,7 @@ Signed-off-by: Yuvasree Sivasankaran --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -2730,6 +2730,9 @@ struct ieee80211_txq { +@@ -2732,6 +2732,9 @@ struct ieee80211_txq { * * @IEEE80211_HW_SUPPORTS_TID_CLASS_OFFLOAD: Hardware suports tid calssification offload. * @@ -33,7 +33,7 @@ Signed-off-by: Yuvasree Sivasankaran * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays */ enum ieee80211_hw_flags { -@@ -2790,6 +2793,7 @@ 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, @@ -83,7 +83,7 @@ Signed-off-by: Yuvasree Sivasankaran return false; if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) -@@ -4328,7 +4335,8 @@ void __ieee80211_subif_start_xmit(struct +@@ -4329,7 +4336,8 @@ void __ieee80211_subif_start_xmit(struct } } @@ -93,7 +93,7 @@ Signed-off-by: Yuvasree Sivasankaran ieee80211_aggr_check(sdata, sta, skb); if (sta) { -@@ -4680,8 +4688,10 @@ static void ieee80211_8023_xmit(struct i +@@ -4681,8 +4689,10 @@ static void ieee80211_8023_xmit(struct i bool multicast; u8 tid; @@ -106,7 +106,7 @@ Signed-off-by: Yuvasree Sivasankaran multicast = is_multicast_ether_addr(ra); -@@ -6416,9 +6426,12 @@ int ieee80211_tx_control_port(struct wip +@@ -6379,9 +6389,12 @@ int ieee80211_tx_control_port(struct wip } if (!IS_ERR(sta)) { @@ -123,7 +123,7 @@ Signed-off-by: Yuvasree Sivasankaran * for MLO STA, the SA should be the AP MLD address, but --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -4525,6 +4525,9 @@ static int ieee80211_get_txq_stats(struc +@@ -4524,6 +4524,9 @@ static int ieee80211_get_txq_stats(struc struct ieee80211_sub_if_data *sdata; int ret = 0; @@ -205,7 +205,7 @@ Signed-off-by: Yuvasree Sivasankaran int i; sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp); -@@ -607,18 +609,22 @@ __sta_info_alloc(struct ieee80211_sub_if +@@ -611,18 +613,22 @@ __sta_info_alloc(struct ieee80211_sub_if sta->last_connected = ktime_get_seconds(); @@ -237,7 +237,7 @@ Signed-off-by: Yuvasree Sivasankaran } if (sta_prepare_rate_control(local, sta, gfp)) -@@ -692,7 +698,8 @@ __sta_info_alloc(struct ieee80211_sub_if +@@ -696,7 +702,8 @@ __sta_info_alloc(struct ieee80211_sub_if return sta; free_txq: @@ -247,7 +247,7 @@ Signed-off-by: Yuvasree Sivasankaran free: sta_info_free_link(&sta->deflink); #ifdef CPTCFG_MAC80211_MESH -@@ -1687,11 +1694,13 @@ void ieee80211_sta_ps_deliver_wakeup(str +@@ -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); @@ -265,7 +265,7 @@ Signed-off-by: Yuvasree Sivasankaran } skb_queue_head_init(&pending); -@@ -2106,6 +2115,9 @@ ieee80211_sta_ps_deliver_response(struct +@@ -2110,6 +2119,9 @@ ieee80211_sta_ps_deliver_response(struct * TIM recalculation. */ @@ -275,7 +275,7 @@ Signed-off-by: Yuvasree Sivasankaran for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) { if (!sta->sta.txq[tid] || !(driver_release_tids & BIT(tid)) || -@@ -2521,7 +2533,7 @@ static void sta_set_tidstats(struct sta_ +@@ -2546,7 +2558,7 @@ static void sta_set_tidstats(struct sta_ tidstats->tx_msdu_failed = sta->deflink.status_stats.msdu_failed[tid]; } @@ -284,7 +284,7 @@ Signed-off-by: Yuvasree Sivasankaran spin_lock_bh(&local->fq.lock); rcu_read_lock(); -@@ -2849,6 +2861,9 @@ unsigned long ieee80211_sta_last_active( +@@ -2874,6 +2886,9 @@ unsigned long ieee80211_sta_last_active( static void sta_update_codel_params(struct sta_info *sta, u32 thr) { From 1e10c64e1bb9137216ec96331ed69660c54ade25 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 25 Mar 2024 15:05:45 -0400 Subject: [PATCH 166/225] firewall4: Remove dependency on fullconenat-nft Making it optional messes up package/install. Remove the dependency altogether. --- package/network/config/firewall4/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package/network/config/firewall4/Makefile b/package/network/config/firewall4/Makefile index 793aef35e7b71f..d1ae642ab103e9 100644 --- a/package/network/config/firewall4/Makefile +++ b/package/network/config/firewall4/Makefile @@ -24,8 +24,7 @@ define Package/firewall4 DEPENDS:= \ +kmod-nft-core +kmod-nft-fib +kmod-nft-offload \ +kmod-nft-nat +nftables-json \ - +ucode +ucode-mod-fs +ucode-mod-ubus +ucode-mod-uci \ - +PACKAGE_kmod-nft-fullcone:kmod-nft-fullcone + +ucode +ucode-mod-fs +ucode-mod-ubus +ucode-mod-uci EXTRA_DEPENDS:=ucode (>=2022.03.22) PROVIDES:=uci-firewall endef From a3658e1516b76700e8c14c8b015e3bd26c2c9210 Mon Sep 17 00:00:00 2001 From: neonman63 Date: Mon, 25 Mar 2024 23:38:14 +0300 Subject: [PATCH 167/225] Update nss-cfi to kernel 6.6 --- .../0605-1-qca-nss-cfi-support.patch | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/target/linux/qualcommax/patches-6.6/0605-1-qca-nss-cfi-support.patch b/target/linux/qualcommax/patches-6.6/0605-1-qca-nss-cfi-support.patch index f6a439ba5306a6..a0ed16e38f242e 100644 --- a/target/linux/qualcommax/patches-6.6/0605-1-qca-nss-cfi-support.patch +++ b/target/linux/qualcommax/patches-6.6/0605-1-qca-nss-cfi-support.patch @@ -1,6 +1,6 @@ --- a/crypto/authenc.c +++ b/crypto/authenc.c -@@ -415,6 +415,8 @@ static int crypto_authenc_create(struct +@@ -417,6 +417,8 @@ static int crypto_authenc_create(struct enc->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME) goto err_free_inst; @@ -11,7 +11,7 @@ inst->alg.base.cra_blocksize = enc->base.cra_blocksize; --- a/include/linux/crypto.h +++ b/include/linux/crypto.h -@@ -86,6 +86,11 @@ +@@ -101,6 +101,11 @@ #define CRYPTO_NOLOAD 0x00008000 /* @@ -25,6 +25,14 @@ * flag unset if they can't handle memory allocation failures. --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c +@@ -3,6 +3,7 @@ + + #include + #include ++#include + #include + #include + #include @@ -658,6 +658,7 @@ static int esp_output(struct xfrm_state struct ip_esp_hdr *esph; struct crypto_aead *aead; @@ -68,6 +76,14 @@ --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c +@@ -15,6 +15,7 @@ + + #include + #include ++#include + #include + #include + #include @@ -696,6 +696,7 @@ static int esp6_output(struct xfrm_state struct ip_esp_hdr *esph; struct crypto_aead *aead; From c47954ac6c80d5a48b558c78b8a75224c04eeede Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 25 Mar 2024 18:27:34 -0400 Subject: [PATCH 168/225] qualcommax: consolidate symbols, revert built-in Symbols for crypto, ktls, netfilter are removed from from being compiled into the kernel and instead left up to the user to compile as modules, as is the case upstream. Other unused qca features were also removed as they don't apply to ipq807x/6018 and are not upstream. Common symbols between 6.1/6.6 that are required for NSS related features have been consolidated into 'config-default'. There is an average 300kb of savings in the final kernel image as well decreased compile time. --- target/linux/qualcommax/config-6.1 | 32 ++---- .../linux/qualcommax/ipq807x/config-default | 104 +++--------------- 2 files changed, 21 insertions(+), 115 deletions(-) diff --git a/target/linux/qualcommax/config-6.1 b/target/linux/qualcommax/config-6.1 index c90649040d9bfd..0ee3b26e084bd0 100644 --- a/target/linux/qualcommax/config-6.1 +++ b/target/linux/qualcommax/config-6.1 @@ -78,15 +78,15 @@ CONFIG_COREDUMP=y CONFIG_CPUFREQ_DT=y CONFIG_CPUFREQ_DT_PLATDEV=y CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set CONFIG_CPU_FREQ_STAT=y CONFIG_CPU_FREQ_THERMAL=y CONFIG_CPU_IDLE=y @@ -187,11 +187,6 @@ CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT_MAP=y CONFIG_HWSPINLOCK=y CONFIG_HWSPINLOCK_QCOM=y -CONFIG_HW_RANDOM=y -CONFIG_HW_RANDOM_MSM=y -CONFIG_HZ=1000 -# CONFIG_HZ_100 is not set -CONFIG_HZ_1000=y CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y @@ -360,12 +355,7 @@ CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y CONFIG_POWER_RESET=y # CONFIG_POWER_RESET_MSM is not set CONFIG_POWER_SUPPLY=y -CONFIG_PREEMPT=y -CONFIG_PREEMPT_COUNT=y -# CONFIG_PREEMPT_DYNAMIC is not set -# CONFIG_PREEMPT_NONE_BUILD is not set -# CONFIG_PREEMPT_NONE is not set -CONFIG_PREEMPT_RCU=y +CONFIG_PREEMPT_NONE_BUILD=y CONFIG_PRINTK_TIME=y CONFIG_PTP_1588_CLOCK_OPTIONAL=y CONFIG_QCA807X_PHY=y @@ -382,7 +372,7 @@ CONFIG_QCOM_BAM_DMA=y # CONFIG_QCOM_CLK_APCS_MSM8916 is not set # CONFIG_QCOM_CLK_APCS_SDX55 is not set # CONFIG_QCOM_COMMAND_DB is not set -CONFIG_QCOM_CPR=y +# CONFIG_QCOM_CPR is not set # CONFIG_QCOM_EBI2 is not set # CONFIG_QCOM_FASTRPC is not set # CONFIG_QCOM_GENI_SE is not set @@ -428,7 +418,6 @@ CONFIG_QUEUED_SPINLOCKS=y CONFIG_RANDSTRUCT_NONE=y CONFIG_RAS=y CONFIG_RATIONAL=y -# CONFIG_RCU_BOOST is not set CONFIG_REGMAP=y CONFIG_REGMAP_MMIO=y CONFIG_REGULATOR=y @@ -488,11 +477,6 @@ CONFIG_SERIAL_MSM=y CONFIG_SERIAL_MSM_CONSOLE=y CONFIG_SGL_ALLOC=y CONFIG_SG_POOL=y -# CONFIG_ALLOC_SKB_PAGE_FRAG_DISABLE is not set -# CONFIG_DEBUG_OBJECTS_SKBUFF is not set -CONFIG_SKB_RECYCLER=y -CONFIG_SKB_RECYCLER_MULTI_CPU=y -# CONFIG_SKB_FAST_RECYCLABLE_DEBUG_ENABLE is not set CONFIG_SMP=y # CONFIG_SM_CAMCC_8450 is not set # CONFIG_SM_GCC_8150 is not set diff --git a/target/linux/qualcommax/ipq807x/config-default b/target/linux/qualcommax/ipq807x/config-default index 68a750e6edb4ac..eeb86e850f04f8 100644 --- a/target/linux/qualcommax/ipq807x/config-default +++ b/target/linux/qualcommax/ipq807x/config-default @@ -1,92 +1,21 @@ CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y CONFIG_ARM_QCOM_CPUFREQ_HW=y -CONFIG_ASN1=y -CONFIG_ASN1_ENCODER=y -CONFIG_ASSOCIATIVE_ARRAY=y -CONFIG_ASYMMETRIC_KEY_TYPE=y -# CONFIG_ASYMMETRIC_TPM_KEY_SUBTYPE is not set -CONFIG_AT803X_PHY=y -CONFIG_BPFILTER=y -CONFIG_BPFILTER_UMH=m -CONFIG_CLZ_TAB=y CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y # CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set -CONFIG_CRYPTO_AES_ARM64=y -CONFIG_CRYPTO_AES_ARM64_BS=y -CONFIG_CRYPTO_AES_ARM64_CE=y -CONFIG_CRYPTO_AES_ARM64_CE_BLK=y -CONFIG_CRYPTO_AES_ARM64_CE_CCM=y -CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y -CONFIG_CRYPTO_ANSI_CPRNG=y -CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=y -CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=y -CONFIG_CRYPTO_BLAKE2B=y -CONFIG_CRYPTO_BLAKE2S=y -CONFIG_CRYPTO_CFB=y -CONFIG_CRYPTO_CHACHA20=y -CONFIG_CRYPTO_CHACHA20POLY1305=y -CONFIG_CRYPTO_CHACHA20_NEON=y -CONFIG_CRYPTO_CMAC=y -CONFIG_CRYPTO_CRCT10DIF=y -CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=y -CONFIG_CRYPTO_CRYPTD=y -CONFIG_CRYPTO_CURVE25519=y -CONFIG_CRYPTO_DH=y -CONFIG_CRYPTO_DH_RFC7919_GROUPS=y -CONFIG_CRYPTO_DRBG=y -CONFIG_CRYPTO_DRBG_HMAC=y -CONFIG_CRYPTO_DRBG_MENU=y -CONFIG_CRYPTO_ECC=y -CONFIG_CRYPTO_ECDH=y -CONFIG_CRYPTO_ECDSA=y -CONFIG_CRYPTO_ECRDSA=y -CONFIG_CRYPTO_GF128MUL=y -CONFIG_CRYPTO_GHASH_ARM64_CE=y -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_JITTERENTROPY=y -CONFIG_CRYPTO_KEYWRAP=y -CONFIG_CRYPTO_LIB_CHACHA_GENERIC=y -CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=y -CONFIG_CRYPTO_LIB_POLY1305_GENERIC=y -CONFIG_CRYPTO_LIB_SM4=y -CONFIG_CRYPTO_LRW=y -CONFIG_CRYPTO_MD4=y -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_NULL2=y -CONFIG_CRYPTO_NHPOLY1305_NEON=y -CONFIG_CRYPTO_OFB=y -CONFIG_CRYPTO_POLY1305=y -CONFIG_CRYPTO_POLY1305_NEON=y -CONFIG_CRYPTO_POLYVAL_ARM64_CE=y -CONFIG_CRYPTO_RNG_DEFAULT=y -CONFIG_CRYPTO_RSA=y -CONFIG_CRYPTO_SHA1_ARM64_CE=y -CONFIG_CRYPTO_SHA2_ARM64_CE=y -CONFIG_CRYPTO_SHA256_ARM64=y -CONFIG_CRYPTO_SHA3=y -CONFIG_CRYPTO_SHA3_ARM64=y -CONFIG_CRYPTO_SHA512=y -CONFIG_CRYPTO_SHA512_ARM64=y -CONFIG_CRYPTO_SHA512_ARM64_CE=y -CONFIG_CRYPTO_SIMD=y -CONFIG_CRYPTO_SM2=y -CONFIG_CRYPTO_SM3=y -CONFIG_CRYPTO_SM3_ARM64_CE=y -CONFIG_CRYPTO_SM3_NEON=y -CONFIG_CRYPTO_SM4_ARM64_CE=y -CONFIG_CRYPTO_SM4_ARM64_CE_BLK=y -CONFIG_CRYPTO_SM4_ARM64_NEON_BLK=y -CONFIG_CRYPTO_STREEBOG=y -CONFIG_CRYPTO_XXHASH=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_DT_IDLE_GENPD=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MSM=y +CONFIG_HZ=1000 +# CONFIG_HZ_100 is not set +CONFIG_HZ_1000=y CONFIG_IP6_NF_TARGET_MASQUERADE=y CONFIG_IP_NF_TARGET_MASQUERADE=y CONFIG_IPQ_GCC_8074=y # CONFIG_MFD_HI6421_SPMI is not set CONFIG_MFD_SPMI_PMIC=y -CONFIG_MPILIB=y # CONFIG_NVMEM_SPMI_SDAM is not set -CONFIG_OID_REGISTRY=y CONFIG_PINCTRL_IPQ8074=y CONFIG_PINCTRL_QCOM_SPMI_PMIC=y # CONFIG_PM8916_WATCHDOG is not set @@ -95,15 +24,11 @@ CONFIG_PM_GENERIC_DOMAINS_OF=y # CONFIG_POWER_RESET_QCOM_PON is not set CONFIG_QCOM_APM=y # CONFIG_QCOM_COINCELL is not set +CONFIG_QCOM_CPR=y CONFIG_QCOM_GDSC=y -# CONFIG_QCOM_IPA is not set -CONFIG_QCOM_QFPROM=y -# CONFIG_QCOM_QMI_HELPERS is not set CONFIG_QCOM_SPMI_ADC5=y # CONFIG_QCOM_SPMI_RRADC is not set CONFIG_QCOM_VADC_COMMON=y -CONFIG_QCOM_WCNSS_CTRL=y -CONFIG_QCOM_WCNSS_PIL=y CONFIG_REGMAP_SPMI=y CONFIG_REGULATOR_CPR3=y # CONFIG_REGULATOR_CPR3_NPU is not set @@ -111,16 +36,13 @@ CONFIG_REGULATOR_CPR4_APSS=y # CONFIG_REGULATOR_QCOM_LABIBB is not set CONFIG_REGULATOR_QCOM_SPMI=y # CONFIG_REGULATOR_QCOM_USB_VBUS is not set -CONFIG_RESET_QCOM_AOSS=y -CONFIG_RESET_QCOM_PDC=y CONFIG_RTC_DRV_PM8XXX=y -# CONFIG_SCHED_CLUSTER is not set -CONFIG_SCHED_CORE=y +# CONFIG_ALLOC_SKB_PAGE_FRAG_DISABLE is not set +# CONFIG_DEBUG_OBJECTS_SKBUFF is not set +CONFIG_SKB_RECYCLER=y +CONFIG_SKB_RECYCLER_MULTI_CPU=y +# CONFIG_SKB_FAST_RECYCLABLE_DEBUG_ENABLE is not set CONFIG_SPMI=y # CONFIG_SPMI_HISI3670 is not set CONFIG_SPMI_MSM_PMIC_ARB=y # CONFIG_SPMI_PMIC_CLKDIV is not set -CONFIG_TLS=y -CONFIG_TLS_DEVICE=y -# CONFIG_TLS_TOE is not set -CONFIG_XOR_BLOCKS=y From 2da9f6012a7fdcdbec32ef901384262e0a89a259 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Tue, 26 Mar 2024 00:24:23 -0400 Subject: [PATCH 169/225] qualcommax: NSS: consolidate patches and align with 6.6 * renamed patches to follow same numbering between 6.1 and 6.6 * combined tcp_window_check and ETHERIP patches into CORE to align with 6.6 * combined skb_recycler patches into single patch to align with 6.6 --- .../0600-1-qca-nss-ecm-support-CORE.patch | 124 +++++ ...a-nss-ecm-netfilter-tcp_window_check.patch | 108 ----- ...ss-ecm-support-netfilter-DSCPREMARK.patch} | 0 ...ca-nss-clients-add-iptunnel-support.patch} | 0 ...5-qca-nss-clients-add-vxlan-support.patch} | 0 ...-nss-clients-iptunnel-lock-this-cpu.patch} | 0 ...patch => 0605-1-qca-nss-cfi-support.patch} | 0 .../0615-uapi-Add-IPPROTO_ETHERIP.patch | 11 - .../0616-net-Add-bond_is_mlo_device.patch | 32 -- ...f-cache-for-skb-data-for-LM-profiles.patch | 69 --- ...-Cache-for-skb-data-for-all-profiles.patch | 91 ---- ...0-0367-Generic-rx-to-rx-skb-recycler.patch | 207 --------- ...debug-track-functions-that-free-SKBs.patch | 51 --- ...ebug-objects-to-track-skb-allocation.patch | 126 ------ ...debug-move-activate-deactivate-sites.patch | 75 ---- ...track-alloc-and-free-complete-stacks.patch | 28 -- ...ug-track-sum-of-skb-while-not-in-use.patch | 29 -- .../9990-0376-Add-notifier-interface.patch | 116 ----- ...sk_buff-head-is-valid-in-consume_skb.patch | 51 --- ...-page-frag-allocations-for-SKB-for-2.patch | 69 --- ...cler-Add-a-cpustate-for-skb_recycler.patch | 25 -- ...ption-check-to-enable-skb-recycler-c.patch | 54 --- ...ompile-error-when-recycler-is-disabl.patch | 32 -- ...kb-while-dequeuing-from-backlog-list.patch | 31 -- ...kb-allocation-to-allocate-the-skbs-f.patch | 158 ------- ...he-crash-in-skbuff.c-for-debug-build.patch | 26 -- ...h-due-to-missing-skb-debug-deactivat.patch | 57 --- .../9990-1-qca-skb_recycler-support.patch | 424 ++++++++++++++++++ 28 files changed, 548 insertions(+), 1446 deletions(-) delete mode 100644 target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-netfilter-tcp_window_check.patch rename target/linux/qualcommax/patches-6.1/{0600-5-qca-nss-ecm-support-netfilter-DSCPREMARK.patch => 0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch} (100%) rename target/linux/qualcommax/patches-6.1/{0603-2-qca-nss-clients-add-iptunnel-support.patch => 0603-4-qca-nss-clients-add-iptunnel-support.patch} (100%) rename target/linux/qualcommax/patches-6.1/{0603-3-qca-nss-clients-add-vxlan-support.patch => 0603-5-qca-nss-clients-add-vxlan-support.patch} (100%) rename target/linux/qualcommax/patches-6.1/{0603-4-qca-nss-clients-iptunnel-lock-this-cpu.patch => 0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch} (100%) rename target/linux/qualcommax/patches-6.1/{0605-qca-nss-cfi-support.patch => 0605-1-qca-nss-cfi-support.patch} (100%) delete mode 100644 target/linux/qualcommax/patches-6.1/0615-uapi-Add-IPPROTO_ETHERIP.patch delete mode 100644 target/linux/qualcommax/patches-6.1/0616-net-Add-bond_is_mlo_device.patch delete mode 100644 target/linux/qualcommax/patches-6.1/9990-0272-net-skbuff-cache-for-skb-data-for-LM-profiles.patch delete mode 100644 target/linux/qualcommax/patches-6.1/9990-0273-net-skbuff-Cache-for-skb-data-for-all-profiles.patch delete mode 100644 target/linux/qualcommax/patches-6.1/9990-0367-Generic-rx-to-rx-skb-recycler.patch delete mode 100644 target/linux/qualcommax/patches-6.1/9990-0368-skbuff_debug-track-functions-that-free-SKBs.patch delete mode 100644 target/linux/qualcommax/patches-6.1/9990-0369-net-skbuff-use-debug-objects-to-track-skb-allocation.patch delete mode 100644 target/linux/qualcommax/patches-6.1/9990-0373-skbuff_debug-move-activate-deactivate-sites.patch delete mode 100644 target/linux/qualcommax/patches-6.1/9990-0374-skbuff_debug-track-alloc-and-free-complete-stacks.patch delete mode 100644 target/linux/qualcommax/patches-6.1/9990-0375-skbuff_debug-track-sum-of-skb-while-not-in-use.patch delete mode 100644 target/linux/qualcommax/patches-6.1/9990-0376-Add-notifier-interface.patch delete mode 100644 target/linux/qualcommax/patches-6.1/9990-0377-net-Check-if-sk_buff-head-is-valid-in-consume_skb.patch delete mode 100644 target/linux/qualcommax/patches-6.1/9990-0378-net-core-Disable-page-frag-allocations-for-SKB-for-2.patch delete mode 100644 target/linux/qualcommax/patches-6.1/9990-0379-skb_recycler-Add-a-cpustate-for-skb_recycler.patch delete mode 100644 target/linux/qualcommax/patches-6.1/9990-0422-net-Fix-kernel-option-check-to-enable-skb-recycler-c.patch delete mode 100644 target/linux/qualcommax/patches-6.1/9990-0429-net-skbuff-Fix-compile-error-when-recycler-is-disabl.patch delete mode 100644 target/linux/qualcommax/patches-6.1/9990-0444-net-prefetch-skb-while-dequeuing-from-backlog-list.patch delete mode 100644 target/linux/qualcommax/patches-6.1/9990-0498-skbuff-Fix-the-skb-allocation-to-allocate-the-skbs-f.patch delete mode 100644 target/linux/qualcommax/patches-6.1/9990-0527-net-Fix-the-crash-in-skbuff.c-for-debug-build.patch delete mode 100644 target/linux/qualcommax/patches-6.1/9990-0558-net-Fix-the-crash-due-to-missing-skb-debug-deactivat.patch create mode 100644 target/linux/qualcommax/patches-6.1/9990-1-qca-skb_recycler-support.patch diff --git a/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch b/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch index 8621227ab8c574..f6dcfe64f1b4d3 100644 --- a/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch +++ b/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch @@ -746,6 +746,46 @@ static inline unsigned short vxlan_get_sk_family(struct vxlan_sock *vs) { return vs->sock->sk->sk_family; +--- a/include/uapi/linux/in.h ++++ b/include/uapi/linux/in.h +@@ -63,6 +63,8 @@ enum { + #define IPPROTO_MTP IPPROTO_MTP + IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */ + #define IPPROTO_BEETPH IPPROTO_BEETPH ++ IPPROTO_ETHERIP = 97, /* ETHERIP protocol number */ ++#define IPPROTO_ETHERIP IPPROTO_ETHERIP + IPPROTO_ENCAP = 98, /* Encapsulation Header */ + #define IPPROTO_ENCAP IPPROTO_ENCAP + IPPROTO_PIM = 103, /* Protocol Independent Multicast */ +@@ -327,7 +329,7 @@ struct sockaddr_in { + #endif + + /* contains the htonl type stuff.. */ +-#include ++#include + + + #endif /* _UAPI_LINUX_IN_H */ +--- a/tools/include/uapi/linux/in.h ++++ b/tools/include/uapi/linux/in.h +@@ -63,6 +63,8 @@ enum { + #define IPPROTO_MTP IPPROTO_MTP + IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */ + #define IPPROTO_BEETPH IPPROTO_BEETPH ++ IPPROTO_ETHERIP = 97, /* ETHERIP protocol number */ ++#define IPPROTO_ETHERIP IPPROTO_ETHERIP + IPPROTO_ENCAP = 98, /* Encapsulation Header */ + #define IPPROTO_ENCAP IPPROTO_ENCAP + IPPROTO_PIM = 103, /* Protocol Independent Multicast */ +@@ -327,7 +329,7 @@ struct sockaddr_in { + #endif + + /* contains the htonl type stuff.. */ +-#include ++#include + + + #endif /* _UAPI_LINUX_IN_H */ --- a/net/netfilter/nf_conntrack_ecache.c +++ b/net/netfilter/nf_conntrack_ecache.c @@ -266,7 +266,6 @@ void nf_conntrack_register_notifier(stru @@ -756,3 +796,87 @@ rcu_assign_pointer(net->ct.nf_conntrack_event_cb, new); mutex_unlock(&nf_ct_ecache_mutex); } +--- a/include/net/netns/conntrack.h ++++ b/include/net/netns/conntrack.h +@@ -26,6 +26,7 @@ struct nf_tcp_net { + unsigned int timeouts[TCP_CONNTRACK_TIMEOUT_MAX]; + u8 tcp_loose; + u8 tcp_be_liberal; ++ u8 tcp_no_window_check; + u8 tcp_max_retrans; + u8 tcp_ignore_invalid_rst; + #if IS_ENABLED(CONFIG_NF_FLOW_TABLE) +diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c +index 3ac1af6f59fc..0a2badd52b54 100644 +--- a/net/netfilter/nf_conntrack_proto_tcp.c ++++ b/net/netfilter/nf_conntrack_proto_tcp.c +@@ -513,11 +513,15 @@ tcp_in_window(struct nf_conn *ct, enum ip_conntrack_dir dir, + struct ip_ct_tcp *state = &ct->proto.tcp; + struct ip_ct_tcp_state *sender = &state->seen[dir]; + struct ip_ct_tcp_state *receiver = &state->seen[!dir]; ++ const struct nf_tcp_net *tn = nf_tcp_pernet(nf_ct_net(ct)); + __u32 seq, ack, sack, end, win, swin; + bool in_recv_win, seq_ok; + s32 receiver_offset; + u16 win_raw; + ++ if (tn->tcp_no_window_check) ++ return NFCT_TCP_ACCEPT; ++ + /* + * Get the required data from the packet. + */ +@@ -1257,7 +1261,7 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct, + IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED && + timeouts[new_state] > timeouts[TCP_CONNTRACK_UNACK]) + timeout = timeouts[TCP_CONNTRACK_UNACK]; +- else if (ct->proto.tcp.last_win == 0 && ++ else if (!tn->tcp_no_window_check && ct->proto.tcp.last_win == 0 && + timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS]) + timeout = timeouts[TCP_CONNTRACK_RETRANS]; + else +@@ -1573,6 +1577,9 @@ void nf_conntrack_tcp_init_net(struct net *net) + */ + tn->tcp_be_liberal = 0; + ++ /* Skip Windows Check */ ++ tn->tcp_no_window_check = 0; ++ + /* If it's non-zero, we turn off RST sequence number check */ + tn->tcp_ignore_invalid_rst = 0; + +diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c +index e9654169b005..84b8e28f0782 100644 +--- a/net/netfilter/nf_conntrack_standalone.c ++++ b/net/netfilter/nf_conntrack_standalone.c +@@ -637,6 +637,7 @@ enum nf_ct_sysctl_index { + #endif + NF_SYSCTL_CT_PROTO_TCP_LOOSE, + NF_SYSCTL_CT_PROTO_TCP_LIBERAL, ++ NF_SYSCTL_CT_PROTO_TCP_NO_WINDOW_CHECK, + NF_SYSCTL_CT_PROTO_TCP_IGNORE_INVALID_RST, + NF_SYSCTL_CT_PROTO_TCP_MAX_RETRANS, + NF_SYSCTL_CT_PROTO_TIMEOUT_UDP, +@@ -844,6 +845,14 @@ static struct ctl_table nf_ct_sysctl_table[] = { + .extra1 = SYSCTL_ZERO, + .extra2 = SYSCTL_ONE, + }, ++ [NF_SYSCTL_CT_PROTO_TCP_NO_WINDOW_CHECK] = { ++ .procname = "nf_conntrack_tcp_no_window_check", ++ .maxlen = sizeof(u8), ++ .mode = 0644, ++ .proc_handler = proc_dou8vec_minmax, ++ .extra1 = SYSCTL_ZERO, ++ .extra2 = SYSCTL_ONE, ++ }, + [NF_SYSCTL_CT_PROTO_TCP_IGNORE_INVALID_RST] = { + .procname = "nf_conntrack_tcp_ignore_invalid_rst", + .maxlen = sizeof(u8), +@@ -1054,6 +1063,7 @@ static void nf_conntrack_standalone_init_tcp_sysctl(struct net *net, + + XASSIGN(LOOSE, &tn->tcp_loose); + XASSIGN(LIBERAL, &tn->tcp_be_liberal); ++ XASSIGN(NO_WINDOW_CHECK, &tn->tcp_no_window_check); + XASSIGN(MAX_RETRANS, &tn->tcp_max_retrans); + XASSIGN(IGNORE_INVALID_RST, &tn->tcp_ignore_invalid_rst); + #undef XASSIGN diff --git a/target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-netfilter-tcp_window_check.patch b/target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-netfilter-tcp_window_check.patch deleted file mode 100644 index 150853573d0116..00000000000000 --- a/target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-netfilter-tcp_window_check.patch +++ /dev/null @@ -1,108 +0,0 @@ -From ed42112c77bfb68594f49e252ace2dd6b8c8e7ff Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Thu, 16 Mar 2023 17:21:39 +0530 -Subject: [PATCH 063/281] OpenWrt: - 613-netfilter_optional_tcp_window_check.patch - -netfilter: optional tcp window check - -Signed-off-by: Felix Fietkau -Signed-off-by: Christian 'Ansuel' Marangi - -Change-Id: I6f7a23b89062cca58c87554e75ae32b0e2aa2831 -Signed-off-by: Ram Chandra Jangir ---- - include/net/netns/conntrack.h | 1 + - net/netfilter/nf_conntrack_proto_tcp.c | 9 ++++++++- - net/netfilter/nf_conntrack_standalone.c | 10 ++++++++++ - 3 files changed, 19 insertions(+), 1 deletion(-) - -diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h -index 1f463b3957c7..2af4f8d24282 100644 ---- a/include/net/netns/conntrack.h -+++ b/include/net/netns/conntrack.h -@@ -26,6 +26,7 @@ struct nf_tcp_net { - unsigned int timeouts[TCP_CONNTRACK_TIMEOUT_MAX]; - u8 tcp_loose; - u8 tcp_be_liberal; -+ u8 tcp_no_window_check; - u8 tcp_max_retrans; - u8 tcp_ignore_invalid_rst; - #if IS_ENABLED(CONFIG_NF_FLOW_TABLE) -diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c -index 3ac1af6f59fc..0a2badd52b54 100644 ---- a/net/netfilter/nf_conntrack_proto_tcp.c -+++ b/net/netfilter/nf_conntrack_proto_tcp.c -@@ -513,11 +513,15 @@ tcp_in_window(struct nf_conn *ct, enum ip_conntrack_dir dir, - struct ip_ct_tcp *state = &ct->proto.tcp; - struct ip_ct_tcp_state *sender = &state->seen[dir]; - struct ip_ct_tcp_state *receiver = &state->seen[!dir]; -+ const struct nf_tcp_net *tn = nf_tcp_pernet(nf_ct_net(ct)); - __u32 seq, ack, sack, end, win, swin; - bool in_recv_win, seq_ok; - s32 receiver_offset; - u16 win_raw; - -+ if (tn->tcp_no_window_check) -+ return NFCT_TCP_ACCEPT; -+ - /* - * Get the required data from the packet. - */ -@@ -1257,7 +1261,7 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct, - IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED && - timeouts[new_state] > timeouts[TCP_CONNTRACK_UNACK]) - timeout = timeouts[TCP_CONNTRACK_UNACK]; -- else if (ct->proto.tcp.last_win == 0 && -+ else if (!tn->tcp_no_window_check && ct->proto.tcp.last_win == 0 && - timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS]) - timeout = timeouts[TCP_CONNTRACK_RETRANS]; - else -@@ -1573,6 +1577,9 @@ void nf_conntrack_tcp_init_net(struct net *net) - */ - tn->tcp_be_liberal = 0; - -+ /* Skip Windows Check */ -+ tn->tcp_no_window_check = 0; -+ - /* If it's non-zero, we turn off RST sequence number check */ - tn->tcp_ignore_invalid_rst = 0; - -diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c -index e9654169b005..84b8e28f0782 100644 ---- a/net/netfilter/nf_conntrack_standalone.c -+++ b/net/netfilter/nf_conntrack_standalone.c -@@ -637,6 +637,7 @@ enum nf_ct_sysctl_index { - #endif - NF_SYSCTL_CT_PROTO_TCP_LOOSE, - NF_SYSCTL_CT_PROTO_TCP_LIBERAL, -+ NF_SYSCTL_CT_PROTO_TCP_NO_WINDOW_CHECK, - NF_SYSCTL_CT_PROTO_TCP_IGNORE_INVALID_RST, - NF_SYSCTL_CT_PROTO_TCP_MAX_RETRANS, - NF_SYSCTL_CT_PROTO_TIMEOUT_UDP, -@@ -844,6 +845,14 @@ static struct ctl_table nf_ct_sysctl_table[] = { - .extra1 = SYSCTL_ZERO, - .extra2 = SYSCTL_ONE, - }, -+ [NF_SYSCTL_CT_PROTO_TCP_NO_WINDOW_CHECK] = { -+ .procname = "nf_conntrack_tcp_no_window_check", -+ .maxlen = sizeof(u8), -+ .mode = 0644, -+ .proc_handler = proc_dou8vec_minmax, -+ .extra1 = SYSCTL_ZERO, -+ .extra2 = SYSCTL_ONE, -+ }, - [NF_SYSCTL_CT_PROTO_TCP_IGNORE_INVALID_RST] = { - .procname = "nf_conntrack_tcp_ignore_invalid_rst", - .maxlen = sizeof(u8), -@@ -1054,6 +1063,7 @@ static void nf_conntrack_standalone_init_tcp_sysctl(struct net *net, - - XASSIGN(LOOSE, &tn->tcp_loose); - XASSIGN(LIBERAL, &tn->tcp_be_liberal); -+ XASSIGN(NO_WINDOW_CHECK, &tn->tcp_no_window_check); - XASSIGN(MAX_RETRANS, &tn->tcp_max_retrans); - XASSIGN(IGNORE_INVALID_RST, &tn->tcp_ignore_invalid_rst); - #undef XASSIGN --- -2.17.1 - diff --git a/target/linux/qualcommax/patches-6.1/0600-5-qca-nss-ecm-support-netfilter-DSCPREMARK.patch b/target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch similarity index 100% rename from target/linux/qualcommax/patches-6.1/0600-5-qca-nss-ecm-support-netfilter-DSCPREMARK.patch rename to target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch diff --git a/target/linux/qualcommax/patches-6.1/0603-2-qca-nss-clients-add-iptunnel-support.patch b/target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-add-iptunnel-support.patch similarity index 100% rename from target/linux/qualcommax/patches-6.1/0603-2-qca-nss-clients-add-iptunnel-support.patch rename to target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-add-iptunnel-support.patch diff --git a/target/linux/qualcommax/patches-6.1/0603-3-qca-nss-clients-add-vxlan-support.patch b/target/linux/qualcommax/patches-6.1/0603-5-qca-nss-clients-add-vxlan-support.patch similarity index 100% rename from target/linux/qualcommax/patches-6.1/0603-3-qca-nss-clients-add-vxlan-support.patch rename to target/linux/qualcommax/patches-6.1/0603-5-qca-nss-clients-add-vxlan-support.patch diff --git a/target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-iptunnel-lock-this-cpu.patch b/target/linux/qualcommax/patches-6.1/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch similarity index 100% rename from target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-iptunnel-lock-this-cpu.patch rename to target/linux/qualcommax/patches-6.1/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch diff --git a/target/linux/qualcommax/patches-6.1/0605-qca-nss-cfi-support.patch b/target/linux/qualcommax/patches-6.1/0605-1-qca-nss-cfi-support.patch similarity index 100% rename from target/linux/qualcommax/patches-6.1/0605-qca-nss-cfi-support.patch rename to target/linux/qualcommax/patches-6.1/0605-1-qca-nss-cfi-support.patch diff --git a/target/linux/qualcommax/patches-6.1/0615-uapi-Add-IPPROTO_ETHERIP.patch b/target/linux/qualcommax/patches-6.1/0615-uapi-Add-IPPROTO_ETHERIP.patch deleted file mode 100644 index b058851cabe019..00000000000000 --- a/target/linux/qualcommax/patches-6.1/0615-uapi-Add-IPPROTO_ETHERIP.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/include/uapi/linux/in.h -+++ a/include/uapi/linux/in.h -@@ -63,6 +63,8 @@ - #define IPPROTO_MTP IPPROTO_MTP - IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */ - #define IPPROTO_BEETPH IPPROTO_BEETPH -+ IPPROTO_ETHERIP = 97, /* ETHERIP protocol number */ -+#define IPPROTO_ETHERIP IPPROTO_ETHERIP - IPPROTO_ENCAP = 98, /* Encapsulation Header */ - #define IPPROTO_ENCAP IPPROTO_ENCAP - IPPROTO_PIM = 103, /* Protocol Independent Multicast */ diff --git a/target/linux/qualcommax/patches-6.1/0616-net-Add-bond_is_mlo_device.patch b/target/linux/qualcommax/patches-6.1/0616-net-Add-bond_is_mlo_device.patch deleted file mode 100644 index 9f419fe9d21656..00000000000000 --- a/target/linux/qualcommax/patches-6.1/0616-net-Add-bond_is_mlo_device.patch +++ /dev/null @@ -1,32 +0,0 @@ ---- a/include/net/bonding.h -+++ a/include/net/bonding.h -@@ -287,6 +287,19 @@ - bool bond_sk_check(struct bonding *bond); - - /** -+ * Returns False if the net_device is not MLO bond netdvice -+ * -+ */ -+static inline bool bond_is_mlo_device(struct net_device *bond_dev) -+{ -+ struct bonding *bond = netdev_priv(bond_dev); -+ if (BOND_MODE(bond) == BOND_MODE_MLO) -+ return true; -+ -+ return false; -+} -+ -+/** - * Returns NULL if the net_device does not belong to any of the bond's slaves - * - * Caller must hold bond lock for read ---- a/include/uapi/linux/if_bonding.h -+++ a/include/uapi/linux/if_bonding.h -@@ -71,6 +71,7 @@ - #define BOND_MODE_8023AD 4 - #define BOND_MODE_TLB 5 - #define BOND_MODE_ALB 6 /* TLB + RLB (receive load balancing) */ -+#define BOND_MODE_MLO 7 /* MLO (Multi link) mode for Wi-Fi 7 AP links */ - - /* each slave's link has 4 states */ - #define BOND_LINK_UP 0 /* link is up and running */ diff --git a/target/linux/qualcommax/patches-6.1/9990-0272-net-skbuff-cache-for-skb-data-for-LM-profiles.patch b/target/linux/qualcommax/patches-6.1/9990-0272-net-skbuff-cache-for-skb-data-for-LM-profiles.patch deleted file mode 100644 index b3dd71696c8f40..00000000000000 --- a/target/linux/qualcommax/patches-6.1/9990-0272-net-skbuff-cache-for-skb-data-for-LM-profiles.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 35958c73762695bf64bd7e657c00e136cd8156ec Mon Sep 17 00:00:00 2001 -From: Kathiravan T -Date: Thu, 29 Apr 2021 16:29:02 +0530 -Subject: [PATCH 272/281] net: skbuff: cache for skb->data for LM profiles - -Signed-off-by: Kathiravan T -Change-Id: I7bcac8d05a11aa3d1a9e015d6530562ed81477a0 ---- - net/core/skbuff.c | 30 ++++++++++++++++++++++++++++-- - 1 file changed, 28 insertions(+), 2 deletions(-) - ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -84,6 +84,12 @@ - #include "dev.h" - #include "sock_destructor.h" - -+ -+#if defined(CONFIG_SKB_FIXED_SIZE_2K) && !defined(__LP64__) -+struct kmem_cache *skb_data_cache; -+#define SKB_DATA_CACHE_SIZE 2176 -+#endif -+ - struct kmem_cache *skbuff_head_cache __ro_after_init; - static struct kmem_cache *skbuff_fclone_cache __ro_after_init; - #ifdef CONFIG_SKB_EXTENSIONS -@@ -444,6 +450,13 @@ static void *kmalloc_reserve(unsigned in - * Try a regular allocation, when that fails and we're not entitled - * to the reserves, fail. - */ -+#if defined(CONFIG_SKB_FIXED_SIZE_2K) && !defined(__LP64__) -+ if (obj_size > SZ_2K && obj_size <= SKB_DATA_CACHE_SIZE) -+ obj = kmem_cache_alloc_node(skb_data_cache, -+ flags | __GFP_NOMEMALLOC | __GFP_NOWARN, -+ node); -+ else -+#endif - obj = kmalloc_node_track_caller(obj_size, - flags | __GFP_NOMEMALLOC | __GFP_NOWARN, - node); -@@ -452,7 +465,12 @@ static void *kmalloc_reserve(unsigned in - - /* Try again but now we are using pfmemalloc reserves */ - ret_pfmemalloc = true; -- obj = kmalloc_node_track_caller(obj_size, flags, node); -+#if defined(CONFIG_SKB_FIXED_SIZE_2K) && !defined(__LP64__) -+ if (obj_size > SZ_2K && obj_size <= SKB_DATA_CACHE_SIZE) -+ obj = kmem_cache_alloc_node(skb_data_cache, flags, node); -+ else -+#endif -+ obj = kmalloc_node_track_caller(obj_size, flags, node); - - out: - if (pfmemalloc) -@@ -4557,6 +4575,14 @@ static void skb_extensions_init(void) {} - - void __init skb_init(void) - { -+ -+#if defined(CONFIG_SKB_FIXED_SIZE_2K) && !defined(__LP64__) -+ skb_data_cache = kmem_cache_create_usercopy("skb_data_cache", -+ SKB_DATA_CACHE_SIZE, -+ 0, 0, 0, SKB_DATA_CACHE_SIZE, -+ NULL); -+#endif -+ - skbuff_head_cache = kmem_cache_create_usercopy("skbuff_head_cache", - sizeof(struct sk_buff), - 0, diff --git a/target/linux/qualcommax/patches-6.1/9990-0273-net-skbuff-Cache-for-skb-data-for-all-profiles.patch b/target/linux/qualcommax/patches-6.1/9990-0273-net-skbuff-Cache-for-skb-data-for-all-profiles.patch deleted file mode 100644 index 6d2cdc660d28d9..00000000000000 --- a/target/linux/qualcommax/patches-6.1/9990-0273-net-skbuff-Cache-for-skb-data-for-all-profiles.patch +++ /dev/null @@ -1,91 +0,0 @@ -From aef6fe6fba93af65b66354aa7ad463cf370723c0 Mon Sep 17 00:00:00 2001 -From: Sneha Maganahalli -Date: Fri, 4 Feb 2022 14:29:37 +0530 -Subject: [PATCH 273/281] net: skbuff: Cache for skb->data for all profiles. - -Cache for skb->data for all profiles. - -Change-Id: Ib84a1b0c037bc27febb24edbee91ffe6427d528d -Signed-off-by: Sneha Maganahalli ---- - net/core/skbuff.c | 34 +++++++++++++++++++++++----------- - 1 file changed, 23 insertions(+), 11 deletions(-) - ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -84,10 +84,29 @@ - #include "dev.h" - #include "sock_destructor.h" - -- --#if defined(CONFIG_SKB_FIXED_SIZE_2K) && !defined(__LP64__) - struct kmem_cache *skb_data_cache; --#define SKB_DATA_CACHE_SIZE 2176 -+ -+/* -+ * For low memory profile, NSS_SKB_FIXED_SIZE_2K is enabled and -+ * CONFIG_SKB_RECYCLER is disabled. For premium and enterprise profile -+ * CONFIG_SKB_RECYCLER is enabled and NSS_SKB_FIXED_SIZE_2K is disabled. -+ * Irrespective of NSS_SKB_FIXED_SIZE_2K enabled/disabled, the -+ * CONFIG_SKB_RECYCLER and __LP64__ determines the value of SKB_DATA_CACHE_SIZE -+ */ -+#if defined(CONFIG_SKB_RECYCLER) -+/* -+ * 2688 for 64bit arch, 2624 for 32bit arch -+ */ -+#define SKB_DATA_CACHE_SIZE (SKB_DATA_ALIGN(SKB_RECYCLE_SIZE + NET_SKB_PAD) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) -+#else -+/* -+ * 2368 for 64bit arch, 2176 for 32bit arch -+ */ -+#if defined(__LP64__) -+#define SKB_DATA_CACHE_SIZE ((SKB_DATA_ALIGN(1984 + NET_SKB_PAD)) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) -+#else -+#define SKB_DATA_CACHE_SIZE ((SKB_DATA_ALIGN(1856 + NET_SKB_PAD)) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) -+#endif - #endif - - struct kmem_cache *skbuff_head_cache __ro_after_init; -@@ -450,14 +469,12 @@ static void *kmalloc_reserve(unsigned in - * Try a regular allocation, when that fails and we're not entitled - * to the reserves, fail. - */ --#if defined(CONFIG_SKB_FIXED_SIZE_2K) && !defined(__LP64__) - if (obj_size > SZ_2K && obj_size <= SKB_DATA_CACHE_SIZE) - obj = kmem_cache_alloc_node(skb_data_cache, - flags | __GFP_NOMEMALLOC | __GFP_NOWARN, - node); - else --#endif -- obj = kmalloc_node_track_caller(obj_size, -+ obj = kmalloc_node_track_caller(obj_size, - flags | __GFP_NOMEMALLOC | __GFP_NOWARN, - node); - if (obj || !(gfp_pfmemalloc_allowed(flags))) -@@ -465,11 +482,9 @@ static void *kmalloc_reserve(unsigned in - - /* Try again but now we are using pfmemalloc reserves */ - ret_pfmemalloc = true; --#if defined(CONFIG_SKB_FIXED_SIZE_2K) && !defined(__LP64__) - if (obj_size > SZ_2K && obj_size <= SKB_DATA_CACHE_SIZE) - obj = kmem_cache_alloc_node(skb_data_cache, flags, node); - else --#endif - obj = kmalloc_node_track_caller(obj_size, flags, node); - - out: -@@ -4575,13 +4590,10 @@ static void skb_extensions_init(void) {} - - void __init skb_init(void) - { -- --#if defined(CONFIG_SKB_FIXED_SIZE_2K) && !defined(__LP64__) - skb_data_cache = kmem_cache_create_usercopy("skb_data_cache", - SKB_DATA_CACHE_SIZE, -- 0, 0, 0, SKB_DATA_CACHE_SIZE, -+ 0, SLAB_PANIC, 0, SKB_DATA_CACHE_SIZE, - NULL); --#endif - - skbuff_head_cache = kmem_cache_create_usercopy("skbuff_head_cache", - sizeof(struct sk_buff), diff --git a/target/linux/qualcommax/patches-6.1/9990-0367-Generic-rx-to-rx-skb-recycler.patch b/target/linux/qualcommax/patches-6.1/9990-0367-Generic-rx-to-rx-skb-recycler.patch deleted file mode 100644 index 223f5efda5092c..00000000000000 --- a/target/linux/qualcommax/patches-6.1/9990-0367-Generic-rx-to-rx-skb-recycler.patch +++ /dev/null @@ -1,207 +0,0 @@ -From 86479de8f60d947e6cef9decebe1b215ac428b21 Mon Sep 17 00:00:00 2001 -From: Tian Yang -Date: Mon, 13 Apr 2020 10:14:08 -0700 -Subject: [PATCH] Generic rx-to-rx skb recycler - -Porting from 3.4 kernel (banana branch). - -Removing kmemcheck header and the no longer valid cpuhotplug notifier function. - -Change-Id: Ie81a7d812ec14a40da8f22cf4e0f7ddaaf166cff -Signed-off-by: Varadarajan Narayanan -Signed-off-by: Pamidipati, Vijay -Signed-off-by: Casey Chen -Signed-off-by: Tian Yang ---- - MAINTAINERS | 5 ++++ - include/linux/skbuff.h | 2 ++ - net/Kconfig | 15 ++++++++++ - net/core/Makefile | 1 + - net/core/skbuff.c | 68 +++++++++++++++++++++++++++++++++++++----- - 5 files changed, 84 insertions(+), 7 deletions(-) - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -143,6 +143,11 @@ Maintainers List - first. When adding to this list, please keep the entries in - alphabetical order. - -+SKB RECYCLER SUPPORT -+M: Casey Chen -+S: Maintained -+F: net/core/skbuff_recycle.* -+ - 3C59X NETWORK DRIVER - M: Steffen Klassert - L: netdev@vger.kernel.org ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -1252,6 +1252,8 @@ static inline void consume_skb(struct sk - void __consume_stateless_skb(struct sk_buff *skb); - void __kfree_skb(struct sk_buff *skb); - extern struct kmem_cache *skbuff_head_cache; -+extern void kfree_skbmem(struct sk_buff *skb); -+extern void skb_release_data(struct sk_buff *skb); - - void kfree_skb_partial(struct sk_buff *skb, bool head_stolen); - bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from, ---- a/net/Kconfig -+++ b/net/Kconfig -@@ -332,6 +332,21 @@ config NET_FLOW_LIMIT - with many clients some protection against DoS by a single (spoofed) - flow that greatly exceeds average workload. - -+config SKB_RECYCLER -+ bool "Generic skb recycling" -+ default y -+ help -+ SKB_RECYCLER is used to implement RX-to-RX skb recycling. -+ This config enables the recycling scheme for bridging and -+ routing workloads. It can reduce skbuff freeing or -+ reallocation overhead. -+ -+ -+config SKB_RECYCLER_MULTI_CPU -+ bool "Cross-CPU recycling for CPU-locked workloads" -+ depends on SMP && SKB_RECYCLER -+ default n -+ - menu "Network testing" - - config NET_PKTGEN ---- a/net/core/Makefile -+++ b/net/core/Makefile -@@ -40,3 +40,4 @@ obj-$(CONFIG_NET_SOCK_MSG) += skmsg.o - obj-$(CONFIG_BPF_SYSCALL) += sock_map.o - obj-$(CONFIG_BPF_SYSCALL) += bpf_sk_storage.o - obj-$(CONFIG_OF) += of_net.o -+obj-$(CONFIG_SKB_RECYCLER) += skbuff_recycle.o ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -109,6 +109,8 @@ struct kmem_cache *skb_data_cache; - #endif - #endif - -+#include "skbuff_recycle.h" -+ - struct kmem_cache *skbuff_head_cache __ro_after_init; - static struct kmem_cache *skbuff_fclone_cache __ro_after_init; - #ifdef CONFIG_SKB_EXTENSIONS -@@ -584,7 +586,7 @@ EXPORT_SYMBOL(__alloc_skb); - /** - * __netdev_alloc_skb - allocate an skbuff for rx on a specific device - * @dev: network device to receive on -- * @len: length to allocate -+ * @length: length to allocate - * @gfp_mask: get_free_pages mask, passed to alloc_skb - * - * Allocate a new &sk_buff and assign it a usage count of one. The -@@ -594,11 +596,28 @@ EXPORT_SYMBOL(__alloc_skb); - * - * %NULL is returned if there is no free memory. - */ --struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int len, -- gfp_t gfp_mask) -+struct sk_buff *__netdev_alloc_skb(struct net_device *dev, -+ unsigned int length, gfp_t gfp_mask) - { -- struct page_frag_cache *nc; - struct sk_buff *skb; -+ unsigned int len = length; -+ -+#ifdef CONFIG_SKB_RECYCLER -+ skb = skb_recycler_alloc(dev, length); -+ if (likely(skb)) -+ return skb; -+ -+ len = SKB_RECYCLE_SIZE; -+ if (unlikely(length > SKB_RECYCLE_SIZE)) -+ len = length; -+ -+ skb = __alloc_skb(len + NET_SKB_PAD, gfp_mask, -+ SKB_ALLOC_RX, NUMA_NO_NODE); -+ if (!skb) -+ goto skb_fail; -+ goto skb_success; -+#else -+ struct page_frag_cache *nc; - bool pfmemalloc; - void *data; - -@@ -645,6 +664,7 @@ struct sk_buff *__netdev_alloc_skb(struc - if (pfmemalloc) - skb->pfmemalloc = 1; - skb->head_frag = 1; -+#endif - - skb_success: - skb_reserve(skb, NET_SKB_PAD); -@@ -813,7 +833,7 @@ static void skb_free_head(struct sk_buff - } - } - --static void skb_release_data(struct sk_buff *skb) -+void skb_release_data(struct sk_buff *skb) - { - struct skb_shared_info *shinfo = skb_shinfo(skb); - int i; -@@ -855,7 +875,7 @@ exit: - /* - * Free an skbuff by memory without cleaning the state. - */ --static void kfree_skbmem(struct sk_buff *skb) -+void kfree_skbmem(struct sk_buff *skb) - { - struct sk_buff_fclones *fclones; - -@@ -1081,8 +1101,41 @@ void consume_skb(struct sk_buff *skb) - if (!skb_unref(skb)) - return; - -+ prefetch(&skb->destructor); -+ -+ /*Tian: Not sure if we need to continue using this since -+ * since unref does the work in 5.4 -+ */ -+ -+ /* -+ if (likely(atomic_read(&skb->users) == 1)) -+ smp_rmb(); -+ else if (likely(!atomic_dec_and_test(&skb->users))) -+ return; -+ */ -+ -+ /* If possible we'd like to recycle any skb rather than just free it, -+ * but in order to do that we need to release any head state too. -+ * We don't want to do this later because we'll be in a pre-emption -+ * disabled state. -+ */ -+ skb_release_head_state(skb); -+ -+ /* Can we recycle this skb? If we can then it will be much faster -+ * for us to recycle this one later than to allocate a new one -+ * from scratch. -+ */ -+ if (likely(skb_recycler_consume(skb))) -+ return; -+ - trace_consume_skb(skb); -- __kfree_skb(skb); -+ -+ /* We're not recycling so now we need to do the rest of what we would -+ * have done in __kfree_skb (above and beyond the skb_release_head_state -+ * that we already did). -+ */ -+ skb_release_data(skb); -+ kfree_skbmem(skb); - } - EXPORT_SYMBOL(consume_skb); - #endif -@@ -4608,6 +4661,7 @@ void __init skb_init(void) - SLAB_HWCACHE_ALIGN|SLAB_PANIC, - NULL); - skb_extensions_init(); -+ skb_recycler_init(); - } - - static int diff --git a/target/linux/qualcommax/patches-6.1/9990-0368-skbuff_debug-track-functions-that-free-SKBs.patch b/target/linux/qualcommax/patches-6.1/9990-0368-skbuff_debug-track-functions-that-free-SKBs.patch deleted file mode 100644 index 4f66fd49baad38..00000000000000 --- a/target/linux/qualcommax/patches-6.1/9990-0368-skbuff_debug-track-functions-that-free-SKBs.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 9a3850e377ff8b567d7edeb64cf7b6d6eda817f2 Mon Sep 17 00:00:00 2001 -From: Tian Yang -Date: Thu, 1 Oct 2015 16:31:33 -0500 -Subject: [PATCH] skbuff_debug: track functions that free SKBs - -This adds a member to struct skbuff if -CONFIG_DEBUG_OBJECTS_SKBUFF is turned on that tracks -the caller that last free'd the SKB. - -This should work for SLAB and SKB recycler free since this -element of the SKB should not get overwritten when allocated -from either pool of objects. - -Performance info for before/after: - -Before: - - speed was 53.45 Mbit/s - cycles = 97974050028 (per pkt = 35368.7482818) - instructions = 26722549696 (per pkt = 9646.87213988) - dcache_misses = 512380452 (per pkt = 184.969950983) - icache_misses = 1268005369 (per pkt = 457.75144238) - -After: - - speed was 48.91 Mbit/s - cycles = 98737753294 (per pkt = 38614.9009095) - instructions = 25770915740 (per pkt = 10078.6307613) - dcache_misses = 589106068 (per pkt = 230.39082501) - icache_misses = 1146428790 (per pkt = 448.351645128) - -Change-Id: Ie9e854015dc040fc30b97f89dd0663601b8f0344 -Signed-off-by: Matthew McClintock -Signed-off-by: Casey Chen ---- - include/linux/skbuff.h | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -1062,6 +1062,10 @@ struct sk_buff { - /* only useable after checking ->active_extensions != 0 */ - struct skb_ext *extensions; - #endif -+ -+#ifdef CONFIG_DEBUG_OBJECTS_SKBUFF -+ void *free_addr; -+#endif - }; - - /* if you move pkt_type around you also must adapt those constants */ diff --git a/target/linux/qualcommax/patches-6.1/9990-0369-net-skbuff-use-debug-objects-to-track-skb-allocation.patch b/target/linux/qualcommax/patches-6.1/9990-0369-net-skbuff-use-debug-objects-to-track-skb-allocation.patch deleted file mode 100644 index bb8f11101aadab..00000000000000 --- a/target/linux/qualcommax/patches-6.1/9990-0369-net-skbuff-use-debug-objects-to-track-skb-allocation.patch +++ /dev/null @@ -1,126 +0,0 @@ -From d30297828bd54324ca19412ae8097d878319556b Mon Sep 17 00:00:00 2001 -From: Tian Yang -Date: Mon, 21 Sep 2015 18:50:13 -0500 -Subject: [PATCH] net: skbuff: use debug objects to track skb allocations - -* tracks skb allocations and frees and warns / errors if - re-use occurs -* init/destroy for slab allocations -* activate/deactivate for in use - -Change-Id: Ia2dd0c7549d765a282295daf27bee6f99e5c7a43 -Signed-off-by: Matthew McClintock -Signed-off-by: Casey Chen -Signed-off-by: Tian Yang ---- - MAINTAINERS | 1 + - lib/Kconfig.debug | 6 ++++++ - net/core/Makefile | 1 + - net/core/dev.c | 1 + - net/core/skbuff.c | 9 ++++++++- - 5 files changed, 17 insertions(+), 1 deletion(-) - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -147,6 +147,7 @@ SKB RECYCLER SUPPORT - M: Casey Chen - S: Maintained - F: net/core/skbuff_recycle.* -+F: net/core/skbuff_debug.* - - 3C59X NETWORK DRIVER - M: Steffen Klassert ---- a/lib/Kconfig.debug -+++ b/lib/Kconfig.debug -@@ -710,6 +710,12 @@ config DEBUG_OBJECTS_PERCPU_COUNTER - percpu counter routines to track the life time of percpu counter - objects and validate the percpu counter operations. - -+config DEBUG_OBJECTS_SKBUFF -+ bool "Debug sk_buff allocations" -+ depends on DEBUG_OBJECTS -+ help -+ Enable this to turn on debugging of sk_buff's (incl. recycler) -+ - config DEBUG_OBJECTS_ENABLE_DEFAULT - int "debug_objects bootup default value (0-1)" - range 0 1 ---- a/net/core/Makefile -+++ b/net/core/Makefile -@@ -41,3 +41,4 @@ obj-$(CONFIG_BPF_SYSCALL) += sock_map.o - obj-$(CONFIG_BPF_SYSCALL) += bpf_sk_storage.o - obj-$(CONFIG_OF) += of_net.o - obj-$(CONFIG_SKB_RECYCLER) += skbuff_recycle.o -+obj-$(CONFIG_DEBUG_OBJECTS_SKBUFF) += skbuff_debug.o ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -153,6 +153,7 @@ - - #include "dev.h" - #include "net-sysfs.h" -+#include "skbuff_debug.h" - - - static DEFINE_SPINLOCK(ptype_lock); ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -110,6 +110,7 @@ struct kmem_cache *skb_data_cache; - #endif - - #include "skbuff_recycle.h" -+#include "skbuff_debug.h" - - struct kmem_cache *skbuff_head_cache __ro_after_init; - static struct kmem_cache *skbuff_fclone_cache __ro_after_init; -@@ -320,8 +321,8 @@ static void __build_skb_around(struct sk - shinfo = skb_shinfo(skb); - memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); - atomic_set(&shinfo->dataref, 1); -- - skb_set_kcov_handle(skb, kcov_common_handle()); -+ skbuff_debugobj_init_and_activate(skb); - } - - /** -@@ -575,6 +576,7 @@ struct sk_buff *__alloc_skb(unsigned int - refcount_set(&fclones->fclone_ref, 1); - } - -+ skbuff_debugobj_init_and_activate(skb); - return skb; - - nodata: -@@ -881,6 +883,7 @@ void kfree_skbmem(struct sk_buff *skb) - - switch (skb->fclone) { - case SKB_FCLONE_UNAVAILABLE: -+ skbuff_debugobj_deactivate(skb); - kmem_cache_free(skbuff_head_cache, skb); - return; - -@@ -901,7 +904,9 @@ void kfree_skbmem(struct sk_buff *skb) - } - if (!refcount_dec_and_test(&fclones->fclone_ref)) - return; -+ - fastpath: -+ skbuff_debugobj_deactivate(&fclones->skb1); - kmem_cache_free(skbuff_fclone_cache, fclones); - } - -@@ -1765,6 +1770,7 @@ struct sk_buff *skb_clone(struct sk_buff - return NULL; - - n->fclone = SKB_FCLONE_UNAVAILABLE; -+ skbuff_debugobj_init_and_activate(n); - } - - return __skb_clone(n, skb); -@@ -5523,6 +5529,7 @@ void kfree_skb_partial(struct sk_buff *s - if (head_stolen) { - skb_release_head_state(skb); - kmem_cache_free(skbuff_head_cache, skb); -+ skbuff_debugobj_deactivate(skb); - } else { - __kfree_skb(skb); - } diff --git a/target/linux/qualcommax/patches-6.1/9990-0373-skbuff_debug-move-activate-deactivate-sites.patch b/target/linux/qualcommax/patches-6.1/9990-0373-skbuff_debug-move-activate-deactivate-sites.patch deleted file mode 100644 index 3617ae55bc1cbc..00000000000000 --- a/target/linux/qualcommax/patches-6.1/9990-0373-skbuff_debug-move-activate-deactivate-sites.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 73886237a0742a19bb0630820829972c39c1e80e Mon Sep 17 00:00:00 2001 -From: Tian Yang -Date: Tue, 29 Dec 2015 13:02:21 -0600 -Subject: [PATCH] skbuff_debug: move activate/deactivate sites - -This way we can see if next/prev in SKB was changed -while the SKB was not being used. - -Change-Id: I281267e230d3406181a07d095a76ae6bc58e2c8d -Signed-off-by: Matthew McClintock -Signed-off-by: Casey Chen -Signed-off-by: Tian Yang ---- - net/core/skbuff.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -322,7 +322,6 @@ static void __build_skb_around(struct sk - memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); - atomic_set(&shinfo->dataref, 1); - skb_set_kcov_handle(skb, kcov_common_handle()); -- skbuff_debugobj_init_and_activate(skb); - } - - /** -@@ -351,6 +350,7 @@ struct sk_buff *__build_skb(void *data, - skb = kmem_cache_alloc(skbuff_head_cache, GFP_ATOMIC); - if (unlikely(!skb)) - return NULL; -+ skbuff_debugobj_init_and_activate(skb); - - memset(skb, 0, offsetof(struct sk_buff, tail)); - __build_skb_around(skb, data, frag_size); -@@ -542,6 +542,7 @@ struct sk_buff *__alloc_skb(unsigned int - skb = kmem_cache_alloc_node(cache, gfp_mask & ~GFP_DMA, node); - if (unlikely(!skb)) - return NULL; -+ skbuff_debugobj_init_and_activate(skb); - prefetchw(skb); - - /* We do our best to align skb_shared_info on a separate cache -@@ -576,10 +577,10 @@ struct sk_buff *__alloc_skb(unsigned int - refcount_set(&fclones->fclone_ref, 1); - } - -- skbuff_debugobj_init_and_activate(skb); - return skb; - - nodata: -+ skbuff_debugobj_deactivate(skb); - kmem_cache_free(cache, skb); - return NULL; - } -@@ -1768,9 +1769,9 @@ struct sk_buff *skb_clone(struct sk_buff - n = kmem_cache_alloc(skbuff_head_cache, gfp_mask); - if (!n) - return NULL; -+ skbuff_debugobj_init_and_activate(n); - - n->fclone = SKB_FCLONE_UNAVAILABLE; -- skbuff_debugobj_init_and_activate(n); - } - - return __skb_clone(n, skb); -@@ -5528,8 +5529,8 @@ void kfree_skb_partial(struct sk_buff *s - { - if (head_stolen) { - skb_release_head_state(skb); -- kmem_cache_free(skbuff_head_cache, skb); - skbuff_debugobj_deactivate(skb); -+ kmem_cache_free(skbuff_head_cache, skb); - } else { - __kfree_skb(skb); - } diff --git a/target/linux/qualcommax/patches-6.1/9990-0374-skbuff_debug-track-alloc-and-free-complete-stacks.patch b/target/linux/qualcommax/patches-6.1/9990-0374-skbuff_debug-track-alloc-and-free-complete-stacks.patch deleted file mode 100644 index d6cc5e4c87278e..00000000000000 --- a/target/linux/qualcommax/patches-6.1/9990-0374-skbuff_debug-track-alloc-and-free-complete-stacks.patch +++ /dev/null @@ -1,28 +0,0 @@ -From a7e6e645b640ed82ce6d6b2101e36694d5ef8cb3 Mon Sep 17 00:00:00 2001 -From: Tian Yang -Date: Tue, 29 Dec 2015 14:04:41 -0600 -Subject: [PATCH] skbuff_debug: track alloc and free complete stacks - -This adds support to record a complete stack trace for all -alloc's and free's of SKBs. - -Change-Id: I81fc76240d49d18035e99c234abcb8e4b9cb14a5 -Signed-off-by: Matthew McClintock -Signed-off-by: Casey Chen ---- - include/linux/skbuff.h | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -1064,7 +1064,9 @@ struct sk_buff { - #endif - - #ifdef CONFIG_DEBUG_OBJECTS_SKBUFF -- void *free_addr; -+#define DEBUG_OBJECTS_SKBUFF_STACKSIZE 20 -+ void *free_addr[DEBUG_OBJECTS_SKBUFF_STACKSIZE]; -+ void *alloc_addr[DEBUG_OBJECTS_SKBUFF_STACKSIZE]; - #endif - }; - diff --git a/target/linux/qualcommax/patches-6.1/9990-0375-skbuff_debug-track-sum-of-skb-while-not-in-use.patch b/target/linux/qualcommax/patches-6.1/9990-0375-skbuff_debug-track-sum-of-skb-while-not-in-use.patch deleted file mode 100644 index f035bbf3e5c4f3..00000000000000 --- a/target/linux/qualcommax/patches-6.1/9990-0375-skbuff_debug-track-sum-of-skb-while-not-in-use.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 1e47f8144d8ff9954e693efa87cf8cc015c28bd2 Mon Sep 17 00:00:00 2001 -From: Tian Yang -Date: Tue, 29 Dec 2015 15:20:54 -0600 -Subject: [PATCH] skbuff_debug: track sum of skb while not in use - -Add a simple sum check across the range of the SKB struct -to see if something else modified after it was freed to the -SKB recycler. - -Right now, we just check for the SKB recycler as freeing to -the slab tends to let other changes to the struct occur. - -Change-Id: I41b4163bf735cc047dd7150cb009098665c9b94e -Signed-off-by: Matthew McClintock -Signed-off-by: Casey Chen ---- - include/linux/skbuff.h | 1 + - 1 file changed, 1 insertion(+) - ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -1067,6 +1067,7 @@ struct sk_buff { - #define DEBUG_OBJECTS_SKBUFF_STACKSIZE 20 - void *free_addr[DEBUG_OBJECTS_SKBUFF_STACKSIZE]; - void *alloc_addr[DEBUG_OBJECTS_SKBUFF_STACKSIZE]; -+ u32 sum; - #endif - }; - diff --git a/target/linux/qualcommax/patches-6.1/9990-0376-Add-notifier-interface.patch b/target/linux/qualcommax/patches-6.1/9990-0376-Add-notifier-interface.patch deleted file mode 100644 index cd3b81777e15ad..00000000000000 --- a/target/linux/qualcommax/patches-6.1/9990-0376-Add-notifier-interface.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 1d79518dee2de6f5ad72c13bd291077e3a06acbf Mon Sep 17 00:00:00 2001 -From: Tian Yang -Date: Thu, 27 Oct 2016 11:46:24 -0500 -Subject: [PATCH] Add notifier interface - -Add a notifier interface for the SKB recycler. This notifier will -propagate events related to skb problems (double free, double alloc, -checksum mismatch). - -The following change is merged together: - - Don't call BUG_ON in the notifier - - The notifier was meant to be terminal, i.e. after propagating the - event it stops the system. - This is causing confusion however, under the assumption that there is - an actual problem in the notifier code. - - This commit removes the BUG_ON call in the notifier, so that the event - originator gets to stop the system (as it was done before the notifier - was introduced). - - Change Id: I5a7af0374dc4991539d742712331de03aa3833d1 - Author and Committer: Cristian Prundeanu - -Change-Id: I35262581ad964ef97d21946a965170531ca9034f -Signed-off-by: Cristian Prundeanu -Signed-off-by: Casey Chen -Signed-off-by: Tian Yang ---- - MAINTAINERS | 1 + - include/linux/debugobjects.h | 14 ++++++++------ - lib/debugobjects.c | 23 +++++++++++++++++++++++ - net/core/Makefile | 2 +- - 4 files changed, 33 insertions(+), 7 deletions(-) - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -148,6 +148,7 @@ M: Casey Chen - S: Maintained - F: net/core/skbuff_recycle.* - F: net/core/skbuff_debug.* -+F: net/core/skbuff_notifier.* - - 3C59X NETWORK DRIVER - M: Steffen Klassert ---- a/include/linux/debugobjects.h -+++ b/include/linux/debugobjects.h -@@ -66,12 +66,13 @@ struct debug_obj_descr { - #ifdef CONFIG_DEBUG_OBJECTS - extern void debug_object_init (void *addr, const struct debug_obj_descr *descr); - extern void --debug_object_init_on_stack(void *addr, const struct debug_obj_descr *descr); --extern int debug_object_activate (void *addr, const struct debug_obj_descr *descr); --extern void debug_object_deactivate(void *addr, const struct debug_obj_descr *descr); --extern void debug_object_destroy (void *addr, const struct debug_obj_descr *descr); --extern void debug_object_free (void *addr, const struct debug_obj_descr *descr); --extern void debug_object_assert_init(void *addr, const struct debug_obj_descr *descr); -+debug_object_init_on_stack(void *addr, struct debug_obj_descr *descr); -+extern int debug_object_activate (void *addr, struct debug_obj_descr *descr); -+extern int debug_object_get_state(void *addr); -+extern void debug_object_deactivate(void *addr, struct debug_obj_descr *descr); -+extern void debug_object_destroy (void *addr, struct debug_obj_descr *descr); -+extern void debug_object_free (void *addr, struct debug_obj_descr *descr); -+extern void debug_object_assert_init(void *addr, struct debug_obj_descr *descr); - - /* - * Active state: -@@ -85,6 +86,7 @@ debug_object_active_state(void *addr, co - extern void debug_objects_early_init(void); - extern void debug_objects_mem_init(void); - #else -+static inline int debug_object_get_state(void *addr) { return 0; } - static inline void - debug_object_init (void *addr, const struct debug_obj_descr *descr) { } - static inline void ---- a/lib/debugobjects.c -+++ b/lib/debugobjects.c -@@ -493,6 +493,29 @@ static struct debug_bucket *get_bucket(u - return &obj_hash[hash]; - } - -+/* -+ * debug_object_get_state(): -+ * returns the state of an object given an address -+ */ -+int debug_object_get_state(void *addr) -+{ -+ struct debug_bucket *db; -+ struct debug_obj *obj; -+ unsigned long flags; -+ enum debug_obj_state state = ODEBUG_STATE_NOTAVAILABLE; -+ -+ db = get_bucket((unsigned long) addr); -+ -+ raw_spin_lock_irqsave(&db->lock, flags); -+ obj = lookup_object(addr, db); -+ if (obj) -+ state = obj->state; -+ raw_spin_unlock_irqrestore(&db->lock, flags); -+ -+ return state; -+} -+EXPORT_SYMBOL(debug_object_get_state); -+ - static void debug_print_object(struct debug_obj *obj, char *msg) - { - const struct debug_obj_descr *descr = obj->descr; ---- a/net/core/Makefile -+++ b/net/core/Makefile -@@ -41,4 +41,4 @@ obj-$(CONFIG_BPF_SYSCALL) += sock_map.o - obj-$(CONFIG_BPF_SYSCALL) += bpf_sk_storage.o - obj-$(CONFIG_OF) += of_net.o - obj-$(CONFIG_SKB_RECYCLER) += skbuff_recycle.o --obj-$(CONFIG_DEBUG_OBJECTS_SKBUFF) += skbuff_debug.o -+obj-$(CONFIG_DEBUG_OBJECTS_SKBUFF) += skbuff_debug.o skbuff_notifier.o diff --git a/target/linux/qualcommax/patches-6.1/9990-0377-net-Check-if-sk_buff-head-is-valid-in-consume_skb.patch b/target/linux/qualcommax/patches-6.1/9990-0377-net-Check-if-sk_buff-head-is-valid-in-consume_skb.patch deleted file mode 100644 index d12ccba300bff7..00000000000000 --- a/target/linux/qualcommax/patches-6.1/9990-0377-net-Check-if-sk_buff-head-is-valid-in-consume_skb.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 7913da3088d10013c5e447547cc247b4d126ed73 Mon Sep 17 00:00:00 2001 -From: Vivek Nataraja -Date: Mon, 29 Jun 2015 11:31:50 +0530 -Subject: [PATCH] net: Check if sk_buff head is valid in consume_skb() - -Commit (0ebd0ac net: add function to allocate sk_buff head -without data area) changes skb_release_all() to check if the -skb has a data area to allow the skb destructor to clear the -data pointer in case only a head has been allocated. - -This was later fixed to check skb->head instead of skb->data -in 'commit 5e71d9d77c07 ("net: fix sk_buff head without data area")'. -as skb->head points to the beginning of the data area. - -Since, this was done only in kfree_skb path and not in consume_skb -path, this leads to kernel panic in some cases. - -Also, since skb_shared_info is not initialized in such skbs, -accessing that in skb_recycler_consume() leads to kernel panic. - -Fix this by checking if skb->head is valid in both the cases. - -Change-Id: Iad9fcbaa91f5f1d1b8b00b88ae279b52db385f0c -Signed-off-by: Vivek Nataraja -Signed-off-by: Casey Chen ---- - net/core/skbuff.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -1131,7 +1131,7 @@ void consume_skb(struct sk_buff *skb) - * for us to recycle this one later than to allocate a new one - * from scratch. - */ -- if (likely(skb_recycler_consume(skb))) -+ if (likely(skb->head) && likely(skb_recycler_consume(skb))) - return; - - trace_consume_skb(skb); -@@ -1140,7 +1140,9 @@ void consume_skb(struct sk_buff *skb) - * have done in __kfree_skb (above and beyond the skb_release_head_state - * that we already did). - */ -- skb_release_data(skb); -+ if (likely(skb->head)) -+ skb_release_data(skb); -+ - kfree_skbmem(skb); - } - EXPORT_SYMBOL(consume_skb); diff --git a/target/linux/qualcommax/patches-6.1/9990-0378-net-core-Disable-page-frag-allocations-for-SKB-for-2.patch b/target/linux/qualcommax/patches-6.1/9990-0378-net-core-Disable-page-frag-allocations-for-SKB-for-2.patch deleted file mode 100644 index 665877a3d6d685..00000000000000 --- a/target/linux/qualcommax/patches-6.1/9990-0378-net-core-Disable-page-frag-allocations-for-SKB-for-2.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 0d2da79c9c91c3ecd79feeafbab850eacd26a43e Mon Sep 17 00:00:00 2001 -From: Tian Yang -Date: Tue, 30 Apr 2019 18:43:02 +0530 -Subject: [PATCH] net core: Disable page frag allocations for SKB for 256MB - profile - -For low memory profiles such as 256MB, using __alloc_page_frag() -for skb allocations can potentially cause pages to be held up -for longer duration without getting freed by the kernel memory -manageer. This can potentially cause out-of-memory situaions. -This patch disabled page frag based SKB allocations for such -low memory profiles. - -Change-Id: Ibc674ad8b46211b8394f0bf7db55366d7210bb01 -Signed-off-by: Adil irfan -Signed-off-by: Kiran Kumar C.S.K ---- - net/Kconfig | 8 +++++++- - net/core/skbuff.c | 8 +++++++- - 2 files changed, 14 insertions(+), 2 deletions(-) - ---- a/net/Kconfig -+++ b/net/Kconfig -@@ -341,12 +341,18 @@ config SKB_RECYCLER - routing workloads. It can reduce skbuff freeing or - reallocation overhead. - -- - config SKB_RECYCLER_MULTI_CPU - bool "Cross-CPU recycling for CPU-locked workloads" - depends on SMP && SKB_RECYCLER - default n - -+config ALLOC_SKB_PAGE_FRAG_DISABLE -+ bool "Disable page fragment based skbuff payload allocations" -+ depends on !SKB_RECYCLER -+ default n -+ help -+ Disable page fragment based allocations for skbuff payloads. -+ - menu "Network testing" - - config NET_PKTGEN ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -622,16 +622,22 @@ struct sk_buff *__netdev_alloc_skb(struc - #else - struct page_frag_cache *nc; - bool pfmemalloc; -+ bool page_frag_alloc_enable = true; - void *data; - - len += NET_SKB_PAD; - -+ -+#ifdef CONFIG_ALLOC_SKB_PAGE_FRAG_DISABLE -+ page_frag_alloc_enable = false; -+#endif - /* If requested length is either too small or too big, - * we use kmalloc() for skb->head allocation. - */ - if (len <= SKB_WITH_OVERHEAD(1024) || - len > SKB_WITH_OVERHEAD(PAGE_SIZE) || -- (gfp_mask & (__GFP_DIRECT_RECLAIM | GFP_DMA))) { -+ (gfp_mask & (__GFP_DIRECT_RECLAIM | GFP_DMA)) || -+ !page_frag_alloc_enable) { - skb = __alloc_skb(len, gfp_mask, SKB_ALLOC_RX, NUMA_NO_NODE); - if (!skb) - goto skb_fail; diff --git a/target/linux/qualcommax/patches-6.1/9990-0379-skb_recycler-Add-a-cpustate-for-skb_recycler.patch b/target/linux/qualcommax/patches-6.1/9990-0379-skb_recycler-Add-a-cpustate-for-skb_recycler.patch deleted file mode 100644 index ae4c22ef01acac..00000000000000 --- a/target/linux/qualcommax/patches-6.1/9990-0379-skb_recycler-Add-a-cpustate-for-skb_recycler.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 3b5e3bb21a496d03739aa44b3a860db37c96321c Mon Sep 17 00:00:00 2001 -From: Tian Yang -Date: Wed, 29 Jul 2020 17:39:28 -0700 -Subject: [PATCH] skb_recycler: Add a cpustate for skb_recycler - -Add one cpu hotplug state for skb_recycler, called CPUHP_SKB_RECYCLER_DEAD -to avoid using NET_DEV state, this solves a warning calltrace issue from net_dev -since it cannot register its NET_DEV_CPU_DEAD callback during its initialization. - -Signed-off-by: Tian Yang -Change-Id: I6f5729ee300248ade42317114847959fda42dd20 ---- - include/linux/cpuhotplug.h | 1 + - 1 file changed, 1 insertion(+) - ---- a/include/linux/cpuhotplug.h -+++ b/include/linux/cpuhotplug.h -@@ -94,6 +94,7 @@ enum cpuhp_state { - CPUHP_RADIX_DEAD, - CPUHP_PAGE_ALLOC, - CPUHP_NET_DEV_DEAD, -+ CPUHP_SKB_RECYCLER_DEAD, - CPUHP_PCI_XGENE_DEAD, - CPUHP_IOMMU_IOVA_DEAD, - CPUHP_LUSTRE_CFS_DEAD, diff --git a/target/linux/qualcommax/patches-6.1/9990-0422-net-Fix-kernel-option-check-to-enable-skb-recycler-c.patch b/target/linux/qualcommax/patches-6.1/9990-0422-net-Fix-kernel-option-check-to-enable-skb-recycler-c.patch deleted file mode 100644 index b21a4c7b818013..00000000000000 --- a/target/linux/qualcommax/patches-6.1/9990-0422-net-Fix-kernel-option-check-to-enable-skb-recycler-c.patch +++ /dev/null @@ -1,54 +0,0 @@ -From cd9333020eac302df781f2e7dd715cd9b10aff0a Mon Sep 17 00:00:00 2001 -From: Swati Singh -Date: Tue, 22 Aug 2023 17:39:12 +0530 -Subject: [PATCH] net: Fix kernel option check to enable skb recycler code - -Use CONFIG_SKB_RECYCLER instead of CONFIG_TRACEPOINTS. - -Change-Id: Iad2d11ec90a305f8b170a15c7addb4d3e031adc3 -Signed-off-by: Swati Singh ---- - include/linux/skbuff.h | 2 +- - net/core/skbuff.c | 5 ++--- - 2 files changed, 3 insertions(+), 4 deletions(-) - ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -1247,7 +1247,7 @@ static inline void kfree_skb_list(struct - kfree_skb_list_reason(segs, SKB_DROP_REASON_NOT_SPECIFIED); - } - --#ifdef CONFIG_TRACEPOINTS -+#ifdef CONFIG_SKB_RECYCLER - void consume_skb(struct sk_buff *skb); - #else - static inline void consume_skb(struct sk_buff *skb) ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -1099,7 +1099,6 @@ void skb_tx_error(struct sk_buff *skb) - } - EXPORT_SYMBOL(skb_tx_error); - --#ifdef CONFIG_TRACEPOINTS - /** - * consume_skb - free an skbuff - * @skb: buffer to free -@@ -1140,8 +1139,9 @@ void consume_skb(struct sk_buff *skb) - if (likely(skb->head) && likely(skb_recycler_consume(skb))) - return; - -+#ifdef CONFIG_TRACEPOINTS - trace_consume_skb(skb); -- -+#endif - /* We're not recycling so now we need to do the rest of what we would - * have done in __kfree_skb (above and beyond the skb_release_head_state - * that we already did). -@@ -1152,7 +1152,6 @@ void consume_skb(struct sk_buff *skb) - kfree_skbmem(skb); - } - EXPORT_SYMBOL(consume_skb); --#endif - - /** - * __consume_stateless_skb - free an skbuff, assuming it is stateless diff --git a/target/linux/qualcommax/patches-6.1/9990-0429-net-skbuff-Fix-compile-error-when-recycler-is-disabl.patch b/target/linux/qualcommax/patches-6.1/9990-0429-net-skbuff-Fix-compile-error-when-recycler-is-disabl.patch deleted file mode 100644 index 19e631145d637b..00000000000000 --- a/target/linux/qualcommax/patches-6.1/9990-0429-net-skbuff-Fix-compile-error-when-recycler-is-disabl.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 1c46d6dbc82a65198344424a736b9800d1387213 Mon Sep 17 00:00:00 2001 -From: Swati Singh -Date: Tue, 5 Sep 2023 10:08:26 +0530 -Subject: [PATCH] net: skbuff: Fix compile error when recycler is disabled - -consume_skb recycle function should be enclosed within -CONFIG_SKB_RECYCLER macro. - -Change-Id: I1703919d8da10102951ec3795eb63cf7ecf9a44b -Signed-off-by: Swati Singh ---- - net/core/skbuff.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -1107,6 +1107,7 @@ EXPORT_SYMBOL(skb_tx_error); - * Functions identically to kfree_skb, but kfree_skb assumes that the frame - * is being dropped after a failure and notes that - */ -+#ifdef CONFIG_SKB_RECYCLER - void consume_skb(struct sk_buff *skb) - { - if (!skb_unref(skb)) -@@ -1152,6 +1153,7 @@ void consume_skb(struct sk_buff *skb) - kfree_skbmem(skb); - } - EXPORT_SYMBOL(consume_skb); -+#endif - - /** - * __consume_stateless_skb - free an skbuff, assuming it is stateless diff --git a/target/linux/qualcommax/patches-6.1/9990-0444-net-prefetch-skb-while-dequeuing-from-backlog-list.patch b/target/linux/qualcommax/patches-6.1/9990-0444-net-prefetch-skb-while-dequeuing-from-backlog-list.patch deleted file mode 100644 index 341f95da7390bf..00000000000000 --- a/target/linux/qualcommax/patches-6.1/9990-0444-net-prefetch-skb-while-dequeuing-from-backlog-list.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 636896a375ffbc62f0ef6c10d8102854021e3c4d Mon Sep 17 00:00:00 2001 -From: KRITHI D SHETTY -Date: Thu, 7 Sep 2023 10:47:59 +0530 -Subject: [PATCH] net: prefetch skb while dequeuing from backlog list. - -Change-Id: I01f1fdadd643a8f2850587200b0133c4c5984f26 -Signed-off-by: KRITHI D SHETTY ---- - net/core/dev.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -5975,10 +5975,16 @@ static int process_backlog(struct napi_s - - napi->weight = READ_ONCE(dev_rx_weight); - while (again) { -- struct sk_buff *skb; -+ struct sk_buff *skb, *next_skb; - - while ((skb = __skb_dequeue(&sd->process_queue))) { - rcu_read_lock(); -+ -+ next_skb = skb_peek(&sd->process_queue); -+ if (likely(next_skb)) { -+ prefetch(next_skb->data); -+ } -+ - __netif_receive_skb(skb); - rcu_read_unlock(); - input_queue_head_incr(sd); diff --git a/target/linux/qualcommax/patches-6.1/9990-0498-skbuff-Fix-the-skb-allocation-to-allocate-the-skbs-f.patch b/target/linux/qualcommax/patches-6.1/9990-0498-skbuff-Fix-the-skb-allocation-to-allocate-the-skbs-f.patch deleted file mode 100644 index 11603dfc54b7a4..00000000000000 --- a/target/linux/qualcommax/patches-6.1/9990-0498-skbuff-Fix-the-skb-allocation-to-allocate-the-skbs-f.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 475bbd3c053a0ed73ed33e41eb7a620a01f583cb Mon Sep 17 00:00:00 2001 -From: Manish Verma -Date: Tue, 10 Oct 2023 22:35:14 +0530 -Subject: [PATCH] [skbuff] Fix the skb allocation to allocate the skbs from the - SKB SLAB - -Due to the kmalloc_size_roundup() function added in the __alloc_skb() -API in 6.1, this API is not allocating the SKBs from the NSS -SKB SLAB area even when the request size is SKB_DATA_CACHE_SIZE. - -This change is deferring the kmalloc_size_roundup() function call after -the SKB is allocated from the NSS SKB SLAB. - -Change-Id: Ic6d75d66163f677b12c915ee26afbbcb26536512 -Signed-off-by: Manish Verma ---- - net/core/skbuff.c | 61 +++++++++++++++++++++++++++-------------------- - 1 file changed, 35 insertions(+), 26 deletions(-) - ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -454,41 +454,47 @@ EXPORT_SYMBOL(napi_build_skb); - * memory is free - */ - static void *kmalloc_reserve(unsigned int *size, gfp_t flags, int node, -- bool *pfmemalloc) --{ -- bool ret_pfmemalloc = false; -- size_t obj_size; -- void *obj; -+ bool *pfmemalloc) -+ { -+ void *obj; -+ bool ret_pfmemalloc = false; -+ unsigned int obj_size = *size; - -- obj_size = SKB_HEAD_ALIGN(*size); -+ if (obj_size > SZ_2K && obj_size <= SKB_DATA_CACHE_SIZE) { -+ obj = kmem_cache_alloc_node(skb_data_cache, -+ flags | __GFP_NOMEMALLOC | __GFP_NOWARN, -+ node); -+ *size = SKB_DATA_CACHE_SIZE; -+ if (obj || !(gfp_pfmemalloc_allowed(flags))) -+ goto out; -+ -+ /* Try again but now we are using pfmemalloc reserves */ -+ ret_pfmemalloc = true; -+ obj = kmem_cache_alloc_node(skb_data_cache, flags, node); -+ goto out; -+ } - - obj_size = kmalloc_size_roundup(obj_size); -- /* The following cast might truncate high-order bits of obj_size, this -- * is harmless because kmalloc(obj_size >= 2^32) will fail anyway. -- */ -- *size = (unsigned int)obj_size; - - /* -- * Try a regular allocation, when that fails and we're not entitled -- * to the reserves, fail. -+ * The following cast might truncate high-order bits of obj_size, this -+ * is harmless because kmalloc(obj_size >= 2^32) will fail anyway. - */ -- if (obj_size > SZ_2K && obj_size <= SKB_DATA_CACHE_SIZE) -- obj = kmem_cache_alloc_node(skb_data_cache, -- flags | __GFP_NOMEMALLOC | __GFP_NOWARN, -- node); -- else -- obj = kmalloc_node_track_caller(obj_size, -- flags | __GFP_NOMEMALLOC | __GFP_NOWARN, -- node); -- if (obj || !(gfp_pfmemalloc_allowed(flags))) -- goto out; -+ *size = (unsigned int)obj_size; - -- /* Try again but now we are using pfmemalloc reserves */ -- ret_pfmemalloc = true; -- if (obj_size > SZ_2K && obj_size <= SKB_DATA_CACHE_SIZE) -- obj = kmem_cache_alloc_node(skb_data_cache, flags, node); -- else -- obj = kmalloc_node_track_caller(obj_size, flags, node); -+ /* -+ * Try a regular allocation, when that fails and we're not entitled -+ * to the reserves, fail. -+ */ -+ obj = kmalloc_node_track_caller(obj_size, -+ flags | __GFP_NOMEMALLOC | __GFP_NOWARN, -+ node); -+ if (obj || !(gfp_pfmemalloc_allowed(flags))) -+ goto out; -+ -+ /* Try again but now we are using pfmemalloc reserves */ -+ ret_pfmemalloc = true; -+ obj = kmalloc_node_track_caller(obj_size, flags, node); - - out: - if (pfmemalloc) -@@ -550,10 +556,12 @@ struct sk_buff *__alloc_skb(unsigned int - * aligned memory blocks, unless SLUB/SLAB debug is enabled. - * Both skb->head and skb_shared_info are cache line aligned. - */ -+ size = SKB_DATA_ALIGN(size); -+ size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); - data = kmalloc_reserve(&size, gfp_mask, node, &pfmemalloc); - if (unlikely(!data)) - goto nodata; -- /* kmalloc_size_roundup() might give us more room than requested. -+ /* kmalloc_reserve(size) might give us more room than requested. - * Put skb_shared_info exactly at the end of allocated zone, - * to allow max possible filling before reallocation. - */ -@@ -644,7 +652,8 @@ struct sk_buff *__netdev_alloc_skb(struc - goto skb_success; - } - -- len = SKB_HEAD_ALIGN(len); -+ len += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -+ len = SKB_DATA_ALIGN(len); - - if (sk_memalloc_socks()) - gfp_mask |= __GFP_MEMALLOC; -@@ -744,7 +753,8 @@ struct sk_buff *__napi_alloc_skb(struct - data = page_frag_alloc_1k(&nc->page_small, gfp_mask); - pfmemalloc = NAPI_SMALL_PAGE_PFMEMALLOC(nc->page_small); - } else { -- len = SKB_HEAD_ALIGN(len); -+ len += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -+ len = SKB_DATA_ALIGN(len); - - data = page_frag_alloc(&nc->page, len, gfp_mask); - pfmemalloc = nc->page.pfmemalloc; -@@ -1958,6 +1968,8 @@ int pskb_expand_head(struct sk_buff *skb - if (skb_pfmemalloc(skb)) - gfp_mask |= __GFP_MEMALLOC; - -+ size = SKB_DATA_ALIGN(size); -+ size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); - data = kmalloc_reserve(&size, gfp_mask, NUMA_NO_NODE, NULL); - if (!data) - goto nodata; -@@ -6333,6 +6345,8 @@ static int pskb_carve_inside_header(stru - if (skb_pfmemalloc(skb)) - gfp_mask |= __GFP_MEMALLOC; - -+ size = SKB_DATA_ALIGN(size); -+ size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); - data = kmalloc_reserve(&size, gfp_mask, NUMA_NO_NODE, NULL); - if (!data) - return -ENOMEM; -@@ -6449,6 +6463,8 @@ static int pskb_carve_inside_nonlinear(s - if (skb_pfmemalloc(skb)) - gfp_mask |= __GFP_MEMALLOC; - -+ size = SKB_DATA_ALIGN(size); -+ size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); - data = kmalloc_reserve(&size, gfp_mask, NUMA_NO_NODE, NULL); - if (!data) - return -ENOMEM; diff --git a/target/linux/qualcommax/patches-6.1/9990-0527-net-Fix-the-crash-in-skbuff.c-for-debug-build.patch b/target/linux/qualcommax/patches-6.1/9990-0527-net-Fix-the-crash-in-skbuff.c-for-debug-build.patch deleted file mode 100644 index f73753c65ad2a7..00000000000000 --- a/target/linux/qualcommax/patches-6.1/9990-0527-net-Fix-the-crash-in-skbuff.c-for-debug-build.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 9bdf7a1d0a1cb12e4e1036b1514c64872bbdafee Mon Sep 17 00:00:00 2001 -From: Pavithra R -Date: Fri, 3 Nov 2023 22:43:32 +0530 -Subject: [PATCH] net: Fix the crash in skbuff.c for debug build - -When skb is allocated in NAPI context we aren't -initializing and activating the skb object. Add support -for init and activating skb in napi_build_skb. - -Change-Id: Idcc3d6c260831be12ec85df474bcdc17f86d3292 -Signed-off-by: Pavithra R ---- - net/core/skbuff.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -417,6 +417,8 @@ static struct sk_buff *__napi_build_skb( - if (unlikely(!skb)) - return NULL; - -+ skbuff_debugobj_init_and_activate(skb); -+ - memset(skb, 0, offsetof(struct sk_buff, tail)); - __build_skb_around(skb, data, frag_size); - diff --git a/target/linux/qualcommax/patches-6.1/9990-0558-net-Fix-the-crash-due-to-missing-skb-debug-deactivat.patch b/target/linux/qualcommax/patches-6.1/9990-0558-net-Fix-the-crash-due-to-missing-skb-debug-deactivat.patch deleted file mode 100644 index da70404d62c05b..00000000000000 --- a/target/linux/qualcommax/patches-6.1/9990-0558-net-Fix-the-crash-due-to-missing-skb-debug-deactivat.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 9f2362ee17aef209a42aa7a9f6f41ca2aa82d2eb Mon Sep 17 00:00:00 2001 -From: Pavithra R -Date: Wed, 22 Nov 2023 20:57:45 +0530 -Subject: [PATCH] net: Fix the crash due to missing skb debug deactivation - -Napi allocation and consume involves activation and deactivation of -skb. In napi_skb_finish function the deactivation was not happening. -The patch fixes the same. Also deactivation was missing in napi_consume_skb. - -Change-Id: I7ea2240c138ec2a4e2796e33f37b1ce923ca7a4d -Signed-off-by: Pavithra R ---- - net/core/gro.c | 6 ++++-- - net/core/skbuff.c | 2 ++ - 2 files changed, 6 insertions(+), 2 deletions(-) - ---- a/net/core/gro.c -+++ b/net/core/gro.c -@@ -3,6 +3,7 @@ - #include - #include - #include -+#include "skbuff_debug.h" - - #define MAX_GRO_SKBS 8 - -@@ -631,9 +632,10 @@ static gro_result_t napi_skb_finish(stru - break; - - case GRO_MERGED_FREE: -- if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD) -+ if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD) { -+ skbuff_debugobj_deactivate(skb); - napi_skb_free_stolen_head(skb); -- else if (skb->fclone != SKB_FCLONE_UNAVAILABLE) -+ } else if (skb->fclone != SKB_FCLONE_UNAVAILABLE) - __kfree_skb(skb); - else - __kfree_skb_defer(skb); ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -1202,6 +1202,7 @@ static void napi_skb_cache_put(struct sk - - void __kfree_skb_defer(struct sk_buff *skb) - { -+ skbuff_debugobj_deactivate(skb); - skb_release_all(skb); - napi_skb_cache_put(skb); - } -@@ -1240,6 +1241,7 @@ void napi_consume_skb(struct sk_buff *sk - return; - } - -+ skbuff_debugobj_deactivate(skb); - skb_release_all(skb); - napi_skb_cache_put(skb); - } diff --git a/target/linux/qualcommax/patches-6.1/9990-1-qca-skb_recycler-support.patch b/target/linux/qualcommax/patches-6.1/9990-1-qca-skb_recycler-support.patch new file mode 100644 index 00000000000000..6547ce41ecf881 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/9990-1-qca-skb_recycler-support.patch @@ -0,0 +1,424 @@ +diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h +index 67575bc..c8761f8 100644 +--- a/include/linux/cpuhotplug.h ++++ b/include/linux/cpuhotplug.h +@@ -94,6 +94,7 @@ enum cpuhp_state { + CPUHP_RADIX_DEAD, + CPUHP_PAGE_ALLOC, + CPUHP_NET_DEV_DEAD, ++ CPUHP_SKB_RECYCLER_DEAD, + CPUHP_PCI_XGENE_DEAD, + CPUHP_IOMMU_IOVA_DEAD, + CPUHP_LUSTRE_CFS_DEAD, +diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h +index 05dcdea..664e8dc 100644 +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -1240,7 +1240,7 @@ static inline void kfree_skb_list(struct sk_buff *segs) + kfree_skb_list_reason(segs, SKB_DROP_REASON_NOT_SPECIFIED); + } + +-#ifdef CONFIG_TRACEPOINTS ++#ifdef CONFIG_SKB_RECYCLER + void consume_skb(struct sk_buff *skb); + #else + static inline void consume_skb(struct sk_buff *skb) +@@ -1252,6 +1252,8 @@ static inline void consume_skb(struct sk_buff *skb) + void __consume_stateless_skb(struct sk_buff *skb); + void __kfree_skb(struct sk_buff *skb); + extern struct kmem_cache *skbuff_head_cache; ++extern void kfree_skbmem(struct sk_buff *skb); ++extern void skb_release_data(struct sk_buff *skb); + + void kfree_skb_partial(struct sk_buff *skb, bool head_stolen); + bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from, +diff --git a/net/Kconfig b/net/Kconfig +index 604b251..cabad55 100644 +--- a/net/Kconfig ++++ b/net/Kconfig +@@ -332,6 +332,27 @@ config NET_FLOW_LIMIT + with many clients some protection against DoS by a single (spoofed) + flow that greatly exceeds average workload. + ++config SKB_RECYCLER ++ bool "Generic skb recycling" ++ default y ++ help ++ SKB_RECYCLER is used to implement RX-to-RX skb recycling. ++ This config enables the recycling scheme for bridging and ++ routing workloads. It can reduce skbuff freeing or ++ reallocation overhead. ++ ++config SKB_RECYCLER_MULTI_CPU ++ bool "Cross-CPU recycling for CPU-locked workloads" ++ depends on SMP && SKB_RECYCLER ++ default n ++ ++config ALLOC_SKB_PAGE_FRAG_DISABLE ++ bool "Disable page fragment based skbuff payload allocations" ++ depends on !SKB_RECYCLER ++ default n ++ help ++ Disable page fragment based allocations for skbuff payloads. ++ + menu "Network testing" + + config NET_PKTGEN +diff --git a/net/core/Makefile b/net/core/Makefile +index 1a71c00..2978093 100644 +--- a/net/core/Makefile ++++ b/net/core/Makefile +@@ -40,3 +40,4 @@ obj-$(CONFIG_NET_SOCK_MSG) += skmsg.o + obj-$(CONFIG_BPF_SYSCALL) += sock_map.o + obj-$(CONFIG_BPF_SYSCALL) += bpf_sk_storage.o + obj-$(CONFIG_OF) += of_net.o ++obj-$(CONFIG_SKB_RECYCLER) += skbuff_recycle.o +diff --git a/net/core/dev.c b/net/core/dev.c +index 27d319b..5a83ee7 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -5974,10 +5974,16 @@ static int process_backlog(struct napi_struct *napi, int quota) + + napi->weight = READ_ONCE(dev_rx_weight); + while (again) { +- struct sk_buff *skb; ++ struct sk_buff *skb, *next_skb; + + while ((skb = __skb_dequeue(&sd->process_queue))) { + rcu_read_lock(); ++ ++ next_skb = skb_peek(&sd->process_queue); ++ if (likely(next_skb)) { ++ prefetch(next_skb->data); ++ } ++ + __netif_receive_skb(skb); + rcu_read_unlock(); + input_queue_head_incr(sd); +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index dcbc50b..2a7de3f 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -84,6 +84,33 @@ + #include "dev.h" + #include "sock_destructor.h" + ++struct kmem_cache *skb_data_cache; ++ ++/* ++ * For low memory profile, NSS_SKB_FIXED_SIZE_2K is enabled and ++ * CONFIG_SKB_RECYCLER is disabled. For premium and enterprise profile ++ * CONFIG_SKB_RECYCLER is enabled and NSS_SKB_FIXED_SIZE_2K is disabled. ++ * Irrespective of NSS_SKB_FIXED_SIZE_2K enabled/disabled, the ++ * CONFIG_SKB_RECYCLER and __LP64__ determines the value of SKB_DATA_CACHE_SIZE ++ */ ++#if defined(CONFIG_SKB_RECYCLER) ++/* ++ * 2688 for 64bit arch, 2624 for 32bit arch ++ */ ++#define SKB_DATA_CACHE_SIZE (SKB_DATA_ALIGN(SKB_RECYCLE_SIZE + NET_SKB_PAD) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) ++#else ++/* ++ * 2368 for 64bit arch, 2176 for 32bit arch ++ */ ++#if defined(__LP64__) ++#define SKB_DATA_CACHE_SIZE ((SKB_DATA_ALIGN(1984 + NET_SKB_PAD)) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) ++#else ++#define SKB_DATA_CACHE_SIZE ((SKB_DATA_ALIGN(1856 + NET_SKB_PAD)) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) ++#endif ++#endif ++ ++#include "skbuff_recycle.h" ++ + struct kmem_cache *skbuff_head_cache __ro_after_init; + static struct kmem_cache *skbuff_fclone_cache __ro_after_init; + #ifdef CONFIG_SKB_EXTENSIONS +@@ -426,32 +453,46 @@ EXPORT_SYMBOL(napi_build_skb); + * memory is free + */ + static void *kmalloc_reserve(unsigned int *size, gfp_t flags, int node, +- bool *pfmemalloc) +-{ +- bool ret_pfmemalloc = false; +- size_t obj_size; +- void *obj; ++ bool *pfmemalloc) ++ { ++ void *obj; ++ bool ret_pfmemalloc = false; ++ unsigned int obj_size = *size; ++ ++ if (obj_size > SZ_2K && obj_size <= SKB_DATA_CACHE_SIZE) { ++ obj = kmem_cache_alloc_node(skb_data_cache, ++ flags | __GFP_NOMEMALLOC | __GFP_NOWARN, ++ node); ++ *size = SKB_DATA_CACHE_SIZE; ++ if (obj || !(gfp_pfmemalloc_allowed(flags))) ++ goto out; + +- obj_size = SKB_HEAD_ALIGN(*size); ++ /* Try again but now we are using pfmemalloc reserves */ ++ ret_pfmemalloc = true; ++ obj = kmem_cache_alloc_node(skb_data_cache, flags, node); ++ goto out; ++ } + + obj_size = kmalloc_size_roundup(obj_size); +- /* The following cast might truncate high-order bits of obj_size, this ++ ++ /* ++ * The following cast might truncate high-order bits of obj_size, this + * is harmless because kmalloc(obj_size >= 2^32) will fail anyway. + */ + *size = (unsigned int)obj_size; + +- /* +- * Try a regular allocation, when that fails and we're not entitled +- * to the reserves, fail. +- */ ++ /* ++ * Try a regular allocation, when that fails and we're not entitled ++ * to the reserves, fail. ++ */ + obj = kmalloc_node_track_caller(obj_size, +- flags | __GFP_NOMEMALLOC | __GFP_NOWARN, +- node); +- if (obj || !(gfp_pfmemalloc_allowed(flags))) +- goto out; ++ flags | __GFP_NOMEMALLOC | __GFP_NOWARN, ++ node); ++ if (obj || !(gfp_pfmemalloc_allowed(flags))) ++ goto out; + +- /* Try again but now we are using pfmemalloc reserves */ +- ret_pfmemalloc = true; ++ /* Try again but now we are using pfmemalloc reserves */ ++ ret_pfmemalloc = true; + obj = kmalloc_node_track_caller(obj_size, flags, node); + + out: +@@ -513,10 +554,12 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, + * aligned memory blocks, unless SLUB/SLAB debug is enabled. + * Both skb->head and skb_shared_info are cache line aligned. + */ ++ size = SKB_DATA_ALIGN(size); ++ size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + data = kmalloc_reserve(&size, gfp_mask, node, &pfmemalloc); + if (unlikely(!data)) + goto nodata; +- /* kmalloc_size_roundup() might give us more room than requested. ++ /* kmalloc_reserve(size) might give us more room than requested. + * Put skb_shared_info exactly at the end of allocated zone, + * to allow max possible filling before reallocation. + */ +@@ -551,7 +594,7 @@ EXPORT_SYMBOL(__alloc_skb); + /** + * __netdev_alloc_skb - allocate an skbuff for rx on a specific device + * @dev: network device to receive on +- * @len: length to allocate ++ * @length: length to allocate + * @gfp_mask: get_free_pages mask, passed to alloc_skb + * + * Allocate a new &sk_buff and assign it a usage count of one. The +@@ -561,29 +604,53 @@ EXPORT_SYMBOL(__alloc_skb); + * + * %NULL is returned if there is no free memory. + */ +-struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int len, +- gfp_t gfp_mask) ++struct sk_buff *__netdev_alloc_skb(struct net_device *dev, ++ unsigned int length, gfp_t gfp_mask) + { +- struct page_frag_cache *nc; + struct sk_buff *skb; ++ unsigned int len = length; ++ ++#ifdef CONFIG_SKB_RECYCLER ++ skb = skb_recycler_alloc(dev, length); ++ if (likely(skb)) ++ return skb; ++ ++ len = SKB_RECYCLE_SIZE; ++ if (unlikely(length > SKB_RECYCLE_SIZE)) ++ len = length; ++ ++ skb = __alloc_skb(len + NET_SKB_PAD, gfp_mask, ++ SKB_ALLOC_RX, NUMA_NO_NODE); ++ if (!skb) ++ goto skb_fail; ++ goto skb_success; ++#else ++ struct page_frag_cache *nc; + bool pfmemalloc; ++ bool page_frag_alloc_enable = true; + void *data; + + len += NET_SKB_PAD; + ++ ++#ifdef CONFIG_ALLOC_SKB_PAGE_FRAG_DISABLE ++ page_frag_alloc_enable = false; ++#endif + /* If requested length is either too small or too big, + * we use kmalloc() for skb->head allocation. + */ + if (len <= SKB_WITH_OVERHEAD(1024) || + len > SKB_WITH_OVERHEAD(PAGE_SIZE) || +- (gfp_mask & (__GFP_DIRECT_RECLAIM | GFP_DMA))) { ++ (gfp_mask & (__GFP_DIRECT_RECLAIM | GFP_DMA)) || ++ !page_frag_alloc_enable) { + skb = __alloc_skb(len, gfp_mask, SKB_ALLOC_RX, NUMA_NO_NODE); + if (!skb) + goto skb_fail; + goto skb_success; + } + +- len = SKB_HEAD_ALIGN(len); ++ len += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); ++ len = SKB_DATA_ALIGN(len); + + if (sk_memalloc_socks()) + gfp_mask |= __GFP_MEMALLOC; +@@ -612,6 +679,7 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int len, + if (pfmemalloc) + skb->pfmemalloc = 1; + skb->head_frag = 1; ++#endif + + skb_success: + skb_reserve(skb, NET_SKB_PAD); +@@ -682,7 +750,8 @@ struct sk_buff *__napi_alloc_skb(struct napi_struct *napi, unsigned int len, + data = page_frag_alloc_1k(&nc->page_small, gfp_mask); + pfmemalloc = NAPI_SMALL_PAGE_PFMEMALLOC(nc->page_small); + } else { +- len = SKB_HEAD_ALIGN(len); ++ len += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); ++ len = SKB_DATA_ALIGN(len); + + data = page_frag_alloc(&nc->page, len, gfp_mask); + pfmemalloc = nc->page.pfmemalloc; +@@ -780,7 +849,7 @@ static void skb_free_head(struct sk_buff *skb) + } + } + +-static void skb_release_data(struct sk_buff *skb) ++void skb_release_data(struct sk_buff *skb) + { + struct skb_shared_info *shinfo = skb_shinfo(skb); + int i; +@@ -822,7 +891,7 @@ static void skb_release_data(struct sk_buff *skb) + /* + * Free an skbuff by memory without cleaning the state. + */ +-static void kfree_skbmem(struct sk_buff *skb) ++void kfree_skbmem(struct sk_buff *skb) + { + struct sk_buff_fclones *fclones; + +@@ -1034,7 +1103,6 @@ void skb_tx_error(struct sk_buff *skb) + } + EXPORT_SYMBOL(skb_tx_error); + +-#ifdef CONFIG_TRACEPOINTS + /** + * consume_skb - free an skbuff + * @skb: buffer to free +@@ -1043,13 +1111,50 @@ EXPORT_SYMBOL(skb_tx_error); + * Functions identically to kfree_skb, but kfree_skb assumes that the frame + * is being dropped after a failure and notes that + */ ++#ifdef CONFIG_SKB_RECYCLER + void consume_skb(struct sk_buff *skb) + { + if (!skb_unref(skb)) + return; + ++ prefetch(&skb->destructor); ++ ++ /*Tian: Not sure if we need to continue using this since ++ * since unref does the work in 5.4 ++ */ ++ ++ /* ++ if (likely(atomic_read(&skb->users) == 1)) ++ smp_rmb(); ++ else if (likely(!atomic_dec_and_test(&skb->users))) ++ return; ++ */ ++ ++ /* If possible we'd like to recycle any skb rather than just free it, ++ * but in order to do that we need to release any head state too. ++ * We don't want to do this later because we'll be in a pre-emption ++ * disabled state. ++ */ ++ skb_release_head_state(skb); ++ ++ /* Can we recycle this skb? If we can then it will be much faster ++ * for us to recycle this one later than to allocate a new one ++ * from scratch. ++ */ ++ if (likely(skb->head) && likely(skb_recycler_consume(skb))) ++ return; ++ ++#ifdef CONFIG_TRACEPOINTS + trace_consume_skb(skb); +- __kfree_skb(skb); ++#endif ++ /* We're not recycling so now we need to do the rest of what we would ++ * have done in __kfree_skb (above and beyond the skb_release_head_state ++ * that we already did). ++ */ ++ if (likely(skb->head)) ++ skb_release_data(skb); ++ ++ kfree_skbmem(skb); + } + EXPORT_SYMBOL(consume_skb); + #endif +@@ -1856,6 +1961,8 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, + if (skb_pfmemalloc(skb)) + gfp_mask |= __GFP_MEMALLOC; + ++ size = SKB_DATA_ALIGN(size); ++ size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + data = kmalloc_reserve(&size, gfp_mask, NUMA_NO_NODE, NULL); + if (!data) + goto nodata; +@@ -4557,6 +4664,11 @@ static void skb_extensions_init(void) {} + + void __init skb_init(void) + { ++ skb_data_cache = kmem_cache_create_usercopy("skb_data_cache", ++ SKB_DATA_CACHE_SIZE, ++ 0, SLAB_PANIC, 0, SKB_DATA_CACHE_SIZE, ++ NULL); ++ + skbuff_head_cache = kmem_cache_create_usercopy("skbuff_head_cache", + sizeof(struct sk_buff), + 0, +@@ -4570,6 +4682,7 @@ void __init skb_init(void) + SLAB_HWCACHE_ALIGN|SLAB_PANIC, + NULL); + skb_extensions_init(); ++ skb_recycler_init(); + } + + static int +@@ -6224,6 +6337,8 @@ static int pskb_carve_inside_header(struct sk_buff *skb, const u32 off, + if (skb_pfmemalloc(skb)) + gfp_mask |= __GFP_MEMALLOC; + ++ size = SKB_DATA_ALIGN(size); ++ size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + data = kmalloc_reserve(&size, gfp_mask, NUMA_NO_NODE, NULL); + if (!data) + return -ENOMEM; +@@ -6340,6 +6455,8 @@ static int pskb_carve_inside_nonlinear(struct sk_buff *skb, const u32 off, + if (skb_pfmemalloc(skb)) + gfp_mask |= __GFP_MEMALLOC; + ++ size = SKB_DATA_ALIGN(size); ++ size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + data = kmalloc_reserve(&size, gfp_mask, NUMA_NO_NODE, NULL); + if (!data) + return -ENOMEM; From 1addb6779ed0f8953a7f239d43765752c4ee1e14 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Tue, 26 Mar 2024 00:32:50 -0400 Subject: [PATCH 170/225] qualcommax: NSS: consolidate patches and align with 6.1 --- .../0600-1-qca-nss-ecm-support-CORE.patch | 10 ++++++++++ ...ecm-fix-IPv6-user-route-change-event-calls.patch} | 0 ...nntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch | 10 ---------- .../9990-1-qca-skb_recycler-support.patch | 12 ------------ 4 files changed, 10 insertions(+), 22 deletions(-) rename target/linux/qualcommax/patches-6.6/{0600-2-qca-nss-ecm-support-CORE-Fix-IPv6-user-route-change-event-calls.patch => 0600-7-qca-nss-ecm-fix-IPv6-user-route-change-event-calls.patch} (100%) delete mode 100644 target/linux/qualcommax/patches-6.6/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch diff --git a/target/linux/qualcommax/patches-6.6/0600-1-qca-nss-ecm-support-CORE.patch b/target/linux/qualcommax/patches-6.6/0600-1-qca-nss-ecm-support-CORE.patch index 21006721e11666..c49b9564044716 100644 --- a/target/linux/qualcommax/patches-6.6/0600-1-qca-nss-ecm-support-CORE.patch +++ b/target/linux/qualcommax/patches-6.6/0600-1-qca-nss-ecm-support-CORE.patch @@ -783,6 +783,16 @@ #endif /* _UAPI_LINUX_IN_H */ +--- a/net/netfilter/nf_conntrack_ecache.c ++++ b/net/netfilter/nf_conntrack_ecache.c +@@ -266,7 +266,6 @@ void nf_conntrack_register_notifier(stru + mutex_lock(&nf_ct_ecache_mutex); + notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb, + lockdep_is_held(&nf_ct_ecache_mutex)); +- WARN_ON_ONCE(notify); + rcu_assign_pointer(net->ct.nf_conntrack_event_cb, new); + mutex_unlock(&nf_ct_ecache_mutex); + } --- a/include/net/netns/conntrack.h +++ b/include/net/netns/conntrack.h @@ -26,6 +26,7 @@ struct nf_tcp_net { diff --git a/target/linux/qualcommax/patches-6.6/0600-2-qca-nss-ecm-support-CORE-Fix-IPv6-user-route-change-event-calls.patch b/target/linux/qualcommax/patches-6.6/0600-7-qca-nss-ecm-fix-IPv6-user-route-change-event-calls.patch similarity index 100% rename from target/linux/qualcommax/patches-6.6/0600-2-qca-nss-ecm-support-CORE-Fix-IPv6-user-route-change-event-calls.patch rename to target/linux/qualcommax/patches-6.6/0600-7-qca-nss-ecm-fix-IPv6-user-route-change-event-calls.patch diff --git a/target/linux/qualcommax/patches-6.6/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch b/target/linux/qualcommax/patches-6.6/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch deleted file mode 100644 index 4b9ee21f2f8545..00000000000000 --- a/target/linux/qualcommax/patches-6.6/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/net/netfilter/nf_conntrack_ecache.c -+++ b/net/netfilter/nf_conntrack_ecache.c -@@ -266,7 +266,6 @@ void nf_conntrack_register_notifier(stru - mutex_lock(&nf_ct_ecache_mutex); - notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb, - lockdep_is_held(&nf_ct_ecache_mutex)); -- WARN_ON_ONCE(notify); - rcu_assign_pointer(net->ct.nf_conntrack_event_cb, new); - mutex_unlock(&nf_ct_ecache_mutex); - } diff --git a/target/linux/qualcommax/patches-6.6/9990-1-qca-skb_recycler-support.patch b/target/linux/qualcommax/patches-6.6/9990-1-qca-skb_recycler-support.patch index 886bc92fe2e26a..e59b5e5398aea4 100644 --- a/target/linux/qualcommax/patches-6.6/9990-1-qca-skb_recycler-support.patch +++ b/target/linux/qualcommax/patches-6.6/9990-1-qca-skb_recycler-support.patch @@ -1,5 +1,3 @@ -diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h -index 624d4a3..5aa8808 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -94,6 +94,7 @@ enum cpuhp_state { @@ -10,8 +8,6 @@ index 624d4a3..5aa8808 100644 CPUHP_PCI_XGENE_DEAD, CPUHP_IOMMU_IOVA_DEAD, CPUHP_LUSTRE_CFS_DEAD, -diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h -index 83cced8..b6ee509 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1065,6 +1065,10 @@ struct sk_buff { @@ -44,8 +40,6 @@ index 83cced8..b6ee509 100644 void kfree_skb_partial(struct sk_buff *skb, bool head_stolen); bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from, -diff --git a/net/Kconfig b/net/Kconfig -index 61eac93..e0c8bf0 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -369,6 +369,27 @@ config NET_FLOW_LIMIT @@ -76,8 +70,6 @@ index 61eac93..e0c8bf0 100644 menu "Network testing" config NET_PKTGEN -diff --git a/net/core/Makefile b/net/core/Makefile -index 5c9fc1f..e90878c 100644 --- a/net/core/Makefile +++ b/net/core/Makefile @@ -41,3 +41,4 @@ obj-$(CONFIG_NET_SOCK_MSG) += skmsg.o @@ -85,8 +77,6 @@ index 5c9fc1f..e90878c 100644 obj-$(CONFIG_BPF_SYSCALL) += bpf_sk_storage.o obj-$(CONFIG_OF) += of_net.o +obj-$(CONFIG_SKB_RECYCLER) += skbuff_recycle.o -diff --git a/net/core/dev.c b/net/core/dev.c -index 85a1038..c6994ab 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -6016,10 +6016,16 @@ static int process_backlog(struct napi_struct *napi, int quota) @@ -107,8 +97,6 @@ index 85a1038..c6994ab 100644 __netif_receive_skb(skb); rcu_read_unlock(); input_queue_head_incr(sd); -diff --git a/net/core/skbuff.c b/net/core/skbuff.c -index bcfa460..eaf8bcb 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -87,6 +87,31 @@ From 5b240edf1923b9b162057622d221d2a89e548b5f Mon Sep 17 00:00:00 2001 From: Qosmio Date: Tue, 26 Mar 2024 00:34:02 -0400 Subject: [PATCH 171/225] qualcommax: remove extraneous 'diff' syntax --- .../0600-1-qca-nss-ecm-support-CORE.patch | 4 ---- .../9990-1-qca-skb_recycler-support.patch | 12 ------------ 2 files changed, 16 deletions(-) diff --git a/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch b/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch index f6dcfe64f1b4d3..a1cd66c4db6f5b 100644 --- a/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch +++ b/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch @@ -806,8 +806,6 @@ u8 tcp_max_retrans; u8 tcp_ignore_invalid_rst; #if IS_ENABLED(CONFIG_NF_FLOW_TABLE) -diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c -index 3ac1af6f59fc..0a2badd52b54 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -513,11 +513,15 @@ tcp_in_window(struct nf_conn *ct, enum ip_conntrack_dir dir, @@ -845,8 +843,6 @@ index 3ac1af6f59fc..0a2badd52b54 100644 /* If it's non-zero, we turn off RST sequence number check */ tn->tcp_ignore_invalid_rst = 0; -diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c -index e9654169b005..84b8e28f0782 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -637,6 +637,7 @@ enum nf_ct_sysctl_index { diff --git a/target/linux/qualcommax/patches-6.1/9990-1-qca-skb_recycler-support.patch b/target/linux/qualcommax/patches-6.1/9990-1-qca-skb_recycler-support.patch index 6547ce41ecf881..899e0a2b527f7b 100644 --- a/target/linux/qualcommax/patches-6.1/9990-1-qca-skb_recycler-support.patch +++ b/target/linux/qualcommax/patches-6.1/9990-1-qca-skb_recycler-support.patch @@ -1,5 +1,3 @@ -diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h -index 67575bc..c8761f8 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -94,6 +94,7 @@ enum cpuhp_state { @@ -10,8 +8,6 @@ index 67575bc..c8761f8 100644 CPUHP_PCI_XGENE_DEAD, CPUHP_IOMMU_IOVA_DEAD, CPUHP_LUSTRE_CFS_DEAD, -diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h -index 05dcdea..664e8dc 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1240,7 +1240,7 @@ static inline void kfree_skb_list(struct sk_buff *segs) @@ -32,8 +28,6 @@ index 05dcdea..664e8dc 100644 void kfree_skb_partial(struct sk_buff *skb, bool head_stolen); bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from, -diff --git a/net/Kconfig b/net/Kconfig -index 604b251..cabad55 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -332,6 +332,27 @@ config NET_FLOW_LIMIT @@ -64,8 +58,6 @@ index 604b251..cabad55 100644 menu "Network testing" config NET_PKTGEN -diff --git a/net/core/Makefile b/net/core/Makefile -index 1a71c00..2978093 100644 --- a/net/core/Makefile +++ b/net/core/Makefile @@ -40,3 +40,4 @@ obj-$(CONFIG_NET_SOCK_MSG) += skmsg.o @@ -73,8 +65,6 @@ index 1a71c00..2978093 100644 obj-$(CONFIG_BPF_SYSCALL) += bpf_sk_storage.o obj-$(CONFIG_OF) += of_net.o +obj-$(CONFIG_SKB_RECYCLER) += skbuff_recycle.o -diff --git a/net/core/dev.c b/net/core/dev.c -index 27d319b..5a83ee7 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5974,10 +5974,16 @@ static int process_backlog(struct napi_struct *napi, int quota) @@ -95,8 +85,6 @@ index 27d319b..5a83ee7 100644 __netif_receive_skb(skb); rcu_read_unlock(); input_queue_head_incr(sd); -diff --git a/net/core/skbuff.c b/net/core/skbuff.c -index dcbc50b..2a7de3f 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -84,6 +84,33 @@ From d9fce8542fca0be3f6d10a01fea3a9519c090516 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Tue, 26 Mar 2024 15:52:55 -0400 Subject: [PATCH 172/225] Revert "package: nft-fullcone" This reverts commit 3bbab2ccf223fd10b9759c5b5f51cef94c817719. --- package/libs/libnftnl/Makefile | 1 - ...ftnl-Add-fullcone-expression-support.patch | 253 ------------------ package/network/config/firewall4/Makefile | 3 +- .../001-firewall4-Add-fullcone-support.patch | 215 --------------- .../network/utils/fullconenat-nft/Makefile | 50 ---- ...bles-Add-fullcone-expression-support.patch | 208 -------------- 6 files changed, 2 insertions(+), 728 deletions(-) delete mode 100644 package/libs/libnftnl/patches/001-libnftnl-Add-fullcone-expression-support.patch delete mode 100644 package/network/config/firewall4/patches/001-firewall4-Add-fullcone-support.patch delete mode 100644 package/network/utils/fullconenat-nft/Makefile delete mode 100644 package/network/utils/nftables/patches/0001-nftables-Add-fullcone-expression-support.patch diff --git a/package/libs/libnftnl/Makefile b/package/libs/libnftnl/Makefile index 1e4fa66e2a6f9c..b512d4d58fe616 100644 --- a/package/libs/libnftnl/Makefile +++ b/package/libs/libnftnl/Makefile @@ -23,7 +23,6 @@ PKG_LICENSE_FILES:=COPYING PKG_INSTALL:=1 PKG_BUILD_PARALLEL:=1 PKG_BUILD_FLAGS:=lto -PKG_FIXUP:=autoreconf include $(INCLUDE_DIR)/package.mk diff --git a/package/libs/libnftnl/patches/001-libnftnl-Add-fullcone-expression-support.patch b/package/libs/libnftnl/patches/001-libnftnl-Add-fullcone-expression-support.patch deleted file mode 100644 index f68882849a25a4..00000000000000 --- a/package/libs/libnftnl/patches/001-libnftnl-Add-fullcone-expression-support.patch +++ /dev/null @@ -1,253 +0,0 @@ -From 6c39f04febd7cfdbd474233379416babcd0fc341 Mon Sep 17 00:00:00 2001 -From: Syrone Wong -Date: Fri, 8 Apr 2022 23:52:11 +0800 -Subject: [PATCH] libnftnl: add fullcone expression support - -Signed-off-by: Syrone Wong ---- - include/libnftnl/expr.h | 6 + - include/linux/netfilter/nf_tables.h | 16 +++ - src/Makefile.am | 1 + - src/expr/fullcone.c | 167 ++++++++++++++++++++++++++++ - src/expr_ops.c | 2 + - 5 files changed, 192 insertions(+) - create mode 100644 src/expr/fullcone.c - ---- a/include/libnftnl/expr.h -+++ b/include/libnftnl/expr.h -@@ -245,6 +245,12 @@ enum { - }; - - enum { -+ NFTNL_EXPR_FULLCONE_FLAGS = NFTNL_EXPR_BASE, -+ NFTNL_EXPR_FULLCONE_REG_PROTO_MIN, -+ NFTNL_EXPR_FULLCONE_REG_PROTO_MAX, -+}; -+ -+enum { - NFTNL_EXPR_REDIR_REG_PROTO_MIN = NFTNL_EXPR_BASE, - NFTNL_EXPR_REDIR_REG_PROTO_MAX, - NFTNL_EXPR_REDIR_FLAGS, ---- a/include/linux/netfilter/nf_tables.h -+++ b/include/linux/netfilter/nf_tables.h -@@ -1464,6 +1464,22 @@ enum nft_masq_attributes { - #define NFTA_MASQ_MAX (__NFTA_MASQ_MAX - 1) - - /** -+ * enum nft_fullcone_attributes - nf_tables fullcone expression attributes -+ * -+ * @NFTA_FULLCONE_FLAGS: NAT flags (see NF_NAT_RANGE_* in linux/netfilter/nf_nat.h) (NLA_U32) -+ * @NFTA_FULLCONE_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers) -+ * @NFTA_FULLCONE_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers) -+ */ -+enum nft_fullcone_attributes { -+ NFTA_FULLCONE_UNSPEC, -+ NFTA_FULLCONE_FLAGS, -+ NFTA_FULLCONE_REG_PROTO_MIN, -+ NFTA_FULLCONE_REG_PROTO_MAX, -+ __NFTA_FULLCONE_MAX -+}; -+#define NFTA_FULLCONE_MAX (__NFTA_FULLCONE_MAX - 1) -+ -+/** - * enum nft_redir_attributes - nf_tables redirect expression netlink attributes - * - * @NFTA_REDIR_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers) ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -55,6 +55,7 @@ libnftnl_la_SOURCES = utils.c \ - expr/target.c \ - expr/tunnel.c \ - expr/masq.c \ -+ expr/fullcone.c \ - expr/redir.c \ - expr/hash.c \ - expr/socket.c \ ---- /dev/null -+++ b/src/expr/fullcone.c -@@ -0,0 +1,167 @@ -+/* -+ * (C) 2022 wongsyrone -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published -+ * by the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "internal.h" -+#include -+#include -+#include -+ -+struct nftnl_expr_fullcone { -+ uint32_t flags; -+ enum nft_registers sreg_proto_min; -+ enum nft_registers sreg_proto_max; -+}; -+ -+static int -+nftnl_expr_fullcone_set(struct nftnl_expr *e, uint16_t type, -+ const void *data, uint32_t data_len) -+{ -+ struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e); -+ -+ switch (type) { -+ case NFTNL_EXPR_FULLCONE_FLAGS: -+ memcpy(&fullcone->flags, data, sizeof(fullcone->flags)); -+ break; -+ case NFTNL_EXPR_FULLCONE_REG_PROTO_MIN: -+ memcpy(&fullcone->sreg_proto_min, data, sizeof(fullcone->sreg_proto_min)); -+ break; -+ case NFTNL_EXPR_FULLCONE_REG_PROTO_MAX: -+ memcpy(&fullcone->sreg_proto_max, data, sizeof(fullcone->sreg_proto_max)); -+ break; -+ default: -+ return -1; -+ } -+ return 0; -+} -+ -+static const void * -+nftnl_expr_fullcone_get(const struct nftnl_expr *e, uint16_t type, -+ uint32_t *data_len) -+{ -+ struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e); -+ -+ switch (type) { -+ case NFTNL_EXPR_FULLCONE_FLAGS: -+ *data_len = sizeof(fullcone->flags); -+ return &fullcone->flags; -+ case NFTNL_EXPR_FULLCONE_REG_PROTO_MIN: -+ *data_len = sizeof(fullcone->sreg_proto_min); -+ return &fullcone->sreg_proto_min; -+ case NFTNL_EXPR_FULLCONE_REG_PROTO_MAX: -+ *data_len = sizeof(fullcone->sreg_proto_max); -+ return &fullcone->sreg_proto_max; -+ } -+ return NULL; -+} -+ -+static int nftnl_expr_fullcone_cb(const struct nlattr *attr, void *data) -+{ -+ const struct nlattr **tb = data; -+ int type = mnl_attr_get_type(attr); -+ -+ if (mnl_attr_type_valid(attr, NFTA_FULLCONE_MAX) < 0) -+ return MNL_CB_OK; -+ -+ switch (type) { -+ case NFTA_FULLCONE_REG_PROTO_MIN: -+ case NFTA_FULLCONE_REG_PROTO_MAX: -+ case NFTA_FULLCONE_FLAGS: -+ if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) -+ abi_breakage(); -+ break; -+ } -+ -+ tb[type] = attr; -+ return MNL_CB_OK; -+} -+ -+static void -+nftnl_expr_fullcone_build(struct nlmsghdr *nlh, const struct nftnl_expr *e) -+{ -+ struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e); -+ -+ if (e->flags & (1 << NFTNL_EXPR_FULLCONE_FLAGS)) -+ mnl_attr_put_u32(nlh, NFTA_FULLCONE_FLAGS, htobe32(fullcone->flags)); -+ if (e->flags & (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MIN)) -+ mnl_attr_put_u32(nlh, NFTA_FULLCONE_REG_PROTO_MIN, -+ htobe32(fullcone->sreg_proto_min)); -+ if (e->flags & (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MAX)) -+ mnl_attr_put_u32(nlh, NFTA_FULLCONE_REG_PROTO_MAX, -+ htobe32(fullcone->sreg_proto_max)); -+} -+ -+static int -+nftnl_expr_fullcone_parse(struct nftnl_expr *e, struct nlattr *attr) -+{ -+ struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e); -+ struct nlattr *tb[NFTA_FULLCONE_MAX+1] = {}; -+ -+ if (mnl_attr_parse_nested(attr, nftnl_expr_fullcone_cb, tb) < 0) -+ return -1; -+ -+ if (tb[NFTA_FULLCONE_FLAGS]) { -+ fullcone->flags = be32toh(mnl_attr_get_u32(tb[NFTA_FULLCONE_FLAGS])); -+ e->flags |= (1 << NFTNL_EXPR_FULLCONE_FLAGS); -+ } -+ if (tb[NFTA_FULLCONE_REG_PROTO_MIN]) { -+ fullcone->sreg_proto_min = -+ be32toh(mnl_attr_get_u32(tb[NFTA_FULLCONE_REG_PROTO_MIN])); -+ e->flags |= (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MIN); -+ } -+ if (tb[NFTA_FULLCONE_REG_PROTO_MAX]) { -+ fullcone->sreg_proto_max = -+ be32toh(mnl_attr_get_u32(tb[NFTA_FULLCONE_REG_PROTO_MAX])); -+ e->flags |= (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MAX); -+ } -+ -+ return 0; -+} -+ -+static int nftnl_expr_fullcone_snprintf(char *buf, size_t remain, -+ uint32_t flags, const struct nftnl_expr *e) -+{ -+ struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e); -+ int offset = 0, ret = 0; -+ -+ if (e->flags & (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MIN)) { -+ ret = snprintf(buf + offset, remain, "proto_min reg %u ", -+ fullcone->sreg_proto_min); -+ SNPRINTF_BUFFER_SIZE(ret, remain, offset); -+ } -+ if (e->flags & (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MAX)) { -+ ret = snprintf(buf + offset, remain, "proto_max reg %u ", -+ fullcone->sreg_proto_max); -+ SNPRINTF_BUFFER_SIZE(ret, remain, offset); -+ } -+ if (e->flags & (1 << NFTNL_EXPR_FULLCONE_FLAGS)) { -+ ret = snprintf(buf + offset, remain, "flags 0x%x ", fullcone->flags); -+ SNPRINTF_BUFFER_SIZE(ret, remain, offset); -+ } -+ -+ return offset; -+} -+ -+struct expr_ops expr_ops_fullcone = { -+ .name = "fullcone", -+ .alloc_len = sizeof(struct nftnl_expr_fullcone), -+ .max_attr = NFTA_FULLCONE_MAX, -+ .set = nftnl_expr_fullcone_set, -+ .get = nftnl_expr_fullcone_get, -+ .parse = nftnl_expr_fullcone_parse, -+ .build = nftnl_expr_fullcone_build, -+ .output = nftnl_expr_fullcone_snprintf, -+}; ---- a/src/expr_ops.c -+++ b/src/expr_ops.c -@@ -20,6 +20,7 @@ extern struct expr_ops expr_ops_limit; - extern struct expr_ops expr_ops_log; - extern struct expr_ops expr_ops_lookup; - extern struct expr_ops expr_ops_masq; -+extern struct expr_ops expr_ops_fullcone; - extern struct expr_ops expr_ops_match; - extern struct expr_ops expr_ops_meta; - extern struct expr_ops expr_ops_ng; -@@ -65,6 +66,7 @@ static struct expr_ops *expr_ops[] = { - &expr_ops_log, - &expr_ops_lookup, - &expr_ops_masq, -+ &expr_ops_fullcone, - &expr_ops_match, - &expr_ops_meta, - &expr_ops_ng, diff --git a/package/network/config/firewall4/Makefile b/package/network/config/firewall4/Makefile index d1ae642ab103e9..7f1058b8d491fc 100644 --- a/package/network/config/firewall4/Makefile +++ b/package/network/config/firewall4/Makefile @@ -23,7 +23,8 @@ define Package/firewall4 TITLE:=OpenWrt 4th gen firewall DEPENDS:= \ +kmod-nft-core +kmod-nft-fib +kmod-nft-offload \ - +kmod-nft-nat +nftables-json \ + +kmod-nft-nat \ + +nftables-json \ +ucode +ucode-mod-fs +ucode-mod-ubus +ucode-mod-uci EXTRA_DEPENDS:=ucode (>=2022.03.22) PROVIDES:=uci-firewall diff --git a/package/network/config/firewall4/patches/001-firewall4-Add-fullcone-support.patch b/package/network/config/firewall4/patches/001-firewall4-Add-fullcone-support.patch deleted file mode 100644 index 46ae728786df1b..00000000000000 --- a/package/network/config/firewall4/patches/001-firewall4-Add-fullcone-support.patch +++ /dev/null @@ -1,215 +0,0 @@ -From aa3b56e289fba7425e649a608c333622ffd9c367 Mon Sep 17 00:00:00 2001 -From: Syrone Wong -Date: Sat, 9 Apr 2022 13:24:19 +0800 -Subject: [PATCH] firewall4: add fullcone support - -fullcone is drop-in replacement of masq for non-udp traffic - -add runtime fullcone rule check, disable it globally if fullcone expr is -invalid - -defaults.fullcone and defaults.fullcone6 are switches for IPv4 and IPv6 -respectively, most IPv6 traffic do NOT need this FullCone NAT functionality. - -Renew: ZiMing Mo ---- - root/etc/config/firewall | 2 ++ - root/usr/share/firewall4/templates/ruleset.uc | 16 ++++++++++++++-- - .../firewall4/templates/zone-fullcone.uc | 4 ++++ - root/usr/share/ucode/fw4.uc | 69 ++++++++++++++++++- - 4 files changed, 89 insertions(+), 4 deletions(-) - create mode 100644 root/usr/share/firewall4/templates/zone-fullcone.uc - ---- a/root/etc/config/firewall -+++ b/root/etc/config/firewall -@@ -5,6 +5,9 @@ config defaults - option forward REJECT - # Uncomment this line to disable ipv6 rules - # option disable_ipv6 1 -+ option flow_offloading 0 -+ option fullcone 0 -+ option fullcone6 0 - - config zone - option name lan ---- a/root/usr/share/firewall4/templates/ruleset.uc -+++ b/root/usr/share/firewall4/templates/ruleset.uc -@@ -327,6 +327,12 @@ table inet fw4 { - {% for (let redirect in fw4.redirects(`dstnat_${zone.name}`)): %} - {%+ include("redirect.uc", { fw4, zone, redirect }) %} - {% endfor %} -+{% if (zone.masq && fw4.default_option("fullcone")): %} -+ {%+ include("zone-fullcone.uc", { fw4, zone, family: 4, direction: "dstnat" }) %} -+{% endif %} -+{% if (zone.masq6 && fw4.default_option("fullcone6")): %} -+ {%+ include("zone-fullcone.uc", { fw4, zone, family: 6, direction: "dstnat" }) %} -+{% endif %} - {% fw4.includes('chain-append', `dstnat_${zone.name}`) %} - } - -@@ -337,20 +343,26 @@ table inet fw4 { - {% for (let redirect in fw4.redirects(`srcnat_${zone.name}`)): %} - {%+ include("redirect.uc", { fw4, zone, redirect }) %} - {% endfor %} --{% if (zone.masq): %} -+{% if (zone.masq && !fw4.default_option("fullcone")): %} - {% for (let saddrs in zone.masq4_src_subnets): %} - {% for (let daddrs in zone.masq4_dest_subnets): %} - {%+ include("zone-masq.uc", { fw4, zone, family: 4, saddrs, daddrs }) %} - {% endfor %} - {% endfor %} - {% endif %} --{% if (zone.masq6): %} -+{% if (zone.masq6 && !fw4.default_option("fullcone6")): %} - {% for (let saddrs in zone.masq6_src_subnets): %} - {% for (let daddrs in zone.masq6_dest_subnets): %} - {%+ include("zone-masq.uc", { fw4, zone, family: 6, saddrs, daddrs }) %} - {% endfor %} - {% endfor %} - {% endif %} -+{% if (zone.masq && fw4.default_option("fullcone")): %} -+ {%+ include("zone-fullcone.uc", { fw4, zone, family: 4, direction: "srcnat" }) %} -+{% endif %} -+{% if (zone.masq6 && fw4.default_option("fullcone6")): %} -+ {%+ include("zone-fullcone.uc", { fw4, zone, family: 6, direction: "srcnat" }) %} -+{% endif %} - {% fw4.includes('chain-append', `srcnat_${zone.name}`) %} - } - ---- /dev/null -+++ b/root/usr/share/firewall4/templates/zone-fullcone.uc -@@ -0,0 +1,4 @@ -+{# /usr/share/firewall4/templates/zone-fullcone.uc #} -+ meta nfproto {{ fw4.nfproto(family) }} fullcone comment "!fw4: Handle {{ -+ zone.name -+}} {{ fw4.nfproto(family, true) }} fullcone NAT {{ direction }} traffic" ---- a/root/usr/share/ucode/fw4.uc -+++ b/root/usr/share/ucode/fw4.uc -@@ -1,3 +1,5 @@ -+// /usr/share/ucode/fw4.uc -+ - const fs = require("fs"); - const uci = require("uci"); - const ubus = require("ubus"); -@@ -489,6 +491,25 @@ function nft_try_hw_offload(devices) { - return (rc == 0); - } - -+function nft_try_fullcone() { -+ let nft_test = -+ 'add table inet fw4-fullcone-test; ' + -+ 'add chain inet fw4-fullcone-test dstnat { ' + -+ 'type nat hook prerouting priority -100; policy accept; ' + -+ 'fullcone; ' + -+ '}; ' + -+ 'add chain inet fw4-fullcone-test srcnat { ' + -+ 'type nat hook postrouting priority -100; policy accept; ' + -+ 'fullcone; ' + -+ '}; '; -+ let cmd = sprintf("/usr/sbin/nft -c '%s' 2>/dev/null", replace(nft_test, "'", "'\\''")); -+ let ok = system(cmd) == 0; -+ if (!ok) { -+ warn("nft_try_fullcone: cmd "+ cmd + "\n"); -+ } -+ return ok; -+} -+ - - return { - read_kernel_version: function() { -@@ -832,6 +853,18 @@ return { - warn(`[!] ${msg}\n`); - }, - -+ myinfo: function(fmt, ...args) { -+ if (getenv("QUIET")) -+ return; -+ -+ let msg = sprintf(fmt, ...args); -+ -+ if (getenv("TTY")) -+ warn(`\033[32m${msg}\033[m\n`); -+ else -+ warn(`[I] ${msg}\n`); -+ }, -+ - get: function(sid, opt) { - return this.cursor.get("firewall", sid, opt); - }, -@@ -1013,6 +1046,21 @@ return { - } - }, - -+ myinfo_section: function(s, msg) { -+ if (s[".name"]) { -+ if (s.name) -+ this.myinfo("Section %s (%s) %s", this.section_id(s[".name"]), s.name, msg); -+ else -+ this.myinfo("Section %s %s", this.section_id(s[".name"]), msg); -+ } -+ else { -+ if (s.name) -+ this.myinfo("ubus %s (%s) %s", s.type || "rule", s.name, msg); -+ else -+ this.myinfo("ubus %s %s", s.type || "rule", msg); -+ } -+ }, -+ - parse_policy: function(val) { - return this.parse_enum(val, [ - "accept", -@@ -1452,6 +1500,7 @@ return { - "dnat", - "snat", - "masquerade", -+ "fullcone", - "accept", - "reject", - "drop" -@@ -1923,6 +1972,8 @@ return { - } - - let defs = this.parse_options(data, { -+ fullcone: [ "bool", "0" ], -+ fullcone6: [ "bool", "0" ], - input: [ "policy", "drop" ], - output: [ "policy", "drop" ], - forward: [ "policy", "drop" ], -@@ -1957,6 +2008,11 @@ return { - - delete defs.syn_flood; - -+ if (!nft_try_fullcone()) { -+ delete defs.fullcone; -+ warn("nft_try_fullcone failed, disable fullcone globally\n"); -+ } -+ - this.state.defaults = defs; - }, - -@@ -2182,10 +2238,23 @@ return { - zone.related_subnets = related_subnets; - zone.related_physdevs = related_physdevs; - -- if (zone.masq || zone.masq6) -+ if (zone.masq) { - zone.dflags.snat = true; -+ if (this.state.defaults.fullcone) { -+ zone.dflags.dnat = true; -+ this.myinfo_section(data, "IPv4 fullcone enabled for zone '" + zone.name + "'"); -+ } -+ } -+ -+ if (zone.masq6) { -+ zone.dflags.snat = true; -+ if (this.state.defaults.fullcone6) { -+ zone.dflags.dnat = true; -+ this.myinfo_section(data, "IPv6 fullcone enabled for zone '" + zone.name + "'"); -+ } -+ } - -- if ((zone.auto_helper && !(zone.masq || zone.masq6)) || length(zone.helper)) { -+ if ((zone.auto_helper && !(zone.masq || zone.masq6 || this.state.defaults.fullcone || this.state.defaults.fullcone6)) || length(zone.helper)) { - zone.dflags.helper = true; - - for (let helper in (length(zone.helper) ? zone.helper : this.state.helpers)) { diff --git a/package/network/utils/fullconenat-nft/Makefile b/package/network/utils/fullconenat-nft/Makefile deleted file mode 100644 index 7f9276de8c100d..00000000000000 --- a/package/network/utils/fullconenat-nft/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# Copyright (c) 2018 Chion Tang -# Original xt_FULLCONENAT and related iptables extension author -# Copyright (c) 2019-2022 GitHub/llccd Twitter/@gNodeB -# Added IPv6 support for xt_FULLCONENAT and ip6tables extension -# Ported to recent kernel versions -# Copyright (c) 2022 Syrone Wong -# Massively rewrite the whole module, split the original code into library and nftables 'fullcone' expression module - -include $(TOPDIR)/rules.mk -include $(INCLUDE_DIR)/kernel.mk - -PKG_NAME:=fullconenat-nft -PKG_RELEASE:=1 - -PKG_SOURCE_PROTO:=git -PKG_SOURCE_URL:=https://github.com/fullcone-nat-nftables/nft-fullcone.git -PKG_SOURCE_DATE:=2023-01-10 -PKG_SOURCE_VERSION:=95ad79bc6d15c64b2770fe8b7092a64d5c2a293c -PKG_MIRROR_HASH:=37ff8a27ce5e2e38820fba366de30c930d33cf20030e28086778aef62961d335 - -PKG_LICENSE:=GPL-2.0-only -PKG_LICENSE_FILES:=LICENSE -PKG_MAINTAINER:=Syrone Wong - -include $(INCLUDE_DIR)/package.mk - -define KernelPackage/nft-fullcone - SUBMENU:=Netfilter Extensions - DEPENDS:=+kmod-nft-nat - TITLE:=nftables fullcone expression support - FILES:= $(PKG_BUILD_DIR)/src/nft_fullcone.ko - KCONFIG:= \ - CONFIG_NF_CONNTRACK_EVENTS=y \ - CONFIG_NF_CONNTRACK_CHAIN_EVENTS=n - AUTOLOAD:=$(call AutoProbe,nft_fullcone) -endef - -define KernelPackage/nft-fullcone/Description - Kernel module adds the fullcone expression that you can use - to perform NAT in the RFC3489-compatible full cone SNAT flavour. - Currently only UDP traffic is supported for full-cone NAT. - For other protos FULLCONENAT is equivalent to MASQUERADE. -endef - -define Build/Compile - +$(KERNEL_MAKE) M="$(PKG_BUILD_DIR)/src" modules -endef - -$(eval $(call KernelPackage,nft-fullcone)) diff --git a/package/network/utils/nftables/patches/0001-nftables-Add-fullcone-expression-support.patch b/package/network/utils/nftables/patches/0001-nftables-Add-fullcone-expression-support.patch deleted file mode 100644 index 4d9eb8a0d674c9..00000000000000 --- a/package/network/utils/nftables/patches/0001-nftables-Add-fullcone-expression-support.patch +++ /dev/null @@ -1,208 +0,0 @@ -From 58c89e8768711a959fdc6e953df3ea2254ff93c1 Mon Sep 17 00:00:00 2001 -From: Syrone Wong -Date: Sat, 9 Apr 2022 00:38:51 +0800 -Subject: [PATCH] nftables: add fullcone expression support - -Signed-off-by: Syrone Wong ---- - include/linux/netfilter/nf_tables.h | 16 ++++++++++ - include/statement.h | 1 + - src/netlink_delinearize.c | 48 +++++++++++++++++++++++++++++ - src/netlink_linearize.c | 7 +++++ - src/parser_bison.y | 28 +++++++++++++++-- - src/scanner.l | 1 + - src/statement.c | 1 + - 7 files changed, 100 insertions(+), 2 deletions(-) - ---- a/include/linux/netfilter/nf_tables.h -+++ b/include/linux/netfilter/nf_tables.h -@@ -1485,6 +1485,22 @@ enum nft_masq_attributes { - #define NFTA_MASQ_MAX (__NFTA_MASQ_MAX - 1) - - /** -+ * enum nft_fullcone_attributes - nf_tables fullcone expression attributes -+ * -+ * @NFTA_FULLCONE_FLAGS: NAT flags (see NF_NAT_RANGE_* in linux/netfilter/nf_nat.h) (NLA_U32) -+ * @NFTA_FULLCONE_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers) -+ * @NFTA_FULLCONE_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers) -+ */ -+enum nft_fullcone_attributes { -+ NFTA_FULLCONE_UNSPEC, -+ NFTA_FULLCONE_FLAGS, -+ NFTA_FULLCONE_REG_PROTO_MIN, -+ NFTA_FULLCONE_REG_PROTO_MAX, -+ __NFTA_FULLCONE_MAX -+}; -+#define NFTA_FULLCONE_MAX (__NFTA_FULLCONE_MAX - 1) -+ -+/** - * enum nft_redir_attributes - nf_tables redirect expression netlink attributes - * - * @NFTA_REDIR_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers) ---- a/include/statement.h -+++ b/include/statement.h -@@ -129,6 +129,7 @@ enum nft_nat_etypes { - __NFT_NAT_SNAT = NFT_NAT_SNAT, - __NFT_NAT_DNAT = NFT_NAT_DNAT, - NFT_NAT_MASQ, -+ NFT_NAT_FULLCONE, - NFT_NAT_REDIR, - }; - ---- a/src/netlink_delinearize.c -+++ b/src/netlink_delinearize.c -@@ -1473,6 +1473,53 @@ out_err: - stmt_free(stmt); - } - -+static void netlink_parse_fullcone(struct netlink_parse_ctx *ctx, -+ const struct location *loc, -+ const struct nftnl_expr *nle) -+{ -+ enum nft_registers reg1, reg2; -+ struct expr *proto; -+ struct stmt *stmt; -+ uint32_t flags = 0; -+ -+ if (nftnl_expr_is_set(nle, NFTNL_EXPR_FULLCONE_FLAGS)) -+ flags = nftnl_expr_get_u32(nle, NFTNL_EXPR_FULLCONE_FLAGS); -+ -+ stmt = nat_stmt_alloc(loc, NFT_NAT_FULLCONE); -+ stmt->nat.flags = flags; -+ -+ reg1 = netlink_parse_register(nle, NFTNL_EXPR_FULLCONE_REG_PROTO_MIN); -+ if (reg1) { -+ proto = netlink_get_register(ctx, loc, reg1); -+ if (proto == NULL) { -+ netlink_error(ctx, loc, -+ "fullcone statement has no proto expression"); -+ goto out_err; -+ } -+ expr_set_type(proto, &inet_service_type, BYTEORDER_BIG_ENDIAN); -+ stmt->nat.proto = proto; -+ } -+ -+ reg2 = netlink_parse_register(nle, NFTNL_EXPR_FULLCONE_REG_PROTO_MAX); -+ if (reg2 && reg2 != reg1) { -+ proto = netlink_get_register(ctx, loc, reg2); -+ if (proto == NULL) { -+ netlink_error(ctx, loc, -+ "fullcone statement has no proto expression"); -+ goto out_err; -+ } -+ expr_set_type(proto, &inet_service_type, BYTEORDER_BIG_ENDIAN); -+ if (stmt->nat.proto != NULL) -+ proto = range_expr_alloc(loc, stmt->nat.proto, proto); -+ stmt->nat.proto = proto; -+ } -+ -+ ctx->stmt = stmt; -+ return; -+out_err: -+ stmt_free(stmt); -+} -+ - static void netlink_parse_redir(struct netlink_parse_ctx *ctx, - const struct location *loc, - const struct nftnl_expr *nle) -@@ -1901,6 +1948,7 @@ static const struct expr_handler netlink - { .name = "tproxy", .parse = netlink_parse_tproxy }, - { .name = "notrack", .parse = netlink_parse_notrack }, - { .name = "masq", .parse = netlink_parse_masq }, -+ { .name = "fullcone", .parse = netlink_parse_fullcone }, - { .name = "redir", .parse = netlink_parse_redir }, - { .name = "dup", .parse = netlink_parse_dup }, - { .name = "queue", .parse = netlink_parse_queue }, ---- a/src/netlink_linearize.c -+++ b/src/netlink_linearize.c -@@ -1221,6 +1221,13 @@ static void netlink_gen_nat_stmt(struct - nftnl_reg_pmin = NFTNL_EXPR_MASQ_REG_PROTO_MIN; - nftnl_reg_pmax = NFTNL_EXPR_MASQ_REG_PROTO_MAX; - break; -+ case NFT_NAT_FULLCONE: -+ nle = alloc_nft_expr("fullcone"); -+ -+ nftnl_flag_attr = NFTNL_EXPR_FULLCONE_FLAGS; -+ nftnl_reg_pmin = NFTNL_EXPR_FULLCONE_REG_PROTO_MIN; -+ nftnl_reg_pmax = NFTNL_EXPR_FULLCONE_REG_PROTO_MAX; -+ break; - case NFT_NAT_REDIR: - nle = alloc_nft_expr("redir"); - ---- a/src/parser_bison.y -+++ b/src/parser_bison.y -@@ -621,6 +621,7 @@ int nft_lex(void *, void *, void *); - %token SNAT "snat" - %token DNAT "dnat" - %token MASQUERADE "masquerade" -+%token FULLCONE "fullcone" - %token REDIRECT "redirect" - %token RANDOM "random" - %token FULLY_RANDOM "fully-random" -@@ -755,8 +756,8 @@ int nft_lex(void *, void *, void *); - %type limit_burst_pkts limit_burst_bytes limit_mode limit_bytes time_unit quota_mode - %type reject_stmt reject_stmt_alloc - %destructor { stmt_free($$); } reject_stmt reject_stmt_alloc --%type nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc redir_stmt redir_stmt_alloc --%destructor { stmt_free($$); } nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc redir_stmt redir_stmt_alloc -+%type nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc fullcone_stmt fullcone_stmt_alloc redir_stmt redir_stmt_alloc -+%destructor { stmt_free($$); } nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc fullcone_stmt fullcone_stmt_alloc redir_stmt redir_stmt_alloc - %type nf_nat_flags nf_nat_flag offset_opt - %type tproxy_stmt - %destructor { stmt_free($$); } tproxy_stmt -@@ -3064,6 +3065,7 @@ stmt : verdict_stmt - | queue_stmt - | ct_stmt - | masq_stmt close_scope_nat -+ | fullcone_stmt close_scope_nat - | redir_stmt close_scope_nat - | dup_stmt close_scope_dup - | fwd_stmt close_scope_fwd -@@ -3976,6 +3978,28 @@ masq_stmt_args : TO COLON stmt_expr - { - $0->nat.proto = $3; - } -+ | TO COLON stmt_expr nf_nat_flags -+ { -+ $0->nat.proto = $3; -+ $0->nat.flags = $4; -+ } -+ | nf_nat_flags -+ { -+ $0->nat.flags = $1; -+ } -+ ; -+ -+fullcone_stmt : fullcone_stmt_alloc fullcone_stmt_args -+ | fullcone_stmt_alloc -+ ; -+ -+fullcone_stmt_alloc : FULLCONE { $$ = nat_stmt_alloc(&@$, NFT_NAT_FULLCONE); } -+ ; -+ -+fullcone_stmt_args : TO COLON stmt_expr -+ { -+ $0->nat.proto = $3; -+ } - | TO COLON stmt_expr nf_nat_flags - { - $0->nat.proto = $3; ---- a/src/scanner.l -+++ b/src/scanner.l -@@ -460,6 +460,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr - "snat" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return SNAT; } - "dnat" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return DNAT; } - "masquerade" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return MASQUERADE; } -+"fullcone" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return FULLCONE; } - "redirect" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return REDIRECT; } - "random" { return RANDOM; } - { ---- a/src/statement.c -+++ b/src/statement.c -@@ -681,6 +681,7 @@ const char *nat_etype2str(enum nft_nat_e - [NFT_NAT_SNAT] = "snat", - [NFT_NAT_DNAT] = "dnat", - [NFT_NAT_MASQ] = "masquerade", -+ [NFT_NAT_FULLCONE] = "fullcone", - [NFT_NAT_REDIR] = "redirect", - }; From 1a2708ab482952bae4875cb9bb27202a1468a314 Mon Sep 17 00:00:00 2001 From: Sean Khan Date: Sat, 30 Mar 2024 16:40:05 -0400 Subject: [PATCH 173/225] Revert "package: fullconenat" This reverts commit 248cd3a623ee3e14da204de0752e61bf9dd8b066. --- package/network/config/firewall/Makefile | 6 +- .../config/firewall/files/firewall.config | 2 - .../config/firewall/patches/fullconenat.patch | 63 ---------------- package/network/utils/fullconenat/Makefile | 71 ------------------- .../fullconenat/patches/000-printk.patch | 19 ----- .../network/utils/fullconenat/src/Makefile | 12 ---- 6 files changed, 2 insertions(+), 171 deletions(-) delete mode 100644 package/network/config/firewall/patches/fullconenat.patch delete mode 100644 package/network/utils/fullconenat/Makefile delete mode 100644 package/network/utils/fullconenat/patches/000-printk.patch delete mode 100644 package/network/utils/fullconenat/src/Makefile diff --git a/package/network/config/firewall/Makefile b/package/network/config/firewall/Makefile index 6ba077b4d1dcdf..3306dde319188c 100644 --- a/package/network/config/firewall/Makefile +++ b/package/network/config/firewall/Makefile @@ -30,9 +30,7 @@ define Package/firewall SECTION:=net CATEGORY:=Base system TITLE:=OpenWrt C Firewall - DEPENDS:=+libubox +libubus +libuci +libip4tc +IPV6:libip6tc +libiptext +IPV6:libiptext6 \ - +libxtables +kmod-ipt-core +kmod-ipt-conntrack +IPV6:kmod-nf-conntrack6 +kmod-ipt-nat \ - +iptables-mod-fullconenat + DEPENDS:=+libubox +libubus +libuci +libip4tc +IPV6:libip6tc +libiptext +IPV6:libiptext6 +libxtables +kmod-ipt-core +kmod-ipt-conntrack +IPV6:kmod-nf-conntrack6 +kmod-ipt-nat PROVIDES:=uci-firewall CONFLICTS:=firewall4 endef @@ -63,4 +61,4 @@ define Package/firewall/install $(INSTALL_CONF) $(PKG_BUILD_DIR)/helpers.conf $(1)/usr/share/fw3 endef -$(eval $(call BuildPackage,firewall)) \ No newline at end of file +$(eval $(call BuildPackage,firewall)) diff --git a/package/network/config/firewall/files/firewall.config b/package/network/config/firewall/files/firewall.config index b694b8cb308b05..b90ac7af0a382c 100644 --- a/package/network/config/firewall/files/firewall.config +++ b/package/network/config/firewall/files/firewall.config @@ -3,8 +3,6 @@ config defaults option input REJECT option output ACCEPT option forward REJECT - option flow_offloading 0 - option fullcone 1 # Uncomment this line to disable ipv6 rules # option disable_ipv6 1 diff --git a/package/network/config/firewall/patches/fullconenat.patch b/package/network/config/firewall/patches/fullconenat.patch deleted file mode 100644 index d69e7129ec7ebd..00000000000000 --- a/package/network/config/firewall/patches/fullconenat.patch +++ /dev/null @@ -1,63 +0,0 @@ -index 85a3750..9fac9b1 100644 ---- a/defaults.c -+++ b/defaults.c -@@ -46,7 +46,9 @@ const struct fw3_option fw3_flag_opts[] = { - FW3_OPT("synflood_protect", bool, defaults, syn_flood), - FW3_OPT("synflood_rate", limit, defaults, syn_flood_rate), - FW3_OPT("synflood_burst", int, defaults, syn_flood_rate.burst), -- -+ -+ FW3_OPT("fullcone", bool, defaults, fullcone), -+ - FW3_OPT("tcp_syncookies", bool, defaults, tcp_syncookies), - FW3_OPT("tcp_ecn", int, defaults, tcp_ecn), - FW3_OPT("tcp_window_scaling", bool, defaults, tcp_window_scaling), -diff --git a/options.h b/options.h -index 6edd174..c02eb97 100644 ---- a/options.h -+++ b/options.h -@@ -267,6 +267,7 @@ struct fw3_defaults - bool drop_invalid; - - bool syn_flood; -+ bool fullcone; - struct fw3_limit syn_flood_rate; - - bool tcp_syncookies; -diff --git a/zones.c b/zones.c -index 2aa7473..57eead0 100644 ---- a/zones.c -+++ b/zones.c -@@ -627,6 +627,7 @@ print_zone_rule(struct fw3_ipt_handle *h - struct fw3_address *msrc; - struct fw3_address *mdest; - struct fw3_ipt_rule *r; -+ struct fw3_defaults *defs = &state->defaults; - - if (!fw3_is_family(zone, handle->family)) - return; -@@ -712,8 +713,22 @@ print_zone_rule(struct fw3_ipt_handle *h - { - r = fw3_ipt_rule_new(handle); - fw3_ipt_rule_src_dest(r, msrc, mdest); -- fw3_ipt_rule_target(r, "MASQUERADE"); -- fw3_ipt_rule_append(r, "zone_%s_postrouting", zone->name); -+ /*FIXME: Workaround for FULLCONE-NAT*/ -+ if(defs->fullcone) -+ { -+ warn("%s will enable FULLCONE-NAT", zone->name); -+ fw3_ipt_rule_target(r, "FULLCONENAT"); -+ fw3_ipt_rule_append(r, "zone_%s_postrouting", zone->name); -+ r = fw3_ipt_rule_new(handle); -+ fw3_ipt_rule_src_dest(r, msrc, mdest); -+ fw3_ipt_rule_target(r, "FULLCONENAT"); -+ fw3_ipt_rule_append(r, "zone_%s_prerouting", zone->name); -+ } -+ else -+ { -+ fw3_ipt_rule_target(r, "MASQUERADE"); -+ fw3_ipt_rule_append(r, "zone_%s_postrouting", zone->name); -+ } - } - } - } diff --git a/package/network/utils/fullconenat/Makefile b/package/network/utils/fullconenat/Makefile deleted file mode 100644 index d0771f7a84215a..00000000000000 --- a/package/network/utils/fullconenat/Makefile +++ /dev/null @@ -1,71 +0,0 @@ -# -# Copyright (C) 2018 Chion Tang -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk -include $(INCLUDE_DIR)/kernel.mk - -PKG_NAME:=fullconenat -PKG_RELEASE:=1 - -PKG_SOURCE_PROTO:=git -PKG_SOURCE_URL:=https://github.com/llccd/netfilter-full-cone-nat.git -PKG_SOURCE_DATE:=2023-01-01 -PKG_SOURCE_VERSION:=74c5e6f3c7faaf33ece451697537c81781781c20 -PKG_MIRROR_HASH:=3c254f1edba28eafdccac9cf95eb550fd2b05eeaaec8a02c73e1dcd2f98f9d93 - -PKG_LICENSE:=GPL-2.0 -PKG_LICENSE_FILES:=LICENSE -PKG_MAINTAINER:=Chion Tang - -include $(INCLUDE_DIR)/package.mk - -define Package/iptables-mod-fullconenat - SUBMENU:=Firewall - SECTION:=net - CATEGORY:=Network - TITLE:=FULLCONENAT iptables extension - DEPENDS:=+iptables +kmod-ipt-fullconenat -endef - -define Package/ip6tables-mod-fullconenat - SUBMENU:=Firewall - SECTION:=net - CATEGORY:=Network - TITLE:=FULLCONENAT ip6tables extension - DEPENDS:=ip6tables +kmod-nf-nat6 +kmod-ipt-fullconenat +ip6tables-mod-nat -endef - -define KernelPackage/ipt-fullconenat - SUBMENU:=Netfilter Extensions - TITLE:=FULLCONENAT netfilter module - DEPENDS:=+kmod-nf-ipt +kmod-nf-nat - KCONFIG:= \ - CONFIG_NF_CONNTRACK_EVENTS=y \ - CONFIG_NF_CONNTRACK_CHAIN_EVENTS=n - FILES:=$(PKG_BUILD_DIR)/xt_FULLCONENAT.ko -endef - -include $(INCLUDE_DIR)/kernel-defaults.mk - -define Build/Compile - +$(KERNEL_MAKE) M="$(PKG_BUILD_DIR)" modules - $(call Build/Compile/Default) -endef - -define Package/iptables-mod-fullconenat/install - $(INSTALL_DIR) $(1)/usr/lib/iptables - $(INSTALL_BIN) $(PKG_BUILD_DIR)/libipt_FULLCONENAT.so $(1)/usr/lib/iptables -endef - -define Package/ip6tables-mod-fullconenat/install - $(INSTALL_DIR) $(1)/usr/lib/iptables - $(INSTALL_BIN) $(PKG_BUILD_DIR)/libip6t_FULLCONENAT.so $(1)/usr/lib/iptables -endef - -$(eval $(call BuildPackage,iptables-mod-fullconenat)) -$(eval $(call BuildPackage,ip6tables-mod-fullconenat)) -$(eval $(call KernelPackage,ipt-fullconenat)) diff --git a/package/network/utils/fullconenat/patches/000-printk.patch b/package/network/utils/fullconenat/patches/000-printk.patch deleted file mode 100644 index 251d10f5ddc204..00000000000000 --- a/package/network/utils/fullconenat/patches/000-printk.patch +++ /dev/null @@ -1,19 +0,0 @@ -diff --git a/xt_FULLCONENAT.c b/xt_FULLCONENAT.c -index 30e7686..492f638 100644 ---- a/xt_FULLCONENAT.c -+++ b/xt_FULLCONENAT.c -@@ -1345,9 +1345,13 @@ static struct xt_target tg_reg[] __read_mostly = { - static int __init fullconenat_tg_init(void) - { - int ret; -+ -+ printk(KERN_INFO "xt_FULLCONENAT: RFC3489 Full Cone NAT module\n" -+ "xt_FULLCONENAT: Copyright (C) 2018 Chion Tang \n"); -+ - wq = create_singlethread_workqueue("xt_FULLCONENAT"); - if (wq == NULL) { -- printk("xt_FULLCONENAT: warning: failed to create workqueue\n"); -+ printk(KERN_WARNING "xt_FULLCONENAT: warning: failed to create workqueue\n"); - } - - #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) diff --git a/package/network/utils/fullconenat/src/Makefile b/package/network/utils/fullconenat/src/Makefile deleted file mode 100644 index a48a513daf60ab..00000000000000 --- a/package/network/utils/fullconenat/src/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -all: libipt_FULLCONENAT.so libip6t_FULLCONENAT.so - -libipt_FULLCONENAT.so: libipt_FULLCONENAT.o - $(CC) -shared -lxtables -o $@ $^; -libipt_FULLCONENAT.o: libipt_FULLCONENAT.c - $(CC) ${CFLAGS} -fPIC -c -o $@ $<; -libip6t_FULLCONENAT.so: libip6t_FULLCONENAT.o - $(CC) -shared -lxtables -o $@ $^; -libip6t_FULLCONENAT.o: libip6t_FULLCONENAT.c - $(CC) ${CFLAGS} -fPIC -c -o $@ $<; - -obj-m += xt_FULLCONENAT.o From a7e3ef68c8da5c6c7b652cdbe4969b54dcde5d40 Mon Sep 17 00:00:00 2001 From: Sean Khan Date: Sun, 31 Mar 2024 16:23:23 -0400 Subject: [PATCH 174/225] kernel: bump 6.1 to 6.1.83 Removed because they are upstream: target/linux/generic/pending-6.1/735-net-mediatek-mtk_eth_soc-release-MAC_MCR_FORCE_LINK-.patch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-6.1.y&id=448cc8b5f743985f6d1d98aa4efb386fef4c3bf2 generic/pending-5.15/736-net-ethernet-mtk_eth_soc-fix-PPE-hanging-issue.patch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-6.1.y&id=9fcadd125044007351905d40c405fadc2d3bb6d6 --- include/kernel-6.1 | 4 +- ..._eth_soc-release-MAC_MCR_FORCE_LINK-.patch | 50 ---------------- ...et-mtk_eth_soc-fix-PPE-hanging-issue.patch | 59 ------------------- 3 files changed, 2 insertions(+), 111 deletions(-) delete mode 100644 target/linux/generic/pending-6.1/735-net-mediatek-mtk_eth_soc-release-MAC_MCR_FORCE_LINK-.patch delete mode 100644 target/linux/generic/pending-6.1/736-net-ethernet-mtk_eth_soc-fix-PPE-hanging-issue.patch diff --git a/include/kernel-6.1 b/include/kernel-6.1 index 0c09df7a7deff9..101dbf34faaff3 100644 --- a/include/kernel-6.1 +++ b/include/kernel-6.1 @@ -1,2 +1,2 @@ -LINUX_VERSION-6.1 = .82 -LINUX_KERNEL_HASH-6.1.82 = d150d2d9d416877668d8b56f75759f166168d192419eefaa942ed67225cbec06 +LINUX_VERSION-6.1 = .83 +LINUX_KERNEL_HASH-6.1.83 = 88b69611093613ce4494527685f833af0c31b986dcbeda7086f69f18f9e0b190 diff --git a/target/linux/generic/pending-6.1/735-net-mediatek-mtk_eth_soc-release-MAC_MCR_FORCE_LINK-.patch b/target/linux/generic/pending-6.1/735-net-mediatek-mtk_eth_soc-release-MAC_MCR_FORCE_LINK-.patch deleted file mode 100644 index 2f7d29b84d495a..00000000000000 --- a/target/linux/generic/pending-6.1/735-net-mediatek-mtk_eth_soc-release-MAC_MCR_FORCE_LINK-.patch +++ /dev/null @@ -1,50 +0,0 @@ -From ef5976ae4e117fae9a61bb3c0f8319a917a425ea Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 11 Mar 2024 17:43:28 +0000 -Subject: [PATCH] net: mediatek: mtk_eth_soc: release MAC_MCR_FORCE_LINK only when MAC is up -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Clearing bit MAC_MCR_FORCE_LINK which forces the link down too early -can result in MAC ending up in a broken/blocked state. - -Fix this by handling this bit in the .mac_link_up and .mac_link_down -calls instead of in .mac_finish. - -Fixes: b8fc9f30821ec ("net: ethernet: mediatek: Add basic PHYLINK support") -Signed-off-by: Daniel Golle ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -662,8 +662,7 @@ static int mtk_mac_finish(struct phylink - mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); - mcr_new = mcr_cur; - mcr_new |= MAC_MCR_IPG_CFG | MAC_MCR_FORCE_MODE | -- MAC_MCR_BACKOFF_EN | MAC_MCR_BACKPR_EN | MAC_MCR_FORCE_LINK | -- MAC_MCR_RX_FIFO_CLR_DIS; -+ MAC_MCR_BACKOFF_EN | MAC_MCR_BACKPR_EN | MAC_MCR_RX_FIFO_CLR_DIS; - - /* Only update control register when needed! */ - if (mcr_new != mcr_cur) -@@ -679,7 +678,7 @@ static void mtk_mac_link_down(struct phy - phylink_config); - u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); - -- mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN); -+ mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK); - mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); - } - -@@ -788,7 +787,7 @@ static void mtk_mac_link_up(struct phyli - if (rx_pause) - mcr |= MAC_MCR_FORCE_RX_FC; - -- mcr |= MAC_MCR_TX_EN | MAC_MCR_RX_EN; -+ mcr |= MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK; - mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); - } - diff --git a/target/linux/generic/pending-6.1/736-net-ethernet-mtk_eth_soc-fix-PPE-hanging-issue.patch b/target/linux/generic/pending-6.1/736-net-ethernet-mtk_eth_soc-fix-PPE-hanging-issue.patch deleted file mode 100644 index 3b190c180158d7..00000000000000 --- a/target/linux/generic/pending-6.1/736-net-ethernet-mtk_eth_soc-fix-PPE-hanging-issue.patch +++ /dev/null @@ -1,59 +0,0 @@ -From c8262ebbf7ca546dd5ead3c0383a89eb401627ff Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 13 Mar 2024 17:55:02 +0000 -Subject: [PATCH] net: ethernet: mtk_eth_soc: fix PPE hanging issue - -A patch to resolve an issue was found in MediaTek's GPL-licensed SDK: -In the mtk_ppe_stop() function, the PPE scan mode is not disabled before -disabling the PPE. This can potentially lead to a hang during the process -of disabling the PPE. - -Without this patch, the PPE may experience a hang during the reboot test. - -Reference: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/b40da332dfe763932a82f9f62a4709457a15dd6c - -Suggested-by: Bc-bocun Chen -Signed-off-by: Daniel Golle ---- - drivers/net/ethernet/mediatek/mtk_ppe.c | 18 +++++++++++------- - 1 file changed, 11 insertions(+), 7 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -1002,7 +1002,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe) - MTK_PPE_KEEPALIVE_DISABLE) | - FIELD_PREP(MTK_PPE_TB_CFG_HASH_MODE, 1) | - FIELD_PREP(MTK_PPE_TB_CFG_SCAN_MODE, -- MTK_PPE_SCAN_MODE_KEEPALIVE_AGE) | -+ MTK_PPE_SCAN_MODE_CHECK_AGE) | - FIELD_PREP(MTK_PPE_TB_CFG_ENTRY_NUM, - MTK_PPE_ENTRIES_SHIFT); - if (mtk_is_netsys_v2_or_greater(ppe->eth)) -@@ -1098,17 +1098,21 @@ int mtk_ppe_stop(struct mtk_ppe *ppe) - - mtk_ppe_cache_enable(ppe, false); - -- /* disable offload engine */ -- ppe_clear(ppe, MTK_PPE_GLO_CFG, MTK_PPE_GLO_CFG_EN); -- ppe_w32(ppe, MTK_PPE_FLOW_CFG, 0); -- - /* disable aging */ - val = MTK_PPE_TB_CFG_AGE_NON_L4 | - MTK_PPE_TB_CFG_AGE_UNBIND | - MTK_PPE_TB_CFG_AGE_TCP | - MTK_PPE_TB_CFG_AGE_UDP | -- MTK_PPE_TB_CFG_AGE_TCP_FIN; -+ MTK_PPE_TB_CFG_AGE_TCP_FIN | -+ MTK_PPE_TB_CFG_SCAN_MODE; - ppe_clear(ppe, MTK_PPE_TB_CFG, val); - -- return mtk_ppe_wait_busy(ppe); -+ if (mtk_ppe_wait_busy(ppe)) -+ return -ETIMEDOUT; -+ -+ /* disable offload engine */ -+ ppe_clear(ppe, MTK_PPE_GLO_CFG, MTK_PPE_GLO_CFG_EN); -+ ppe_w32(ppe, MTK_PPE_FLOW_CFG, 0); -+ -+ return 0; - } From 803d80e6eba4bea6b990fc3d0b1965d640491066 Mon Sep 17 00:00:00 2001 From: Sean Khan Date: Sun, 31 Mar 2024 19:16:29 -0400 Subject: [PATCH 175/225] qualcommax: disable swiotlb for 64mb in saving. Disable software input output translation lookaside buffer (swiotlb) as it wastes memory on low memory platforms (512m or less) --- ...com-disable-swiotlb-for-64mb-savings.patch | 198 ++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.6/9991-arm64-dts-qcom-disable-swiotlb-for-64mb-savings.patch diff --git a/target/linux/qualcommax/patches-6.6/9991-arm64-dts-qcom-disable-swiotlb-for-64mb-savings.patch b/target/linux/qualcommax/patches-6.6/9991-arm64-dts-qcom-disable-swiotlb-for-64mb-savings.patch new file mode 100644 index 00000000000000..c0606f73eb5561 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/9991-arm64-dts-qcom-disable-swiotlb-for-64mb-savings.patch @@ -0,0 +1,198 @@ +--- a/arch/arm64/boot/dts/qcom/ipq6010-wax214.dts ++++ b/arch/arm64/boot/dts/qcom/ipq6010-wax214.dts +@@ -25,7 +25,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " root=/dev/ubiblock0_1"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_1"; + }; + + keys { +--- a/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts ++++ b/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts +@@ -27,7 +27,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " root=/dev/ubiblock0_1"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_1"; + }; + + keys { +--- a/arch/arm64/boot/dts/qcom/ipq8070-rm2-6.dts ++++ b/arch/arm64/boot/dts/qcom/ipq8070-rm2-6.dts +@@ -32,7 +32,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " root=/dev/ubiblock0_1"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_1"; + }; + + keys { +--- a/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi +@@ -20,7 +20,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " root=/dev/ubiblock0_0"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_0"; + }; + + keys { +--- a/arch/arm64/boot/dts/qcom/ipq8071-eap102.dts ++++ b/arch/arm64/boot/dts/qcom/ipq8071-eap102.dts +@@ -30,7 +30,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " root=/dev/ubiblock0_1"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_1"; + }; + + keys { +--- a/arch/arm64/boot/dts/qcom/ipq8071-mf269.dts ++++ b/arch/arm64/boot/dts/qcom/ipq8071-mf269.dts +@@ -24,7 +24,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " root=/dev/ubiblock0_0"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_0"; + }; + + keys { +--- a/arch/arm64/boot/dts/qcom/ipq8072-aw1000.dts ++++ b/arch/arm64/boot/dts/qcom/ipq8072-aw1000.dts +@@ -34,7 +34,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " root=/dev/ubiblock0_1"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_1"; + }; + + gpio-export { +--- a/arch/arm64/boot/dts/qcom/ipq8072-ax880.dts ++++ b/arch/arm64/boot/dts/qcom/ipq8072-ax880.dts +@@ -29,7 +29,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " root=/dev/ubiblock0_1"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_1"; + }; + + keys { +--- a/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts ++++ b/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts +@@ -26,7 +26,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " root=/dev/ubiblock0_0"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_0"; + }; + + keys { +--- a/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts ++++ b/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts +@@ -32,7 +32,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " root=/dev/ubiblock0_1"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_1"; + }; + + keys { +--- a/arch/arm64/boot/dts/qcom/ipq8072-mx5300.dts ++++ b/arch/arm64/boot/dts/qcom/ipq8072-mx5300.dts +@@ -32,7 +32,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " root=/dev/ubiblock0_0 rootfstype=squashfs ro"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_0 rootfstype=squashfs ro"; + }; + + keys { +--- a/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts ++++ b/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts +@@ -27,7 +27,7 @@ + * Netgear's U-Boot adds "ubi.mtd=rootfs root=mtd:ubi_rootfs" + * That fails to create a UBI block device, so add it here. + */ +- bootargs-append = " ubi.block=0,rootfs root=/dev/ubiblock0_1"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce ubi.block=0,rootfs root=/dev/ubiblock0_1"; + }; + + keys { +--- a/arch/arm64/boot/dts/qcom/ipq8072-wax620.dts ++++ b/arch/arm64/boot/dts/qcom/ipq8072-wax620.dts +@@ -28,7 +28,7 @@ + * Netgear's U-Boot adds "ubi.mtd=rootfs root=mtd:ubi_rootfs" + * That fails to create a UBI block device, so add it here. + */ +- bootargs-append = " root=/dev/ubiblock0_1"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_1"; + }; + + keys { +--- a/arch/arm64/boot/dts/qcom/ipq8072-wpq873.dts ++++ b/arch/arm64/boot/dts/qcom/ipq8072-wpq873.dts +@@ -31,7 +31,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " root=/dev/ubiblock0_1"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_1"; + }; + + keys { +--- a/arch/arm64/boot/dts/qcom/ipq8074-rax120v2.dts ++++ b/arch/arm64/boot/dts/qcom/ipq8074-rax120v2.dts +@@ -25,7 +25,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " ubi.mtd=rootfs root=/dev/ubiblock0_0"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce ubi.mtd=rootfs root=/dev/ubiblock0_0"; + }; + + keys { +--- a/arch/arm64/boot/dts/qcom/ipq8074-wax630.dts ++++ b/arch/arm64/boot/dts/qcom/ipq8074-wax630.dts +@@ -29,7 +29,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " root=/dev/ubiblock0_1"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_1"; + }; + + keys { +--- a/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts ++++ b/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts +@@ -25,7 +25,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " ubi.mtd=user_property root=/dev/ubiblock1_0"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce ubi.mtd=user_property root=/dev/ubiblock1_0"; + }; + + leds { +--- a/arch/arm64/boot/dts/qcom/ipq8174-mx4200.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq8174-mx4200.dtsi +@@ -29,7 +29,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " root=/dev/ubiblock0_0"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_0"; + }; + + keys { From e19f1914a6c9faee6ac088a16d3dc77d663cde3e Mon Sep 17 00:00:00 2001 From: Sean Khan Date: Sun, 31 Mar 2024 19:22:43 -0400 Subject: [PATCH 176/225] qca-nss-dp: use cp instead of symlink for `nss_dp_arch.h` Build files shouldn't be symlinked in the staging directory, as doing so would create a race condition if the build folder for 'qca-nss-dp' was deleted for any reason. --- package/kernel/qca-nss-dp/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/kernel/qca-nss-dp/Makefile b/package/kernel/qca-nss-dp/Makefile index e17446d23634c4..167a9af4e4c385 100644 --- a/package/kernel/qca-nss-dp/Makefile +++ b/package/kernel/qca-nss-dp/Makefile @@ -39,7 +39,7 @@ EXTRA_CFLAGS+= \ NSS_DP_HAL_DIR:=$(PKG_BUILD_DIR)/hal define Build/Configure - $(LN) $(NSS_DP_HAL_DIR)/soc_ops/$(CONFIG_TARGET_SUBTARGET)/nss_$(CONFIG_TARGET_SUBTARGET).h \ + $(CP) $(NSS_DP_HAL_DIR)/soc_ops/$(CONFIG_TARGET_SUBTARGET)/nss_$(CONFIG_TARGET_SUBTARGET).h \ $(PKG_BUILD_DIR)/exports/nss_dp_arch.h endef From de28b67f31e4b459acbd9abf803f168ee91803a6 Mon Sep 17 00:00:00 2001 From: Sean Khan Date: Sun, 31 Mar 2024 21:46:20 -0400 Subject: [PATCH 177/225] qualcommax: only disable swiotlb for platforms <= 512M Disabling swiotlb is only required for platforms with 512M or less to save 64mb. --- ...com-disable-swiotlb-for-64mb-savings.patch | 99 ------------------- 1 file changed, 99 deletions(-) diff --git a/target/linux/qualcommax/patches-6.6/9991-arm64-dts-qcom-disable-swiotlb-for-64mb-savings.patch b/target/linux/qualcommax/patches-6.6/9991-arm64-dts-qcom-disable-swiotlb-for-64mb-savings.patch index c0606f73eb5561..bb610079aad154 100644 --- a/target/linux/qualcommax/patches-6.6/9991-arm64-dts-qcom-disable-swiotlb-for-64mb-savings.patch +++ b/target/linux/qualcommax/patches-6.6/9991-arm64-dts-qcom-disable-swiotlb-for-64mb-savings.patch @@ -41,17 +41,6 @@ + bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_0"; }; - keys { ---- a/arch/arm64/boot/dts/qcom/ipq8071-eap102.dts -+++ b/arch/arm64/boot/dts/qcom/ipq8071-eap102.dts -@@ -30,7 +30,7 @@ - - chosen { - stdout-path = "serial0:115200n8"; -- bootargs-append = " root=/dev/ubiblock0_1"; -+ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_1"; - }; - keys { --- a/arch/arm64/boot/dts/qcom/ipq8071-mf269.dts +++ b/arch/arm64/boot/dts/qcom/ipq8071-mf269.dts @@ -64,17 +53,6 @@ }; keys { ---- a/arch/arm64/boot/dts/qcom/ipq8072-aw1000.dts -+++ b/arch/arm64/boot/dts/qcom/ipq8072-aw1000.dts -@@ -34,7 +34,7 @@ - - chosen { - stdout-path = "serial0:115200n8"; -- bootargs-append = " root=/dev/ubiblock0_1"; -+ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_1"; - }; - - gpio-export { --- a/arch/arm64/boot/dts/qcom/ipq8072-ax880.dts +++ b/arch/arm64/boot/dts/qcom/ipq8072-ax880.dts @@ -29,7 +29,7 @@ @@ -85,39 +63,6 @@ + bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_1"; }; - keys { ---- a/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts -+++ b/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts -@@ -26,7 +26,7 @@ - - chosen { - stdout-path = "serial0:115200n8"; -- bootargs-append = " root=/dev/ubiblock0_0"; -+ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_0"; - }; - - keys { ---- a/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts -+++ b/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts -@@ -32,7 +32,7 @@ - - chosen { - stdout-path = "serial0:115200n8"; -- bootargs-append = " root=/dev/ubiblock0_1"; -+ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_1"; - }; - - keys { ---- a/arch/arm64/boot/dts/qcom/ipq8072-mx5300.dts -+++ b/arch/arm64/boot/dts/qcom/ipq8072-mx5300.dts -@@ -32,7 +32,7 @@ - - chosen { - stdout-path = "serial0:115200n8"; -- bootargs-append = " root=/dev/ubiblock0_0 rootfstype=squashfs ro"; -+ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_0 rootfstype=squashfs ro"; - }; - keys { --- a/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts +++ b/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts @@ -129,17 +74,6 @@ + bootargs-append = " coherent_pool=2M swiotlb=noforce ubi.block=0,rootfs root=/dev/ubiblock0_1"; }; - keys { ---- a/arch/arm64/boot/dts/qcom/ipq8072-wax620.dts -+++ b/arch/arm64/boot/dts/qcom/ipq8072-wax620.dts -@@ -28,7 +28,7 @@ - * Netgear's U-Boot adds "ubi.mtd=rootfs root=mtd:ubi_rootfs" - * That fails to create a UBI block device, so add it here. - */ -- bootargs-append = " root=/dev/ubiblock0_1"; -+ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_1"; - }; - keys { --- a/arch/arm64/boot/dts/qcom/ipq8072-wpq873.dts +++ b/arch/arm64/boot/dts/qcom/ipq8072-wpq873.dts @@ -152,39 +86,6 @@ }; keys { ---- a/arch/arm64/boot/dts/qcom/ipq8074-rax120v2.dts -+++ b/arch/arm64/boot/dts/qcom/ipq8074-rax120v2.dts -@@ -25,7 +25,7 @@ - - chosen { - stdout-path = "serial0:115200n8"; -- bootargs-append = " ubi.mtd=rootfs root=/dev/ubiblock0_0"; -+ bootargs-append = " coherent_pool=2M swiotlb=noforce ubi.mtd=rootfs root=/dev/ubiblock0_0"; - }; - - keys { ---- a/arch/arm64/boot/dts/qcom/ipq8074-wax630.dts -+++ b/arch/arm64/boot/dts/qcom/ipq8074-wax630.dts -@@ -29,7 +29,7 @@ - - chosen { - stdout-path = "serial0:115200n8"; -- bootargs-append = " root=/dev/ubiblock0_1"; -+ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_1"; - }; - - keys { ---- a/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts -+++ b/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts -@@ -25,7 +25,7 @@ - - chosen { - stdout-path = "serial0:115200n8"; -- bootargs-append = " ubi.mtd=user_property root=/dev/ubiblock1_0"; -+ bootargs-append = " coherent_pool=2M swiotlb=noforce ubi.mtd=user_property root=/dev/ubiblock1_0"; - }; - - leds { --- a/arch/arm64/boot/dts/qcom/ipq8174-mx4200.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq8174-mx4200.dtsi @@ -29,7 +29,7 @@ From 021d42c57b93a101cf3c10dd841a88637ddfc074 Mon Sep 17 00:00:00 2001 From: Sean Khan Date: Thu, 4 Apr 2024 22:14:16 -0400 Subject: [PATCH 178/225] hostapd: switch to upstream branch to prevent breaking --- ...hannels-to-be-selected-if-dfs-is-ena.patch | 28 +- ...erministic-channel-on-channel-switch.patch | 6 +- ...ix-sta-add-after-previous-connection.patch | 8 +- ...ewrite-neigh-code-to-not-depend-on-l.patch | 18 +- ...ssing-authentication-frames-in-block.patch | 2 +- .../patches/050-Fix-OpenWrt-13156.patch | 63 ++ ...-extra-ies-only-if-allowed-by-driver.patch | 62 ++ ...edtls-TLS-crypto-option-initial-port.patch | 40 +- .../patches/120-mbedtls-fips186_2_prf.patch | 4 +- .../135-mbedtls-fix-owe-association.patch | 14 +- ...efile-make-run-tests-with-CONFIG_TLS.patch | 166 ++--- ...tapd-update-cfs0-and-cfs1-for-160MHz.patch | 24 +- ...pdate-drv-ifindex-on-removing-the-fi.patch | 2 +- ...0211_put_freq_params-call-outside-of.patch | 8 +- ...hannel_list_update_timeout-in-hostap.patch | 4 +- .../hostapd/patches/200-multicall.patch | 281 +++---- .../patches/201-lto-jobserver-support.patch | 64 ++ ...duplicate-_DIRS-before-calling-mkdir.patch | 23 + ..._AP-functions-dependant-on-CONFIG_AP.patch | 33 + ...ion-of-WLAN_SUPP_RATES_MAX-to-defs.h.patch | 56 ++ .../213-wpa_supplicant-fix-warnings.patch | 32 + .../patches/220-indicate-features.patch | 69 ++ .../patches/250-hostapd_cli_ifdef.patch | 61 ++ .../hostapd/patches/251-wpa_cli_ifdef.patch | 22 + .../patches/252-disable_ctrl_iface_mib.patch | 243 ++++++ ...253-qos_map_set_without_interworking.patch | 103 +++ .../services/hostapd/patches/300-noscan.patch | 11 +- .../hostapd/patches/301-mesh-noscan.patch | 45 +- .../patches/310-rescan_immediately.patch | 7 +- .../hostapd/patches/320-optional_rfkill.patch | 4 + .../patches/330-nl80211_fix_set_freq.patch | 7 +- .../341-mesh-ctrl-iface-channel-switch.patch | 19 +- .../patches/350-nl80211_del_beacon_bss.patch | 13 +- .../381-hostapd_cli_UNKNOWN-COMMAND.patch | 13 +- .../400-wps_single_auth_enc_type.patch | 7 + .../patches/410-limit_debug_messages.patch | 5 + ...dd-new-config-params-to-be-used-with.patch | 29 +- .../patches/463-add-mcast_rate-to-11s.patch | 6 +- .../patches/464-fix-mesh-obss-check.patch | 7 +- ...tapd-config-support-random-BSS-color.patch | 2 +- .../patches/470-survey_data_fallback.patch | 8 +- .../patches/590-rrm-wnm-statistics.patch | 46 +- .../hostapd/patches/600-ubus_support.patch | 691 +++++++++--------- .../hostapd/patches/601-ucode_support.patch | 553 +++++++------- .../610-hostapd_cli_ujail_permission.patch | 40 + .../patches/701-reload_config_inline.patch | 10 +- .../hostapd/patches/710-vlan_no_bridge.patch | 30 +- .../patches/711-wds_bridge_force.patch | 15 +- .../patches/720-iface_max_num_sta.patch | 72 +- .../hostapd/patches/730-ft_iface.patch | 12 +- .../hostapd/patches/740-snoop_iface.patch | 70 +- .../751-qos_map_ignore_when_unsupported.patch | 9 +- .../hostapd/patches/760-dynamic_own_ip.patch | 65 +- .../hostapd/patches/761-shared_das_port.patch | 29 +- .../hostapd/patches/770-radius_server.patch | 10 +- 55 files changed, 2152 insertions(+), 1119 deletions(-) create mode 100644 package/network/services/hostapd/patches/050-Fix-OpenWrt-13156.patch create mode 100644 package/network/services/hostapd/patches/051-nl80211-add-extra-ies-only-if-allowed-by-driver.patch create mode 100644 package/network/services/hostapd/patches/201-lto-jobserver-support.patch create mode 100644 package/network/services/hostapd/patches/210-build-de-duplicate-_DIRS-before-calling-mkdir.patch create mode 100644 package/network/services/hostapd/patches/211-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch create mode 100644 package/network/services/hostapd/patches/212-Move-definition-of-WLAN_SUPP_RATES_MAX-to-defs.h.patch create mode 100644 package/network/services/hostapd/patches/213-wpa_supplicant-fix-warnings.patch create mode 100644 package/network/services/hostapd/patches/220-indicate-features.patch create mode 100644 package/network/services/hostapd/patches/250-hostapd_cli_ifdef.patch create mode 100644 package/network/services/hostapd/patches/251-wpa_cli_ifdef.patch create mode 100644 package/network/services/hostapd/patches/252-disable_ctrl_iface_mib.patch create mode 100644 package/network/services/hostapd/patches/253-qos_map_set_without_interworking.patch diff --git a/package/network/services/hostapd/patches/010-mesh-Allow-DFS-channels-to-be-selected-if-dfs-is-ena.patch b/package/network/services/hostapd/patches/010-mesh-Allow-DFS-channels-to-be-selected-if-dfs-is-ena.patch index 0a51c84d2158b2..4291f015180c53 100644 --- a/package/network/services/hostapd/patches/010-mesh-Allow-DFS-channels-to-be-selected-if-dfs-is-ena.patch +++ b/package/network/services/hostapd/patches/010-mesh-Allow-DFS-channels-to-be-selected-if-dfs-is-ena.patch @@ -9,12 +9,12 @@ Note: DFS is assumed to be usable if a country code has been set Signed-off-by: Benjamin Berg Signed-off-by: Peter Oh --- - wpa_supplicant/wpa_supplicant.c | 25 +++++++++++++++++++------ - 1 file changed, 19 insertions(+), 6 deletions(-) + wpa_supplicant/wpa_supplicant.c | 38 ++++++++++++++++++++++----------- + 1 file changed, 25 insertions(+), 13 deletions(-) --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c -@@ -2638,7 +2638,7 @@ static int drv_supports_vht(struct wpa_s +@@ -2698,7 +2698,7 @@ static int drv_supports_vht(struct wpa_s } @@ -23,7 +23,7 @@ Signed-off-by: Peter Oh { int i; -@@ -2647,7 +2647,10 @@ static bool ibss_mesh_is_80mhz_avail(int +@@ -2707,7 +2707,10 @@ static bool ibss_mesh_is_80mhz_avail(int chan = hw_get_channel_chan(mode, i, NULL); if (!chan || @@ -35,7 +35,7 @@ Signed-off-by: Peter Oh return false; } -@@ -2774,7 +2777,7 @@ static void ibss_mesh_select_40mhz(struc +@@ -2834,7 +2837,7 @@ static void ibss_mesh_select_40mhz(struc const struct wpa_ssid *ssid, struct hostapd_hw_modes *mode, struct hostapd_freq_params *freq, @@ -44,7 +44,7 @@ Signed-off-by: Peter Oh int chan_idx; struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL; int i, res; -@@ -2798,8 +2801,11 @@ static void ibss_mesh_select_40mhz(struc +@@ -2858,8 +2861,11 @@ static void ibss_mesh_select_40mhz(struc return; /* Check primary channel flags */ @@ -57,7 +57,7 @@ Signed-off-by: Peter Oh #ifdef CONFIG_HT_OVERRIDES if (ssid->disable_ht40) -@@ -2825,8 +2831,11 @@ static void ibss_mesh_select_40mhz(struc +@@ -2885,8 +2891,11 @@ static void ibss_mesh_select_40mhz(struc return; /* Check secondary channel flags */ @@ -70,7 +70,7 @@ Signed-off-by: Peter Oh if (ht40 == -1) { if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS)) -@@ -2880,7 +2889,7 @@ static bool ibss_mesh_select_80_160mhz(s +@@ -2940,7 +2949,7 @@ static bool ibss_mesh_select_80_160mhz(s const struct wpa_ssid *ssid, struct hostapd_hw_modes *mode, struct hostapd_freq_params *freq, @@ -79,7 +79,7 @@ Signed-off-by: Peter Oh static const int bw80[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5825, 5955, 6035, 6115, 6195, 6275, 6355, 6435, -@@ -2925,7 +2934,7 @@ static bool ibss_mesh_select_80_160mhz(s +@@ -2985,7 +2994,7 @@ static bool ibss_mesh_select_80_160mhz(s goto skip_80mhz; /* Use 40 MHz if channel not usable */ @@ -88,7 +88,7 @@ Signed-off-by: Peter Oh goto skip_80mhz; chwidth = CONF_OPER_CHWIDTH_80MHZ; -@@ -2939,7 +2948,7 @@ static bool ibss_mesh_select_80_160mhz(s +@@ -2999,7 +3008,7 @@ static bool ibss_mesh_select_80_160mhz(s if ((mode->he_capab[ieee80211_mode].phy_cap[ HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] & HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G) && is_6ghz && @@ -97,7 +97,7 @@ Signed-off-by: Peter Oh for (j = 0; j < ARRAY_SIZE(bw160); j++) { if (freq->freq == bw160[j]) { chwidth = CONF_OPER_CHWIDTH_160MHZ; -@@ -2967,10 +2976,12 @@ static bool ibss_mesh_select_80_160mhz(s +@@ -3027,10 +3036,12 @@ static bool ibss_mesh_select_80_160mhz(s if (!chan) continue; @@ -113,15 +113,15 @@ Signed-off-by: Peter Oh /* Found a suitable second segment for 80+80 */ chwidth = CONF_OPER_CHWIDTH_80P80MHZ; -@@ -3025,6 +3036,7 @@ void ibss_mesh_setup_freq(struct wpa_sup +@@ -3085,6 +3096,7 @@ void ibss_mesh_setup_freq(struct wpa_sup int i, obss_scan = 1; u8 channel; - bool is_6ghz; + bool is_6ghz, is_24ghz; + bool dfs_enabled = wpa_s->conf->country[0] && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_RADAR); freq->freq = ssid->frequency; -@@ -3070,9 +3082,9 @@ void ibss_mesh_setup_freq(struct wpa_sup +@@ -3133,9 +3145,9 @@ void ibss_mesh_setup_freq(struct wpa_sup freq->channel = channel; /* Setup higher BW only for 5 GHz */ if (mode->mode == HOSTAPD_MODE_IEEE80211A) { diff --git a/package/network/services/hostapd/patches/011-mesh-use-deterministic-channel-on-channel-switch.patch b/package/network/services/hostapd/patches/011-mesh-use-deterministic-channel-on-channel-switch.patch index 07b7a5971d3e00..a53fcc480c6586 100644 --- a/package/network/services/hostapd/patches/011-mesh-use-deterministic-channel-on-channel-switch.patch +++ b/package/network/services/hostapd/patches/011-mesh-use-deterministic-channel-on-channel-switch.patch @@ -64,11 +64,11 @@ Signed-off-by: Markus Theil return NULL; + chan_idx = _rand % num_available_chandefs; - dfs_find_channel(iface, &chan, chan_idx, type); - if (!chan) { + wpa_printf(MSG_DEBUG, "DFS: Picked random entry from the list: %d/%d", + chan_idx, num_available_chandefs); --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c -@@ -11017,6 +11017,10 @@ static int nl80211_switch_channel(void * +@@ -11195,6 +11195,10 @@ static int nl80211_switch_channel(void * if (ret) goto error; diff --git a/package/network/services/hostapd/patches/021-fix-sta-add-after-previous-connection.patch b/package/network/services/hostapd/patches/021-fix-sta-add-after-previous-connection.patch index 227c580552d479..a4a90933b17d61 100644 --- a/package/network/services/hostapd/patches/021-fix-sta-add-after-previous-connection.patch +++ b/package/network/services/hostapd/patches/021-fix-sta-add-after-previous-connection.patch @@ -1,6 +1,10 @@ +From: Felix Fietkau +Date: Tue, 25 May 2021 10:50:16 +0200 +Subject: [PATCH] fix adding back stations after a missed deauth/disassoc + --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c -@@ -4616,6 +4616,13 @@ static int add_associated_sta(struct hos +@@ -4659,6 +4659,13 @@ static int add_associated_sta(struct hos * drivers to accept the STA parameter configuration. Since this is * after a new FT-over-DS exchange, a new TK has been derived, so key * reinstallation is not a concern for this case. @@ -14,7 +18,7 @@ */ wpa_printf(MSG_DEBUG, "Add associated STA " MACSTR " (added_unassoc=%d auth_alg=%u ft_over_ds=%u reassoc=%d authorized=%d ft_tk=%d fils_tk=%d)", -@@ -4629,7 +4636,8 @@ static int add_associated_sta(struct hos +@@ -4672,7 +4679,8 @@ static int add_associated_sta(struct hos (!(sta->flags & WLAN_STA_AUTHORIZED) || (reassoc && sta->ft_over_ds && sta->auth_alg == WLAN_AUTH_FT) || (!wpa_auth_sta_ft_tk_already_set(sta->wpa_sm) && diff --git a/package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch b/package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch index ba1f6e6c23c8cd..c5cf8b1b7985d4 100644 --- a/package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch +++ b/package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch @@ -10,17 +10,17 @@ Signed-off-by: Felix Fietkau --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c -@@ -16,9 +16,6 @@ - #include +@@ -18,9 +18,6 @@ #include #include + #include -#ifdef CONFIG_LIBNL3_ROUTE -#include -#endif /* CONFIG_LIBNL3_ROUTE */ #include #include #include -@@ -5783,26 +5780,29 @@ fail: +@@ -5859,26 +5856,29 @@ fail: static void rtnl_neigh_delete_fdb_entry(struct i802_bss *bss, const u8 *addr) { @@ -64,7 +64,7 @@ Signed-off-by: Felix Fietkau if (err < 0) { wpa_printf(MSG_DEBUG, "nl80211: bridge FDB entry delete for " MACSTR " ifindex=%d failed: %s", MAC2STR(addr), -@@ -5812,9 +5812,8 @@ static void rtnl_neigh_delete_fdb_entry( +@@ -5888,9 +5888,8 @@ static void rtnl_neigh_delete_fdb_entry( MACSTR, MAC2STR(addr)); } @@ -76,7 +76,7 @@ Signed-off-by: Felix Fietkau } -@@ -8492,7 +8491,6 @@ static void *i802_init(struct hostapd_da +@@ -8615,7 +8614,6 @@ static void *i802_init(struct hostapd_da (params->num_bridge == 0 || !params->bridge[0])) add_ifidx(drv, br_ifindex, drv->ifindex); @@ -84,7 +84,7 @@ Signed-off-by: Felix Fietkau if (bss->added_if_into_bridge || bss->already_in_bridge) { int err; -@@ -8509,7 +8507,6 @@ static void *i802_init(struct hostapd_da +@@ -8632,7 +8630,6 @@ static void *i802_init(struct hostapd_da goto failed; } } @@ -92,7 +92,7 @@ Signed-off-by: Felix Fietkau if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) { wpa_printf(MSG_DEBUG, -@@ -11893,13 +11890,14 @@ static int wpa_driver_br_add_ip_neigh(vo +@@ -12071,13 +12068,14 @@ static int wpa_driver_br_add_ip_neigh(vo const u8 *ipaddr, int prefixlen, const u8 *addr) { @@ -112,7 +112,7 @@ Signed-off-by: Felix Fietkau int res; if (!ipaddr || prefixlen == 0 || !addr) -@@ -11918,85 +11916,66 @@ static int wpa_driver_br_add_ip_neigh(vo +@@ -12096,85 +12094,66 @@ static int wpa_driver_br_add_ip_neigh(vo } if (version == 4) { @@ -220,7 +220,7 @@ Signed-off-by: Felix Fietkau addrsize = 16; } else { return -EINVAL; -@@ -12014,41 +11993,30 @@ static int wpa_driver_br_delete_ip_neigh +@@ -12192,41 +12171,30 @@ static int wpa_driver_br_delete_ip_neigh return -1; } diff --git a/package/network/services/hostapd/patches/040-mesh-allow-processing-authentication-frames-in-block.patch b/package/network/services/hostapd/patches/040-mesh-allow-processing-authentication-frames-in-block.patch index b7bf9e351e08b5..636ec2d9c8b7c7 100644 --- a/package/network/services/hostapd/patches/040-mesh-allow-processing-authentication-frames-in-block.patch +++ b/package/network/services/hostapd/patches/040-mesh-allow-processing-authentication-frames-in-block.patch @@ -16,7 +16,7 @@ Signed-off-by: Felix Fietkau --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c -@@ -3020,15 +3020,6 @@ static void handle_auth(struct hostapd_d +@@ -3032,15 +3032,6 @@ static void handle_auth(struct hostapd_d seq_ctrl); return; } diff --git a/package/network/services/hostapd/patches/050-Fix-OpenWrt-13156.patch b/package/network/services/hostapd/patches/050-Fix-OpenWrt-13156.patch new file mode 100644 index 00000000000000..a044409d2d813a --- /dev/null +++ b/package/network/services/hostapd/patches/050-Fix-OpenWrt-13156.patch @@ -0,0 +1,63 @@ +From 26cd9bafc1d25e602952ee86cd2a5b8c3a995490 Mon Sep 17 00:00:00 2001 +From: Stijn Tintel +Date: Fri, 28 Jul 2023 16:27:47 +0300 +Subject: [PATCH] Revert "Do prune_association only after the STA is + authorized" + +Commit e978072baaca ("Do prune_association only after the STA is +authorized") causes issues when an STA roams from one interface to +another interface on the same PHY. The mt7915 driver is not able to +handle this properly. While the commits fixes a DoS, there are other +devices and drivers with the same limitation, so revert to the orginal +behavior for now, until we have a better solution in place. + +Ref: https://github.com/openwrt/openwrt/issues/13156 +Signed-off-by: Stijn Tintel +--- + src/ap/hostapd.c | 14 +++++++++++--- + src/ap/sta_info.c | 3 --- + 2 files changed, 11 insertions(+), 6 deletions(-) + +--- a/src/ap/hostapd.c ++++ b/src/ap/hostapd.c +@@ -3646,6 +3646,8 @@ int hostapd_remove_iface(struct hapd_int + void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, + int reassoc) + { ++ int mld_assoc_link_id = -1; ++ + if (hapd->tkip_countermeasures) { + hostapd_drv_sta_deauth(hapd, sta->addr, + WLAN_REASON_MICHAEL_MIC_FAILURE); +@@ -3653,10 +3655,16 @@ void hostapd_new_assoc_sta(struct hostap + } + + #ifdef CONFIG_IEEE80211BE +- if (ap_sta_is_mld(hapd, sta) && +- sta->mld_assoc_link_id != hapd->mld_link_id) +- return; ++ if (ap_sta_is_mld(hapd, sta)) { ++ if (sta->mld_assoc_link_id == hapd->mld_link_id) { ++ mld_assoc_link_id = sta->mld_assoc_link_id; ++ } else { ++ return; ++ } ++ } + #endif /* CONFIG_IEEE80211BE */ ++ if (mld_assoc_link_id != -2) ++ hostapd_prune_associations(hapd, sta->addr, mld_assoc_link_id); + + ap_sta_clear_disconnect_timeouts(hapd, sta); + sta->post_csa_sa_query = 0; +--- a/src/ap/sta_info.c ++++ b/src/ap/sta_info.c +@@ -1412,9 +1412,6 @@ bool ap_sta_set_authorized_flag(struct h + mld_assoc_link_id = -2; + } + #endif /* CONFIG_IEEE80211BE */ +- if (mld_assoc_link_id != -2) +- hostapd_prune_associations(hapd, sta->addr, +- mld_assoc_link_id); + sta->flags |= WLAN_STA_AUTHORIZED; + } else { + sta->flags &= ~WLAN_STA_AUTHORIZED; diff --git a/package/network/services/hostapd/patches/051-nl80211-add-extra-ies-only-if-allowed-by-driver.patch b/package/network/services/hostapd/patches/051-nl80211-add-extra-ies-only-if-allowed-by-driver.patch new file mode 100644 index 00000000000000..de4d4ad3c2461c --- /dev/null +++ b/package/network/services/hostapd/patches/051-nl80211-add-extra-ies-only-if-allowed-by-driver.patch @@ -0,0 +1,62 @@ +From: David Bauer +To: hostap@lists.infradead.org +Cc: =?utf-8?q?=C3=89tienne_Morice?= +Subject: [PATCH] nl80211: add extra-ies only if allowed by driver +Date: Sun, 30 Jan 2022 20:22:00 +0100 +Message-Id: <20220130192200.10883-1-mail@david-bauer.net> +List-Id: + +Upgrading wpa_supplicant from 2.9 to 2.10 breaks broadcom-wl +based adapters. The reason for it is hostapd tries to install additional +IEs for scanning while the driver does not support this. + +The kernel indicates the maximum number of bytes for additional scan IEs +using the NL80211_ATTR_MAX_SCAN_IE_LEN attribute. Save this value and +only add additional scan IEs in case the driver can accommodate these +additional IEs. + +Reported-by: Étienne Morice +Tested-by: Étienne Morice +Signed-off-by: David Bauer +--- + src/drivers/driver.h | 3 +++ + src/drivers/driver_nl80211_capa.c | 4 ++++ + src/drivers/driver_nl80211_scan.c | 2 +- + 3 files changed, 8 insertions(+), 1 deletion(-) + +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -2340,6 +2340,9 @@ struct wpa_driver_capa { + /** Maximum number of iterations in a single scan plan */ + u32 max_sched_scan_plan_iterations; + ++ /** Maximum number of extra IE bytes for scans */ ++ u16 max_scan_ie_len; ++ + /** Whether sched_scan (offloaded scanning) is supported */ + int sched_scan_supported; + +--- a/src/drivers/driver_nl80211_capa.c ++++ b/src/drivers/driver_nl80211_capa.c +@@ -972,6 +972,10 @@ static int wiphy_info_handler(struct nl_ + nla_get_u32(tb[NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS]); + } + ++ if (tb[NL80211_ATTR_MAX_SCAN_IE_LEN]) ++ capa->max_scan_ie_len = ++ nla_get_u16(tb[NL80211_ATTR_MAX_SCAN_IE_LEN]); ++ + if (tb[NL80211_ATTR_MAX_MATCH_SETS]) + capa->max_match_sets = + nla_get_u8(tb[NL80211_ATTR_MAX_MATCH_SETS]); +--- a/src/drivers/driver_nl80211_scan.c ++++ b/src/drivers/driver_nl80211_scan.c +@@ -221,7 +221,7 @@ nl80211_scan_common(struct i802_bss *bss + wpa_printf(MSG_DEBUG, "nl80211: Passive scan requested"); + } + +- if (params->extra_ies) { ++ if (params->extra_ies && drv->capa.max_scan_ie_len >= params->extra_ies_len) { + wpa_hexdump(MSG_MSGDUMP, "nl80211: Scan extra IEs", + params->extra_ies, params->extra_ies_len); + if (nla_put(msg, NL80211_ATTR_IE, params->extra_ies_len, diff --git a/package/network/services/hostapd/patches/110-mbedtls-TLS-crypto-option-initial-port.patch b/package/network/services/hostapd/patches/110-mbedtls-TLS-crypto-option-initial-port.patch index 1d14a8f715ed4a..b786d3bccb5af0 100644 --- a/package/network/services/hostapd/patches/110-mbedtls-TLS-crypto-option-initial-port.patch +++ b/package/network/services/hostapd/patches/110-mbedtls-TLS-crypto-option-initial-port.patch @@ -21,7 +21,7 @@ Signed-off-by: Glenn Strauss --- a/hostapd/Makefile +++ b/hostapd/Makefile -@@ -745,6 +745,40 @@ endif +@@ -757,6 +757,40 @@ endif CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONFIG_TLS_DEFAULT_CIPHERS)\" endif @@ -62,7 +62,7 @@ Signed-off-by: Glenn Strauss ifeq ($(CONFIG_TLS), gnutls) ifndef CONFIG_CRYPTO # default to libgcrypt -@@ -924,9 +958,11 @@ endif +@@ -936,9 +970,11 @@ endif ifneq ($(CONFIG_TLS), openssl) ifneq ($(CONFIG_TLS), wolfssl) @@ -74,7 +74,7 @@ Signed-off-by: Glenn Strauss ifdef NEED_AES_EAX AESOBJS += ../src/crypto/aes-eax.o NEED_AES_CTR=y -@@ -936,38 +972,48 @@ AESOBJS += ../src/crypto/aes-siv.o +@@ -948,38 +984,48 @@ AESOBJS += ../src/crypto/aes-siv.o NEED_AES_CTR=y endif ifdef NEED_AES_CTR @@ -123,7 +123,7 @@ Signed-off-by: Glenn Strauss ifdef NEED_AES_DEC ifdef CONFIG_INTERNAL_AES AESOBJS += ../src/crypto/aes-internal-dec.o -@@ -982,12 +1028,16 @@ ifneq ($(CONFIG_TLS), openssl) +@@ -994,12 +1040,16 @@ ifneq ($(CONFIG_TLS), openssl) ifneq ($(CONFIG_TLS), linux) ifneq ($(CONFIG_TLS), gnutls) ifneq ($(CONFIG_TLS), wolfssl) @@ -140,7 +140,7 @@ Signed-off-by: Glenn Strauss ifdef CONFIG_INTERNAL_SHA1 SHA1OBJS += ../src/crypto/sha1-internal.o ifdef NEED_FIPS186_2_PRF -@@ -996,16 +1046,22 @@ endif +@@ -1008,16 +1058,22 @@ endif endif ifneq ($(CONFIG_TLS), openssl) ifneq ($(CONFIG_TLS), wolfssl) @@ -163,7 +163,7 @@ Signed-off-by: Glenn Strauss ifdef NEED_SHA1 OBJS += $(SHA1OBJS) -@@ -1015,11 +1071,13 @@ ifneq ($(CONFIG_TLS), openssl) +@@ -1027,11 +1083,13 @@ ifneq ($(CONFIG_TLS), openssl) ifneq ($(CONFIG_TLS), linux) ifneq ($(CONFIG_TLS), gnutls) ifneq ($(CONFIG_TLS), wolfssl) @@ -177,7 +177,7 @@ Signed-off-by: Glenn Strauss ifdef NEED_MD5 ifdef CONFIG_INTERNAL_MD5 -@@ -1058,56 +1116,81 @@ ifneq ($(CONFIG_TLS), openssl) +@@ -1070,56 +1128,81 @@ ifneq ($(CONFIG_TLS), openssl) ifneq ($(CONFIG_TLS), linux) ifneq ($(CONFIG_TLS), gnutls) ifneq ($(CONFIG_TLS), wolfssl) @@ -259,7 +259,7 @@ Signed-off-by: Glenn Strauss ifdef CONFIG_INTERNAL_SHA384 CFLAGS += -DCONFIG_INTERNAL_SHA384 -@@ -1152,11 +1235,13 @@ HOBJS += $(SHA1OBJS) +@@ -1164,11 +1247,13 @@ HOBJS += $(SHA1OBJS) ifneq ($(CONFIG_TLS), openssl) ifneq ($(CONFIG_TLS), linux) ifneq ($(CONFIG_TLS), wolfssl) @@ -273,7 +273,7 @@ Signed-off-by: Glenn Strauss ifdef CONFIG_RADIUS_SERVER CFLAGS += -DRADIUS_SERVER -@@ -1329,7 +1414,9 @@ NOBJS += ../src/utils/trace.o +@@ -1341,7 +1426,9 @@ NOBJS += ../src/utils/trace.o endif HOBJS += hlr_auc_gw.o ../src/utils/common.o ../src/utils/wpa_debug.o ../src/utils/os_$(CONFIG_OS).o ../src/utils/wpabuf.o ../src/crypto/milenage.o @@ -283,7 +283,7 @@ Signed-off-by: Glenn Strauss ifdef CONFIG_INTERNAL_AES HOBJS += ../src/crypto/aes-internal.o HOBJS += ../src/crypto/aes-internal-enc.o -@@ -1352,13 +1439,17 @@ SOBJS += ../src/common/sae.o +@@ -1364,13 +1451,17 @@ SOBJS += ../src/common/sae.o SOBJS += ../src/common/sae_pk.o SOBJS += ../src/common/dragonfly.o SOBJS += $(AESOBJS) @@ -326,7 +326,7 @@ Signed-off-by: Glenn Strauss # Driver interface for Host AP driver CONFIG_DRIVER_HOSTAP=y -@@ -278,6 +290,7 @@ CONFIG_IPV6=y +@@ -281,6 +293,7 @@ CONFIG_IPV6=y # openssl = OpenSSL (default) # gnutls = GnuTLS # internal = Internal TLSv1 implementation (experimental) @@ -7765,7 +7765,7 @@ Signed-off-by: Glenn Strauss CONFIG_SIM_SIMULATOR=y --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile -@@ -1163,6 +1163,29 @@ endif +@@ -1229,6 +1229,29 @@ endif CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONFIG_TLS_DEFAULT_CIPHERS)\" endif @@ -7795,7 +7795,7 @@ Signed-off-by: Glenn Strauss ifeq ($(CONFIG_TLS), gnutls) ifndef CONFIG_CRYPTO # default to libgcrypt -@@ -1355,9 +1378,11 @@ endif +@@ -1421,9 +1444,11 @@ endif ifneq ($(CONFIG_TLS), openssl) ifneq ($(CONFIG_TLS), wolfssl) @@ -7807,7 +7807,7 @@ Signed-off-by: Glenn Strauss ifdef CONFIG_OPENSSL_INTERNAL_AES_WRAP # Seems to be needed at least with BoringSSL NEED_INTERNAL_AES_WRAP=y -@@ -1371,9 +1396,11 @@ endif +@@ -1437,9 +1462,11 @@ endif ifdef NEED_INTERNAL_AES_WRAP ifneq ($(CONFIG_TLS), linux) @@ -7819,7 +7819,7 @@ Signed-off-by: Glenn Strauss ifdef NEED_AES_EAX AESOBJS += ../src/crypto/aes-eax.o NEED_AES_CTR=y -@@ -1383,35 +1410,45 @@ AESOBJS += ../src/crypto/aes-siv.o +@@ -1449,35 +1476,45 @@ AESOBJS += ../src/crypto/aes-siv.o NEED_AES_CTR=y endif ifdef NEED_AES_CTR @@ -7865,7 +7865,7 @@ Signed-off-by: Glenn Strauss ifdef NEED_AES_ENC ifdef CONFIG_INTERNAL_AES AESOBJS += ../src/crypto/aes-internal-enc.o -@@ -1426,12 +1463,16 @@ ifneq ($(CONFIG_TLS), openssl) +@@ -1492,12 +1529,16 @@ ifneq ($(CONFIG_TLS), openssl) ifneq ($(CONFIG_TLS), linux) ifneq ($(CONFIG_TLS), gnutls) ifneq ($(CONFIG_TLS), wolfssl) @@ -7882,7 +7882,7 @@ Signed-off-by: Glenn Strauss ifdef CONFIG_INTERNAL_SHA1 SHA1OBJS += ../src/crypto/sha1-internal.o ifdef NEED_FIPS186_2_PRF -@@ -1443,29 +1484,37 @@ CFLAGS += -DCONFIG_NO_PBKDF2 +@@ -1509,29 +1550,37 @@ CFLAGS += -DCONFIG_NO_PBKDF2 else ifneq ($(CONFIG_TLS), openssl) ifneq ($(CONFIG_TLS), wolfssl) @@ -7920,7 +7920,7 @@ Signed-off-by: Glenn Strauss ifdef NEED_MD5 ifdef CONFIG_INTERNAL_MD5 MD5OBJS += ../src/crypto/md5-internal.o -@@ -1520,12 +1569,17 @@ ifneq ($(CONFIG_TLS), openssl) +@@ -1586,12 +1635,17 @@ ifneq ($(CONFIG_TLS), openssl) ifneq ($(CONFIG_TLS), linux) ifneq ($(CONFIG_TLS), gnutls) ifneq ($(CONFIG_TLS), wolfssl) @@ -7938,7 +7938,7 @@ Signed-off-by: Glenn Strauss ifdef CONFIG_INTERNAL_SHA256 SHA256OBJS += ../src/crypto/sha256-internal.o endif -@@ -1538,50 +1592,68 @@ CFLAGS += -DCONFIG_INTERNAL_SHA512 +@@ -1604,50 +1658,68 @@ CFLAGS += -DCONFIG_INTERNAL_SHA512 SHA256OBJS += ../src/crypto/sha512-internal.o endif ifdef NEED_TLS_PRF_SHA256 @@ -8007,7 +8007,7 @@ Signed-off-by: Glenn Strauss ifdef NEED_ASN1 OBJS += ../src/tls/asn1.o -@@ -1756,10 +1828,12 @@ ifdef CONFIG_FIPS +@@ -1822,10 +1894,12 @@ ifdef CONFIG_FIPS CFLAGS += -DCONFIG_FIPS ifneq ($(CONFIG_TLS), openssl) ifneq ($(CONFIG_TLS), wolfssl) diff --git a/package/network/services/hostapd/patches/120-mbedtls-fips186_2_prf.patch b/package/network/services/hostapd/patches/120-mbedtls-fips186_2_prf.patch index a48725264fd36a..c101fbf75ff1c8 100644 --- a/package/network/services/hostapd/patches/120-mbedtls-fips186_2_prf.patch +++ b/package/network/services/hostapd/patches/120-mbedtls-fips186_2_prf.patch @@ -12,7 +12,7 @@ Signed-off-by: Glenn Strauss --- a/hostapd/Makefile +++ b/hostapd/Makefile -@@ -759,10 +759,6 @@ endif +@@ -771,10 +771,6 @@ endif OBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o HOBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o SOBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o @@ -101,7 +101,7 @@ Signed-off-by: Glenn Strauss --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile -@@ -1174,10 +1174,6 @@ endif +@@ -1240,10 +1240,6 @@ endif OBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o OBJS_p += ../src/crypto/crypto_$(CONFIG_CRYPTO).o OBJS_priv += ../src/crypto/crypto_$(CONFIG_CRYPTO).o diff --git a/package/network/services/hostapd/patches/135-mbedtls-fix-owe-association.patch b/package/network/services/hostapd/patches/135-mbedtls-fix-owe-association.patch index 0c29432d3f83f3..3733f915054c3d 100644 --- a/package/network/services/hostapd/patches/135-mbedtls-fix-owe-association.patch +++ b/package/network/services/hostapd/patches/135-mbedtls-fix-owe-association.patch @@ -1,10 +1,18 @@ +From: David Bauer +Date: Tue, 24 Oct 2023 03:07:48 +0200 +Subject: [PATCH] hostapd: fix OWE association with mbedtls + The code for hostapd-mbedtls did not work when used for OWE association. -When handling association requests, the buffer offsets and length assumptions were incorrect, leading to never calculating the y point, thus denying association. +When handling association requests, the buffer offsets and length +assumptions were incorrect, leading to never calculating the y point, +thus denying association. -Also when crafting the association response, the buffer contained the trailing key-type. +Also when crafting the association response, the buffer contained the +trailing key-type. -Fix up both issues to adhere to the specification and make hostapd-mbedtls work with the OWE security type. +Fix up both issues to adhere to the specification and make +hostapd-mbedtls work with the OWE security type. --- a/src/crypto/crypto_mbedtls.c +++ b/src/crypto/crypto_mbedtls.c diff --git a/package/network/services/hostapd/patches/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch b/package/network/services/hostapd/patches/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch index e96083c5435b74..32e8ec3a89a034 100644 --- a/package/network/services/hostapd/patches/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch +++ b/package/network/services/hostapd/patches/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch @@ -38,15 +38,15 @@ Signed-off-by: Glenn Strauss src/crypto/Makefile | 129 ++++++++++++++++++++- src/crypto/crypto_module_tests.c | 134 ++++++++++++++++++++++ src/tls/Makefile | 11 ++ - tests/Makefile | 75 +++++++++--- - tests/hwsim/example-hostapd.config | 11 +- - tests/hwsim/example-wpa_supplicant.config | 12 +- + tests/Makefile | 76 +++++++++--- + tests/hwsim/example-hostapd.config | 10 +- + tests/hwsim/example-wpa_supplicant.config | 11 +- tests/hwsim/test_ap_eap.py | 114 +++++++++++++----- tests/hwsim/test_ap_ft.py | 4 +- tests/hwsim/test_authsrv.py | 9 +- tests/hwsim/test_dpp.py | 19 ++- tests/hwsim/test_erp.py | 16 +-- - tests/hwsim/test_fils.py | 5 +- + tests/hwsim/test_fils.py | 4 + tests/hwsim/test_pmksa_cache.py | 4 +- tests/hwsim/test_sae.py | 7 ++ tests/hwsim/test_suite_b.py | 3 + @@ -56,12 +56,12 @@ Signed-off-by: Glenn Strauss tests/test-https.c | 12 +- tests/test-https_server.c | 12 +- wpa_supplicant/Makefile | 6 + - 22 files changed, 524 insertions(+), 91 deletions(-) + 22 files changed, 522 insertions(+), 91 deletions(-) create mode 100644 tests/test-crypto_module.c --- a/hostapd/Makefile +++ b/hostapd/Makefile -@@ -696,6 +696,7 @@ CFLAGS += -DCONFIG_TLSV12 +@@ -708,6 +708,7 @@ CFLAGS += -DCONFIG_TLSV12 endif ifeq ($(CONFIG_TLS), wolfssl) @@ -69,7 +69,7 @@ Signed-off-by: Glenn Strauss CONFIG_CRYPTO=wolfssl ifdef TLS_FUNCS OBJS += ../src/crypto/tls_wolfssl.o -@@ -716,6 +717,7 @@ endif +@@ -728,6 +729,7 @@ endif endif ifeq ($(CONFIG_TLS), openssl) @@ -77,7 +77,7 @@ Signed-off-by: Glenn Strauss CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 CONFIG_CRYPTO=openssl ifdef TLS_FUNCS -@@ -746,6 +748,7 @@ CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONF +@@ -758,6 +760,7 @@ CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONF endif ifeq ($(CONFIG_TLS), mbedtls) @@ -85,7 +85,7 @@ Signed-off-by: Glenn Strauss ifndef CONFIG_CRYPTO CONFIG_CRYPTO=mbedtls endif -@@ -776,6 +779,7 @@ endif +@@ -788,6 +791,7 @@ endif endif ifeq ($(CONFIG_TLS), gnutls) @@ -93,7 +93,7 @@ Signed-off-by: Glenn Strauss ifndef CONFIG_CRYPTO # default to libgcrypt CONFIG_CRYPTO=gnutls -@@ -806,6 +810,7 @@ endif +@@ -818,6 +822,7 @@ endif endif ifeq ($(CONFIG_TLS), internal) @@ -101,7 +101,7 @@ Signed-off-by: Glenn Strauss ifndef CONFIG_CRYPTO CONFIG_CRYPTO=internal endif -@@ -884,6 +889,7 @@ endif +@@ -896,6 +901,7 @@ endif endif ifeq ($(CONFIG_TLS), linux) @@ -271,7 +271,7 @@ Signed-off-by: Glenn Strauss endif --- a/src/crypto/crypto_module_tests.c +++ b/src/crypto/crypto_module_tests.c -@@ -2469,6 +2469,139 @@ static int test_hpke(void) +@@ -2470,6 +2470,139 @@ static int test_hpke(void) } @@ -411,7 +411,7 @@ Signed-off-by: Glenn Strauss static int test_ms_funcs(void) { #ifndef CONFIG_FIPS -@@ -2590,6 +2723,7 @@ int crypto_module_tests(void) +@@ -2591,6 +2724,7 @@ int crypto_module_tests(void) test_fips186_2_prf() || test_extract_expand_hkdf() || test_hpke() || @@ -444,23 +444,25 @@ Signed-off-by: Glenn Strauss include ../lib.rules --- a/tests/Makefile +++ b/tests/Makefile -@@ -1,8 +1,10 @@ +@@ -1,10 +1,12 @@ -ALL=test-base64 test-md4 test-milenage \ - test-rsa-sig-ver \ - test-sha1 \ - test-https test-https_server \ -- test-sha256 test-aes test-x509v3 test-list test-rc4 +- test-sha256 test-aes test-x509v3 test-list test-rc4 \ +RUN_TESTS= \ + test-list \ + test-md4 test-rc4 test-sha1 test-sha256 \ + test-milenage test-aes \ -+ test-crypto_module -+ -+ALL=$(RUN_TESTS) test-base64 test-https test-https_server ++ test-crypto_module \ + test-bss ++ALL=$(RUN_TESTS) test-base64 test-https test-https_server ++ include ../src/build.rules -@@ -24,13 +26,27 @@ CFLAGS += -DCONFIG_IEEE80211R_AP + ifdef LIBFUZZER +@@ -25,13 +27,27 @@ CFLAGS += -DCONFIG_IEEE80211R_AP CFLAGS += -DCONFIG_IEEE80211R CFLAGS += -DCONFIG_TDLS @@ -490,7 +492,7 @@ Signed-off-by: Glenn Strauss _OBJS_VAR := LLIBS include ../src/objs.mk -@@ -42,12 +58,43 @@ include ../src/objs.mk +@@ -43,12 +59,43 @@ include ../src/objs.mk LIBS = $(SLIBS) $(DLIBS) LLIBS = -Wl,--start-group $(DLIBS) -Wl,--end-group $(SLIBS) @@ -534,8 +536,8 @@ Signed-off-by: Glenn Strauss test-base64: $(call BUILDOBJ,test-base64.o) $(LIBS) $(LDO) $(LDFLAGS) -o $@ $^ $(LLIBS) -@@ -83,17 +130,11 @@ test-x509v3: $(call BUILDOBJ,test-x509v3 - +@@ -141,18 +188,11 @@ test-bss: $(call BUILDOBJ,test-bss.o) $( + $(LDO) $(LDFLAGS) -o $@ $< $(LLIBS) $(WPA_CFLAGS) $(WPA_OBJS) $(LIBS) run-tests: $(ALL) - ./test-aes @@ -545,6 +547,7 @@ Signed-off-by: Glenn Strauss - ./test-rsa-sig-ver - ./test-sha1 - ./test-sha256 +- ./test-bss + @set -ex; for i in $(RUN_TESTS); do ./$$i; done @echo @echo All tests completed successfully. @@ -575,14 +578,6 @@ Signed-off-by: Glenn Strauss CONFIG_EAP_EKE=y CONFIG_PKCS12=y CONFIG_RADIUS_SERVER=y -@@ -89,6 +81,7 @@ CFLAGS += -DCONFIG_RADIUS_TEST - CONFIG_MODULE_TESTS=y - - CONFIG_SUITEB=y -+CONFIG_SUITEB192=$(if $(filter openssl mbedtls,$(CONFIG_TLS)),y,) - - # AddressSanitizer (ASan) can be enabled by uncommenting the following lines. - # This can be used as a more efficient memory error detector than valgrind --- a/tests/hwsim/example-wpa_supplicant.config +++ b/tests/hwsim/example-wpa_supplicant.config @@ -35,16 +35,7 @@ LIBS += -rdynamic @@ -603,14 +598,6 @@ Signed-off-by: Glenn Strauss CONFIG_USIM_SIMULATOR=y CONFIG_SIM_SIMULATOR=y -@@ -137,6 +128,7 @@ CONFIG_TESTING_OPTIONS=y - CONFIG_MODULE_TESTS=y - - CONFIG_SUITEB=y -+CONFIG_SUITEB192=$(if $(filter openssl mbedtls,$(CONFIG_TLS)),y,) - - # AddressSanitizer (ASan) can be enabled by uncommenting the following lines. - # This can be used as a more efficient memory error detector than valgrind --- a/tests/hwsim/test_ap_eap.py +++ b/tests/hwsim/test_ap_eap.py @@ -42,20 +42,42 @@ def check_eap_capa(dev, method): @@ -708,10 +695,10 @@ Signed-off-by: Glenn Strauss tls = dev.request("GET tls_library") + if tls.startswith("mbed TLS"): + raise HwsimSkip("TLS v1.3 not supported") - if "run=OpenSSL 1.1.1" not in tls and "run=OpenSSL 3.0" not in tls and "wolfSSL" not in tls: - raise HwsimSkip("TLS v1.3 not supported") - -@@ -118,11 +157,15 @@ def check_pkcs12_support(dev): + ok = ['run=OpenSSL 1.1.1', 'run=OpenSSL 3.0', 'run=OpenSSL 3.1', + 'run=OpenSSL 3.2', 'wolfSSL'] + for s in ok: +@@ -122,11 +161,15 @@ def check_pkcs12_support(dev): # raise HwsimSkip("PKCS#12 not supported with this TLS library: " + tls) if tls.startswith("wolfSSL"): raise HwsimSkip("PKCS#12 not supported with this TLS library: " + tls) @@ -727,7 +714,7 @@ Signed-off-by: Glenn Strauss def check_ec_support(dev): tls = dev.request("GET tls_library") -@@ -1712,7 +1755,7 @@ def test_ap_wpa2_eap_ttls_pap_subject_ma +@@ -1741,7 +1784,7 @@ def test_ap_wpa2_eap_ttls_pap_subject_ma eap_connect(dev[0], hapd, "TTLS", "pap user", anonymous_identity="ttls", password="password", ca_cert="auth_serv/ca.pem", phase2="auth=PAP", @@ -736,7 +723,7 @@ Signed-off-by: Glenn Strauss altsubject_match="EMAIL:noone@example.com;DNS:server.w1.fi;URI:http://example.com/") eap_reauth(dev[0], "TTLS") -@@ -2947,6 +2990,7 @@ def test_ap_wpa2_eap_tls_neg_domain_matc +@@ -2976,6 +3019,7 @@ def test_ap_wpa2_eap_tls_neg_domain_matc def test_ap_wpa2_eap_tls_neg_subject_match(dev, apdev): """WPA2-Enterprise negative test - subject mismatch""" @@ -744,7 +731,7 @@ Signed-off-by: Glenn Strauss params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") hostapd.add_ap(apdev[0], params) dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", -@@ -3007,6 +3051,7 @@ def test_ap_wpa2_eap_tls_neg_subject_mat +@@ -3036,6 +3080,7 @@ def test_ap_wpa2_eap_tls_neg_subject_mat def test_ap_wpa2_eap_tls_neg_altsubject_match(dev, apdev): """WPA2-Enterprise negative test - altsubject mismatch""" @@ -752,7 +739,7 @@ Signed-off-by: Glenn Strauss params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") hostapd.add_ap(apdev[0], params) -@@ -3547,7 +3592,7 @@ def test_ap_wpa2_eap_ikev2_oom(dev, apde +@@ -3582,7 +3627,7 @@ def test_ap_wpa2_eap_ikev2_oom(dev, apde dev[0].request("REMOVE_NETWORK all") tls = dev[0].request("GET tls_library") @@ -761,7 +748,7 @@ Signed-off-by: Glenn Strauss tests = [(1, "os_get_random;dh_init")] else: tests = [(1, "crypto_dh_init;dh_init")] -@@ -4861,7 +4906,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca +@@ -4896,7 +4941,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca params["private_key"] = "auth_serv/iCA-server/server.key" hostapd.add_ap(apdev[0], params) tls = dev[0].request("GET tls_library") @@ -770,7 +757,7 @@ Signed-off-by: Glenn Strauss ca_cert = "auth_serv/iCA-user/ca-and-root.pem" client_cert = "auth_serv/iCA-user/user_and_ica.pem" else: -@@ -4927,6 +4972,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca +@@ -4962,6 +5007,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca run_ap_wpa2_eap_tls_intermediate_ca_ocsp(dev, apdev, params, "-sha1") def run_ap_wpa2_eap_tls_intermediate_ca_ocsp(dev, apdev, params, md): @@ -778,7 +765,7 @@ Signed-off-by: Glenn Strauss params = int_eap_server_params() params["ca_cert"] = "auth_serv/iCA-server/ca-and-root.pem" params["server_cert"] = "auth_serv/iCA-server/server.pem" -@@ -4936,7 +4982,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ +@@ -4971,7 +5017,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ try: hostapd.add_ap(apdev[0], params) tls = dev[0].request("GET tls_library") @@ -787,7 +774,7 @@ Signed-off-by: Glenn Strauss ca_cert = "auth_serv/iCA-user/ca-and-root.pem" client_cert = "auth_serv/iCA-user/user_and_ica.pem" else: -@@ -4972,7 +5018,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ +@@ -5007,7 +5053,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ try: hostapd.add_ap(apdev[0], params) tls = dev[0].request("GET tls_library") @@ -796,7 +783,7 @@ Signed-off-by: Glenn Strauss ca_cert = "auth_serv/iCA-user/ca-and-root.pem" client_cert = "auth_serv/iCA-user/user_and_ica.pem" else: -@@ -5022,7 +5068,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca +@@ -5057,7 +5103,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca try: hostapd.add_ap(apdev[0], params) tls = dev[0].request("GET tls_library") @@ -805,7 +792,7 @@ Signed-off-by: Glenn Strauss ca_cert = "auth_serv/iCA-user/ca-and-root.pem" client_cert = "auth_serv/iCA-user/user_and_ica.pem" else: -@@ -5089,7 +5135,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca +@@ -5124,7 +5170,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca hostapd.add_ap(apdev[0], params) tls = dev[0].request("GET tls_library") @@ -814,7 +801,7 @@ Signed-off-by: Glenn Strauss ca_cert = "auth_serv/iCA-user/ca-and-root.pem" client_cert = "auth_serv/iCA-user/user_and_ica.pem" else: -@@ -5347,6 +5393,7 @@ def test_ap_wpa2_eap_ttls_server_cert_ek +@@ -5382,6 +5428,7 @@ def test_ap_wpa2_eap_ttls_server_cert_ek def test_ap_wpa2_eap_ttls_server_pkcs12(dev, apdev): """WPA2-Enterprise using EAP-TTLS and server PKCS#12 file""" @@ -822,7 +809,7 @@ Signed-off-by: Glenn Strauss skip_with_fips(dev[0]) params = int_eap_server_params() del params["server_cert"] -@@ -5359,6 +5406,7 @@ def test_ap_wpa2_eap_ttls_server_pkcs12( +@@ -5394,6 +5441,7 @@ def test_ap_wpa2_eap_ttls_server_pkcs12( def test_ap_wpa2_eap_ttls_server_pkcs12_extra(dev, apdev): """EAP-TTLS and server PKCS#12 file with extra certs""" @@ -830,7 +817,7 @@ Signed-off-by: Glenn Strauss skip_with_fips(dev[0]) params = int_eap_server_params() del params["server_cert"] -@@ -5381,6 +5429,7 @@ def test_ap_wpa2_eap_ttls_dh_params_serv +@@ -5416,6 +5464,7 @@ def test_ap_wpa2_eap_ttls_dh_params_serv def test_ap_wpa2_eap_ttls_dh_params_dsa_server(dev, apdev): """WPA2-Enterprise using EAP-TTLS and alternative server dhparams (DSA)""" @@ -838,7 +825,7 @@ Signed-off-by: Glenn Strauss params = int_eap_server_params() params["dh_file"] = "auth_serv/dsaparam.pem" hapd = hostapd.add_ap(apdev[0], params) -@@ -5692,8 +5741,8 @@ def test_ap_wpa2_eap_non_ascii_identity2 +@@ -5727,8 +5776,8 @@ def test_ap_wpa2_eap_non_ascii_identity2 def test_openssl_cipher_suite_config_wpas(dev, apdev): """OpenSSL cipher suite configuration on wpa_supplicant""" tls = dev[0].request("GET tls_library") @@ -849,7 +836,7 @@ Signed-off-by: Glenn Strauss params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") hapd = hostapd.add_ap(apdev[0], params) eap_connect(dev[0], hapd, "TTLS", "pap user", -@@ -5719,14 +5768,14 @@ def test_openssl_cipher_suite_config_wpa +@@ -5754,14 +5803,14 @@ def test_openssl_cipher_suite_config_wpa def test_openssl_cipher_suite_config_hapd(dev, apdev): """OpenSSL cipher suite configuration on hostapd""" tls = dev[0].request("GET tls_library") @@ -868,7 +855,7 @@ Signed-off-by: Glenn Strauss eap_connect(dev[0], hapd, "TTLS", "pap user", anonymous_identity="ttls", password="password", ca_cert="auth_serv/ca.pem", phase2="auth=PAP") -@@ -6168,13 +6217,17 @@ def test_ap_wpa2_eap_tls_versions(dev, a +@@ -6207,13 +6256,17 @@ def test_ap_wpa2_eap_tls_versions(dev, a check_tls_ver(dev[0], hapd, "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1", "TLSv1.2") @@ -888,10 +875,10 @@ Signed-off-by: Glenn Strauss + "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=0 tls_disable_tlsv1_2=1", "TLSv1.1") + check_tls_ver(dev[2], hapd, + "tls_disable_tlsv1_0=0 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1", "TLSv1") - if "run=OpenSSL 1.1.1" in tls or "run=OpenSSL 3.0" in tls: + if "run=OpenSSL 1.1.1" in tls or "run=OpenSSL 3." in tls: check_tls_ver(dev[0], hapd, "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1 tls_disable_tlsv1_3=0", "TLSv1.3") -@@ -6196,6 +6249,11 @@ def test_ap_wpa2_eap_tls_versions_server +@@ -6235,6 +6288,11 @@ def test_ap_wpa2_eap_tls_versions_server tests = [("TLSv1", "[ENABLE-TLSv1.0][DISABLE-TLSv1.1][DISABLE-TLSv1.2][DISABLE-TLSv1.3]"), ("TLSv1.1", "[ENABLE-TLSv1.0][ENABLE-TLSv1.1][DISABLE-TLSv1.2][DISABLE-TLSv1.3]"), ("TLSv1.2", "[ENABLE-TLSv1.0][ENABLE-TLSv1.1][ENABLE-TLSv1.2][DISABLE-TLSv1.3]")] @@ -903,7 +890,7 @@ Signed-off-by: Glenn Strauss for exp, flags in tests: hapd.disable() hapd.set("tls_flags", flags) -@@ -7255,6 +7313,7 @@ def test_ap_wpa2_eap_assoc_rsn(dev, apde +@@ -7305,6 +7363,7 @@ def test_ap_wpa2_eap_assoc_rsn(dev, apde def test_eap_tls_ext_cert_check(dev, apdev): """EAP-TLS and external server certification validation""" # With internal server certificate chain validation @@ -911,7 +898,7 @@ Signed-off-by: Glenn Strauss id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TLS", identity="tls user", ca_cert="auth_serv/ca.pem", -@@ -7267,6 +7326,7 @@ def test_eap_tls_ext_cert_check(dev, apd +@@ -7317,6 +7376,7 @@ def test_eap_tls_ext_cert_check(dev, apd def test_eap_ttls_ext_cert_check(dev, apdev): """EAP-TTLS and external server certification validation""" # Without internal server certificate chain validation @@ -919,7 +906,7 @@ Signed-off-by: Glenn Strauss id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", identity="pap user", anonymous_identity="ttls", password="password", phase2="auth=PAP", -@@ -7277,6 +7337,7 @@ def test_eap_ttls_ext_cert_check(dev, ap +@@ -7327,6 +7387,7 @@ def test_eap_ttls_ext_cert_check(dev, ap def test_eap_peap_ext_cert_check(dev, apdev): """EAP-PEAP and external server certification validation""" # With internal server certificate chain validation @@ -927,7 +914,7 @@ Signed-off-by: Glenn Strauss id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="PEAP", identity="user", anonymous_identity="peap", ca_cert="auth_serv/ca.pem", -@@ -7287,6 +7348,7 @@ def test_eap_peap_ext_cert_check(dev, ap +@@ -7337,6 +7398,7 @@ def test_eap_peap_ext_cert_check(dev, ap def test_eap_fast_ext_cert_check(dev, apdev): """EAP-FAST and external server certification validation""" @@ -935,7 +922,7 @@ Signed-off-by: Glenn Strauss check_eap_capa(dev[0], "FAST") # With internal server certificate chain validation dev[0].request("SET blob fast_pac_auth_ext ") -@@ -7301,10 +7363,6 @@ def test_eap_fast_ext_cert_check(dev, ap +@@ -7351,10 +7413,6 @@ def test_eap_fast_ext_cert_check(dev, ap run_ext_cert_check(dev, apdev, id) def run_ext_cert_check(dev, apdev, net_id): @@ -948,7 +935,7 @@ Signed-off-by: Glenn Strauss --- a/tests/hwsim/test_ap_ft.py +++ b/tests/hwsim/test_ap_ft.py -@@ -2474,11 +2474,11 @@ def test_ap_ft_ap_oom5(dev, apdev): +@@ -2486,11 +2486,11 @@ def test_ap_ft_ap_oom5(dev, apdev): # This will fail to roam dev[0].roam(bssid1, check_bssid=False) @@ -992,7 +979,7 @@ Signed-off-by: Glenn Strauss raise HwsimSkip("Crypto library does not support Brainpool curves: " + tls) capa = dev.request("GET_CAPABILITY dpp") ver = 1 -@@ -3892,6 +3893,9 @@ def test_dpp_proto_auth_req_no_i_proto_k +@@ -3902,6 +3903,9 @@ def test_dpp_proto_auth_req_no_i_proto_k def test_dpp_proto_auth_req_invalid_i_proto_key(dev, apdev): """DPP protocol testing - invalid I-proto key in Auth Req""" @@ -1002,7 +989,7 @@ Signed-off-by: Glenn Strauss run_dpp_proto_auth_req_missing(dev, 66, "Invalid Initiator Protocol Key") def test_dpp_proto_auth_req_no_i_nonce(dev, apdev): -@@ -3987,7 +3991,12 @@ def test_dpp_proto_auth_resp_no_r_proto_ +@@ -3997,7 +4001,12 @@ def test_dpp_proto_auth_resp_no_r_proto_ def test_dpp_proto_auth_resp_invalid_r_proto_key(dev, apdev): """DPP protocol testing - invalid R-Proto Key in Auth Resp""" @@ -1016,7 +1003,7 @@ Signed-off-by: Glenn Strauss def test_dpp_proto_auth_resp_no_r_nonce(dev, apdev): """DPP protocol testing - no R-nonce in Auth Resp""" -@@ -4349,11 +4358,17 @@ def test_dpp_proto_pkex_exchange_resp_in +@@ -4359,11 +4368,17 @@ def test_dpp_proto_pkex_exchange_resp_in def test_dpp_proto_pkex_cr_req_invalid_bootstrap_key(dev, apdev): """DPP protocol testing - invalid Bootstrap Key in PKEX Commit-Reveal Request""" @@ -1092,21 +1079,20 @@ Signed-off-by: Glenn Strauss dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", --- a/tests/hwsim/test_fils.py +++ b/tests/hwsim/test_fils.py -@@ -1422,7 +1422,10 @@ def run_fils_sk_pfs(dev, apdev, group, p - check_erp_capa(dev[0]) - - tls = dev[0].request("GET tls_library") -- if not tls.startswith("wolfSSL"): -+ if tls.startswith("mbed TLS"): +@@ -1472,6 +1472,10 @@ def check_ec_group(dev, group): + tls = dev.request("GET tls_library") + if tls.startswith("wolfSSL"): + return ++ elif tls.startswith("mbed TLS"): + if int(group) == 27: + raise HwsimSkip("Brainpool EC group 27 not supported by mbed TLS") -+ elif not tls.startswith("wolfSSL"): - if int(group) in [25]: - if not (tls.startswith("OpenSSL") and ("build=OpenSSL 1.0.2" in tls or "build=OpenSSL 1.1" in tls or "build=OpenSSL 3.0" in tls) and ("run=OpenSSL 1.0.2" in tls or "run=OpenSSL 1.1" in tls or "run=OpenSSL 3.0" in tls)): - raise HwsimSkip("EC group not supported") ++ return + if int(group) in [25]: + if not (tls.startswith("OpenSSL") and ("build=OpenSSL 1.0.2" in tls or "build=OpenSSL 1.1" in tls or "build=OpenSSL 3." in tls) and ("run=OpenSSL 1.0.2" in tls or "run=OpenSSL 1.1" in tls or "run=OpenSSL 3." in tls)): + raise HwsimSkip("EC group not supported") --- a/tests/hwsim/test_pmksa_cache.py +++ b/tests/hwsim/test_pmksa_cache.py -@@ -955,7 +955,7 @@ def test_pmksa_cache_preauth_wpas_oom(de +@@ -958,7 +958,7 @@ def test_pmksa_cache_preauth_wpas_oom(de eap_connect(dev[0], hapd, "PAX", "pax.user@example.com", password_hex="0123456789abcdef0123456789abcdef", bssid=apdev[0]['bssid']) @@ -1115,7 +1101,7 @@ Signed-off-by: Glenn Strauss with alloc_fail(dev[0], i, "rsn_preauth_init"): res = dev[0].request("PREAUTH f2:11:22:33:44:55").strip() logger.info("Iteration %d - PREAUTH command results: %s" % (i, res)) -@@ -963,7 +963,7 @@ def test_pmksa_cache_preauth_wpas_oom(de +@@ -966,7 +966,7 @@ def test_pmksa_cache_preauth_wpas_oom(de state = dev[0].request('GET_ALLOC_FAIL') if state.startswith('0:'): break @@ -1126,7 +1112,7 @@ Signed-off-by: Glenn Strauss """PMKSA cache control interface operations""" --- a/tests/hwsim/test_sae.py +++ b/tests/hwsim/test_sae.py -@@ -177,6 +177,11 @@ def test_sae_groups(dev, apdev): +@@ -178,6 +178,11 @@ def test_sae_groups(dev, apdev): if tls.startswith("OpenSSL") and "run=OpenSSL 1." in tls: logger.info("Add Brainpool EC groups since OpenSSL is new enough") sae_groups += [27, 28, 29, 30] @@ -1138,7 +1124,7 @@ Signed-off-by: Glenn Strauss heavy_groups = [14, 15, 16] suitable_groups = [15, 16, 17, 18, 19, 20, 21] groups = [str(g) for g in sae_groups] -@@ -2193,6 +2198,8 @@ def run_sae_pwe_group(dev, apdev, group) +@@ -2194,6 +2199,8 @@ def run_sae_pwe_group(dev, apdev, group) logger.info("Add Brainpool EC groups since OpenSSL is new enough") elif tls.startswith("wolfSSL"): logger.info("Make sure Brainpool EC groups were enabled when compiling wolfSSL") @@ -1179,7 +1165,7 @@ Signed-off-by: Glenn Strauss res = dev[0].request(cmd) --- a/tests/hwsim/utils.py +++ b/tests/hwsim/utils.py -@@ -141,7 +141,13 @@ def check_imsi_privacy_support(dev): +@@ -145,7 +145,13 @@ def check_imsi_privacy_support(dev): def check_tls_tod(dev): tls = dev.request("GET tls_library") @@ -1308,7 +1294,7 @@ Signed-off-by: Glenn Strauss if (need_more_data) { --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile -@@ -1122,6 +1122,7 @@ CFLAGS += -DCONFIG_TLSV12 +@@ -1188,6 +1188,7 @@ TLS_FUNCS=y endif ifeq ($(CONFIG_TLS), wolfssl) @@ -1316,7 +1302,7 @@ Signed-off-by: Glenn Strauss ifdef TLS_FUNCS CFLAGS += -DWOLFSSL_DER_LOAD OBJS += ../src/crypto/tls_wolfssl.o -@@ -1137,6 +1138,7 @@ LIBS_p += -lwolfssl -lm +@@ -1203,6 +1204,7 @@ LIBS_p += -lwolfssl -lm endif ifeq ($(CONFIG_TLS), openssl) @@ -1324,7 +1310,7 @@ Signed-off-by: Glenn Strauss CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 ifdef TLS_FUNCS CFLAGS += -DEAP_TLS_OPENSSL -@@ -1164,6 +1166,7 @@ CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONF +@@ -1230,6 +1232,7 @@ CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONF endif ifeq ($(CONFIG_TLS), mbedtls) @@ -1332,7 +1318,7 @@ Signed-off-by: Glenn Strauss ifndef CONFIG_CRYPTO CONFIG_CRYPTO=mbedtls endif -@@ -1183,6 +1186,7 @@ endif +@@ -1249,6 +1252,7 @@ endif endif ifeq ($(CONFIG_TLS), gnutls) @@ -1340,7 +1326,7 @@ Signed-off-by: Glenn Strauss ifndef CONFIG_CRYPTO # default to libgcrypt CONFIG_CRYPTO=gnutls -@@ -1213,6 +1217,7 @@ endif +@@ -1279,6 +1283,7 @@ endif endif ifeq ($(CONFIG_TLS), internal) @@ -1348,7 +1334,7 @@ Signed-off-by: Glenn Strauss ifndef CONFIG_CRYPTO CONFIG_CRYPTO=internal endif -@@ -1293,6 +1298,7 @@ endif +@@ -1359,6 +1364,7 @@ endif endif ifeq ($(CONFIG_TLS), linux) diff --git a/package/network/services/hostapd/patches/170-hostapd-update-cfs0-and-cfs1-for-160MHz.patch b/package/network/services/hostapd/patches/170-hostapd-update-cfs0-and-cfs1-for-160MHz.patch index b0151b071f6aab..96f674a77d516f 100644 --- a/package/network/services/hostapd/patches/170-hostapd-update-cfs0-and-cfs1-for-160MHz.patch +++ b/package/network/services/hostapd/patches/170-hostapd-update-cfs0-and-cfs1-for-160MHz.patch @@ -21,15 +21,15 @@ operation information element instead. Signed-off-by: P Praneesh --- hostapd/config_file.c | 2 ++ - src/ap/ieee802_11_ht.c | 7 +++++++ - src/ap/ieee802_11_vht.c | 16 ++++++++++++++++ + src/ap/ieee802_11_ht.c | 9 +++++++++ + src/ap/ieee802_11_vht.c | 17 +++++++++++++++++ src/common/hw_features_common.c | 1 + - src/common/ieee802_11_defs.h | 1 + - 5 files changed, 27 insertions(+) + src/common/ieee802_11_defs.h | 2 ++ + 5 files changed, 31 insertions(+) --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -1153,6 +1153,8 @@ static int hostapd_config_vht_capab(stru +@@ -1229,6 +1229,8 @@ static int hostapd_config_vht_capab(stru conf->vht_capab |= VHT_CAP_RX_ANTENNA_PATTERN; if (os_strstr(capab, "[TX-ANTENNA-PATTERN]")) conf->vht_capab |= VHT_CAP_TX_ANTENNA_PATTERN; @@ -66,7 +66,7 @@ Signed-off-by: P Praneesh return pos; --- a/src/ap/ieee802_11_vht.c +++ b/src/ap/ieee802_11_vht.c -@@ -25,6 +25,7 @@ u8 * hostapd_eid_vht_capabilities(struct +@@ -26,6 +26,7 @@ u8 * hostapd_eid_vht_capabilities(struct struct ieee80211_vht_capabilities *cap; struct hostapd_hw_modes *mode = hapd->iface->current_mode; u8 *pos = eid; @@ -74,7 +74,7 @@ Signed-off-by: P Praneesh if (!mode || is_6ghz_op_class(hapd->iconf->op_class)) return eid; -@@ -62,6 +63,17 @@ u8 * hostapd_eid_vht_capabilities(struct +@@ -63,6 +64,17 @@ u8 * hostapd_eid_vht_capabilities(struct host_to_le32(nsts << VHT_CAP_BEAMFORMEE_STS_OFFSET); } @@ -92,7 +92,7 @@ Signed-off-by: P Praneesh /* Supported MCS set comes from hw */ os_memcpy(&cap->vht_supported_mcs_set, mode->vht_mcs_set, 8); -@@ -74,6 +86,7 @@ u8 * hostapd_eid_vht_capabilities(struct +@@ -75,6 +87,7 @@ u8 * hostapd_eid_vht_capabilities(struct u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid) { struct ieee80211_vht_operation *oper; @@ -100,7 +100,7 @@ Signed-off-by: P Praneesh u8 *pos = eid; enum oper_chan_width oper_chwidth = hostapd_get_oper_chwidth(hapd->iconf); -@@ -106,6 +119,7 @@ u8 * hostapd_eid_vht_operation(struct ho +@@ -110,6 +123,7 @@ u8 * hostapd_eid_vht_operation(struct ho oper->vht_op_info_chan_center_freq_seg1_idx = seg1; oper->vht_op_info_chwidth = oper_chwidth; @@ -108,7 +108,7 @@ Signed-off-by: P Praneesh if (oper_chwidth == CONF_OPER_CHWIDTH_160MHZ) { /* * Convert 160 MHz channel width to new style as interop -@@ -119,6 +133,9 @@ u8 * hostapd_eid_vht_operation(struct ho +@@ -123,6 +137,9 @@ u8 * hostapd_eid_vht_operation(struct ho oper->vht_op_info_chan_center_freq_seg0_idx -= 8; else oper->vht_op_info_chan_center_freq_seg0_idx += 8; @@ -120,7 +120,7 @@ Signed-off-by: P Praneesh * Convert 80+80 MHz channel width to new style as interop --- a/src/common/hw_features_common.c +++ b/src/common/hw_features_common.c -@@ -811,6 +811,7 @@ int ieee80211ac_cap_check(u32 hw, u32 co +@@ -898,6 +898,7 @@ int ieee80211ac_cap_check(u32 hw, u32 co VHT_CAP_CHECK(VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB); VHT_CAP_CHECK(VHT_CAP_RX_ANTENNA_PATTERN); VHT_CAP_CHECK(VHT_CAP_TX_ANTENNA_PATTERN); @@ -130,7 +130,7 @@ Signed-off-by: P Praneesh #undef VHT_CAP_CHECK_MAX --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h -@@ -1349,6 +1349,8 @@ struct ieee80211_ampe_ie { +@@ -1397,6 +1397,8 @@ struct ieee80211_ampe_ie { #define VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB ((u32) BIT(26) | BIT(27)) #define VHT_CAP_RX_ANTENNA_PATTERN ((u32) BIT(28)) #define VHT_CAP_TX_ANTENNA_PATTERN ((u32) BIT(29)) diff --git a/package/network/services/hostapd/patches/181-driver_nl80211-update-drv-ifindex-on-removing-the-fi.patch b/package/network/services/hostapd/patches/181-driver_nl80211-update-drv-ifindex-on-removing-the-fi.patch index adfb21fb471a49..b54abecc4f7768 100644 --- a/package/network/services/hostapd/patches/181-driver_nl80211-update-drv-ifindex-on-removing-the-fi.patch +++ b/package/network/services/hostapd/patches/181-driver_nl80211-update-drv-ifindex-on-removing-the-fi.patch @@ -8,7 +8,7 @@ Signed-off-by: Felix Fietkau --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c -@@ -8867,6 +8867,7 @@ static int wpa_driver_nl80211_if_remove( +@@ -8985,6 +8985,7 @@ static int wpa_driver_nl80211_if_remove( if (drv->first_bss->next) { drv->first_bss = drv->first_bss->next; drv->ctx = drv->first_bss->ctx; diff --git a/package/network/services/hostapd/patches/182-nl80211-move-nl80211_put_freq_params-call-outside-of.patch b/package/network/services/hostapd/patches/182-nl80211-move-nl80211_put_freq_params-call-outside-of.patch index 395c645954247c..e875a82aea778d 100644 --- a/package/network/services/hostapd/patches/182-nl80211-move-nl80211_put_freq_params-call-outside-of.patch +++ b/package/network/services/hostapd/patches/182-nl80211-move-nl80211_put_freq_params-call-outside-of.patch @@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c -@@ -5226,6 +5226,9 @@ static int wpa_driver_nl80211_set_ap(voi +@@ -5315,6 +5315,9 @@ static int wpa_driver_nl80211_set_ap(voi nla_nest_end(msg, ftm); } @@ -22,13 +22,13 @@ Signed-off-by: Felix Fietkau #ifdef CONFIG_IEEE80211AX if (params->he_spr_ctrl) { struct nlattr *spr; -@@ -5260,9 +5263,6 @@ static int wpa_driver_nl80211_set_ap(voi +@@ -5349,9 +5352,6 @@ static int wpa_driver_nl80211_set_ap(voi nla_nest_end(msg, spr); } - if (params->freq && nl80211_put_freq_params(msg, params->freq) < 0) - goto fail; - - if (params->freq && params->freq->he_enabled) { + if (params->freq && params->freq->he_enabled && + nl80211_attr_supported(drv, NL80211_ATTR_HE_BSS_COLOR)) { struct nlattr *bss_color; - diff --git a/package/network/services/hostapd/patches/183-hostapd-cancel-channel_list_update_timeout-in-hostap.patch b/package/network/services/hostapd/patches/183-hostapd-cancel-channel_list_update_timeout-in-hostap.patch index fe81318385f15a..4d1af1f5c0c6f5 100644 --- a/package/network/services/hostapd/patches/183-hostapd-cancel-channel_list_update_timeout-in-hostap.patch +++ b/package/network/services/hostapd/patches/183-hostapd-cancel-channel_list_update_timeout-in-hostap.patch @@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c -@@ -569,6 +569,7 @@ static void sta_track_deinit(struct host +@@ -656,6 +656,7 @@ static void sta_track_deinit(struct host void hostapd_cleanup_iface_partial(struct hostapd_iface *iface) { wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); @@ -18,7 +18,7 @@ Signed-off-by: Felix Fietkau #ifdef NEED_AP_MLME hostapd_stop_setup_timers(iface); #endif /* NEED_AP_MLME */ -@@ -598,7 +599,6 @@ void hostapd_cleanup_iface_partial(struc +@@ -685,7 +686,6 @@ void hostapd_cleanup_iface_partial(struc static void hostapd_cleanup_iface(struct hostapd_iface *iface) { wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); diff --git a/package/network/services/hostapd/patches/200-multicall.patch b/package/network/services/hostapd/patches/200-multicall.patch index 8f54a8d3544718..1a193b51bb1e19 100644 --- a/package/network/services/hostapd/patches/200-multicall.patch +++ b/package/network/services/hostapd/patches/200-multicall.patch @@ -1,3 +1,10 @@ +From: Felix Fietkau +Date: Sat, 23 Jan 2010 08:28:26 +0000 +Subject: [PATCH] Add option to build a multicall binary + +This allows building both hostapd and wpa_supplicant as a single binary +(wpad). + --- a/hostapd/Makefile +++ b/hostapd/Makefile @@ -1,6 +1,7 @@ @@ -18,7 +25,7 @@ OBJS += ../src/ap/vlan_init.o OBJS += ../src/ap/vlan_ifconfig.o OBJS += ../src/ap/vlan.o -@@ -357,10 +359,14 @@ CFLAGS += -DCONFIG_MBO +@@ -358,10 +360,14 @@ CFLAGS += -DCONFIG_MBO OBJS += ../src/ap/mbo_ap.o endif @@ -36,7 +43,7 @@ LIBS += $(DRV_AP_LIBS) ifdef CONFIG_L2_PACKET -@@ -1380,6 +1386,12 @@ install: $(addprefix $(DESTDIR)$(BINDIR) +@@ -1392,6 +1398,12 @@ install: $(addprefix $(DESTDIR)$(BINDIR) _OBJS_VAR := OBJS include ../src/objs.mk @@ -49,7 +56,7 @@ hostapd: $(OBJS) $(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS) @$(E) " LD " $@ -@@ -1460,6 +1472,12 @@ include ../src/objs.mk +@@ -1472,6 +1484,12 @@ include ../src/objs.mk _OBJS_VAR := SOBJS include ../src/objs.mk @@ -62,6 +69,86 @@ nt_password_hash: $(NOBJS) $(Q)$(CC) $(LDFLAGS) -o nt_password_hash $(NOBJS) $(LIBS_n) @$(E) " LD " $@ +--- a/hostapd/main.c ++++ b/hostapd/main.c +@@ -705,6 +705,11 @@ fail: + return -1; + } + ++void hostapd_wpa_event(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); ++ ++void hostapd_wpa_event_global(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); + + #ifdef CONFIG_WPS + static int gen_uuid(const char *txt_addr) +@@ -798,6 +803,8 @@ int main(int argc, char *argv[]) + return -1; + #endif /* CONFIG_DPP */ + ++ wpa_supplicant_event = hostapd_wpa_event; ++ wpa_supplicant_event_global = hostapd_wpa_event_global; + for (;;) { + c = getopt(argc, argv, "b:Bde:f:hi:KP:sSTtu:vg:G:q"); + if (c < 0) +--- a/src/ap/drv_callbacks.c ++++ b/src/ap/drv_callbacks.c +@@ -2341,8 +2341,8 @@ err: + #endif /* CONFIG_OWE */ + + +-void wpa_supplicant_event(void *ctx, enum wpa_event_type event, +- union wpa_event_data *data) ++void hostapd_wpa_event(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data) + { + struct hostapd_data *hapd = ctx; + struct sta_info *sta; +@@ -2674,7 +2674,7 @@ void wpa_supplicant_event(void *ctx, enu + } + + +-void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event, ++void hostapd_wpa_event_global(void *ctx, enum wpa_event_type event, + union wpa_event_data *data) + { + struct hapd_interfaces *interfaces = ctx; +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -6763,8 +6763,8 @@ union wpa_event_data { + * Driver wrapper code should call this function whenever an event is received + * from the driver. + */ +-void wpa_supplicant_event(void *ctx, enum wpa_event_type event, +- union wpa_event_data *data); ++extern void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); + + /** + * wpa_supplicant_event_global - Report a driver event for wpa_supplicant +@@ -6776,7 +6776,7 @@ void wpa_supplicant_event(void *ctx, enu + * Same as wpa_supplicant_event(), but we search for the interface in + * wpa_global. + */ +-void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event, ++extern void (*wpa_supplicant_event_global)(void *ctx, enum wpa_event_type event, + union wpa_event_data *data); + + /* +--- a/src/drivers/drivers.c ++++ b/src/drivers/drivers.c +@@ -10,6 +10,10 @@ + #include "utils/common.h" + #include "driver.h" + ++void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); ++void (*wpa_supplicant_event_global)(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); + + const struct wpa_driver_ops *const wpa_drivers[] = + { --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -10,6 +10,7 @@ ALL += dbus/fi.w1.wpa_supplicant1.servic @@ -72,7 +159,7 @@ include ../src/build.rules ifdef CONFIG_BUILD_PASN_SO -@@ -382,7 +383,9 @@ endif +@@ -388,7 +389,9 @@ endif ifdef CONFIG_IBSS_RSN NEED_RSN_AUTHENTICATOR=y CFLAGS += -DCONFIG_IBSS_RSN @@ -82,7 +169,7 @@ OBJS += ibss_rsn.o endif -@@ -924,6 +927,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS +@@ -980,6 +983,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS LIBS += -ldl -rdynamic endif @@ -93,7 +180,7 @@ endif ifdef CONFIG_AP -@@ -931,9 +938,11 @@ NEED_EAP_COMMON=y +@@ -987,9 +994,11 @@ NEED_EAP_COMMON=y NEED_RSN_AUTHENTICATOR=y CFLAGS += -DCONFIG_AP OBJS += ap.o @@ -105,7 +192,7 @@ OBJS += ../src/ap/hostapd.o OBJS += ../src/ap/wpa_auth_glue.o OBJS += ../src/ap/utils.o -@@ -1022,6 +1031,12 @@ endif +@@ -1080,6 +1089,12 @@ endif ifdef CONFIG_HS20 OBJS += ../src/ap/hs20.o endif @@ -118,7 +205,7 @@ endif ifdef CONFIG_MBO -@@ -1030,7 +1045,9 @@ CFLAGS += -DCONFIG_MBO +@@ -1089,7 +1104,9 @@ NEED_GAS=y endif ifdef NEED_RSN_AUTHENTICATOR @@ -128,7 +215,7 @@ NEED_AES_WRAP=y OBJS += ../src/ap/wpa_auth.o OBJS += ../src/ap/wpa_auth_ie.o -@@ -2010,6 +2027,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv) +@@ -2079,6 +2096,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv) _OBJS_VAR := OBJS include ../src/objs.mk @@ -141,7 +228,7 @@ wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs) $(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS) @$(E) " LD " $@ -@@ -2142,6 +2165,12 @@ eap_gpsk.so: $(SRC_EAP_GPSK) +@@ -2211,6 +2234,12 @@ eap_gpsk.so: $(SRC_EAP_GPSK) $(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@ @$(E) " sed" $< @@ -154,50 +241,63 @@ wpa_supplicant.exe: wpa_supplicant mv -f $< $@ wpa_cli.exe: wpa_cli ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -6676,8 +6676,8 @@ union wpa_event_data { - * Driver wrapper code should call this function whenever an event is received - * from the driver. - */ --void wpa_supplicant_event(void *ctx, enum wpa_event_type event, -- union wpa_event_data *data); -+extern void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event, -+ union wpa_event_data *data); +--- a/wpa_supplicant/eapol_test.c ++++ b/wpa_supplicant/eapol_test.c +@@ -31,7 +31,12 @@ + #include "ctrl_iface.h" + #include "pcsc_funcs.h" + #include "wpas_glue.h" ++#include "drivers/driver.h" - /** - * wpa_supplicant_event_global - Report a driver event for wpa_supplicant -@@ -6689,7 +6689,7 @@ void wpa_supplicant_event(void *ctx, enu - * Same as wpa_supplicant_event(), but we search for the interface in - * wpa_global. - */ --void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event, -+extern void (*wpa_supplicant_event_global)(void *ctx, enum wpa_event_type event, - union wpa_event_data *data); ++void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); ++void (*wpa_supplicant_event_global)(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); - /* ---- a/src/ap/drv_callbacks.c -+++ b/src/ap/drv_callbacks.c -@@ -2182,8 +2182,8 @@ err: - #endif /* CONFIG_OWE */ + const struct wpa_driver_ops *const wpa_drivers[] = { NULL }; + +@@ -1325,6 +1330,10 @@ static void usage(void) + "option several times.\n"); + } + ++extern void supplicant_event(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); ++extern void supplicant_event_global(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); + + int main(int argc, char *argv[]) + { +@@ -1348,6 +1357,8 @@ int main(int argc, char *argv[]) + if (os_program_init()) + return -1; + ++ wpa_supplicant_event = supplicant_event; ++ wpa_supplicant_event_global = supplicant_event_global; + hostapd_logger_register_cb(hostapd_logger_cb); + + os_memset(&eapol_test, 0, sizeof(eapol_test)); +--- a/wpa_supplicant/events.c ++++ b/wpa_supplicant/events.c +@@ -5919,8 +5919,8 @@ static void wpas_link_reconfig(struct wp + } -void wpa_supplicant_event(void *ctx, enum wpa_event_type event, - union wpa_event_data *data) -+void hostapd_wpa_event(void *ctx, enum wpa_event_type event, -+ union wpa_event_data *data) ++void supplicant_event(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data) { - struct hostapd_data *hapd = ctx; - #ifndef CONFIG_NO_STDOUT_DEBUG -@@ -2487,7 +2487,7 @@ void wpa_supplicant_event(void *ctx, enu + struct wpa_supplicant *wpa_s = ctx; + int resched; +@@ -6872,7 +6872,7 @@ void wpa_supplicant_event(void *ctx, enu } -void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event, -+void hostapd_wpa_event_global(void *ctx, enum wpa_event_type event, ++void supplicant_event_global(void *ctx, enum wpa_event_type event, union wpa_event_data *data) { - struct hapd_interfaces *interfaces = ctx; + struct wpa_supplicant *wpa_s; --- a/wpa_supplicant/wpa_priv.c +++ b/wpa_supplicant/wpa_priv.c @@ -1039,8 +1039,8 @@ static void wpa_priv_send_ft_response(st @@ -229,31 +329,9 @@ wpa_priv_fd_workaround(); os_memset(&global, 0, sizeof(global)); ---- a/wpa_supplicant/events.c -+++ b/wpa_supplicant/events.c -@@ -5530,8 +5530,8 @@ static void wpas_link_reconfig(struct wp - } - - --void wpa_supplicant_event(void *ctx, enum wpa_event_type event, -- union wpa_event_data *data) -+void supplicant_event(void *ctx, enum wpa_event_type event, -+ union wpa_event_data *data) - { - struct wpa_supplicant *wpa_s = ctx; - int resched; -@@ -6449,7 +6449,7 @@ void wpa_supplicant_event(void *ctx, enu - } - - --void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event, -+void supplicant_event_global(void *ctx, enum wpa_event_type event, - union wpa_event_data *data) - { - struct wpa_supplicant *wpa_s; --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c -@@ -7469,7 +7469,6 @@ struct wpa_interface * wpa_supplicant_ma +@@ -7583,7 +7583,6 @@ struct wpa_interface * wpa_supplicant_ma return NULL; } @@ -261,7 +339,7 @@ /** * wpa_supplicant_match_existing - Match existing interfaces * @global: Pointer to global data from wpa_supplicant_init() -@@ -7504,6 +7503,11 @@ static int wpa_supplicant_match_existing +@@ -7618,6 +7617,11 @@ static int wpa_supplicant_match_existing #endif /* CONFIG_MATCH_IFACE */ @@ -273,7 +351,7 @@ /** * wpa_supplicant_add_iface - Add a new network interface -@@ -7760,6 +7764,8 @@ struct wpa_global * wpa_supplicant_init( +@@ -7874,6 +7878,8 @@ struct wpa_global * wpa_supplicant_init( #ifndef CONFIG_NO_WPA_MSG wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb); #endif /* CONFIG_NO_WPA_MSG */ @@ -282,74 +360,3 @@ if (params->wpa_debug_file_path) wpa_debug_open_file(params->wpa_debug_file_path); ---- a/hostapd/main.c -+++ b/hostapd/main.c -@@ -698,6 +698,11 @@ fail: - return -1; - } - -+void hostapd_wpa_event(void *ctx, enum wpa_event_type event, -+ union wpa_event_data *data); -+ -+void hostapd_wpa_event_global(void *ctx, enum wpa_event_type event, -+ union wpa_event_data *data); - - #ifdef CONFIG_WPS - static int gen_uuid(const char *txt_addr) -@@ -791,6 +796,8 @@ int main(int argc, char *argv[]) - return -1; - #endif /* CONFIG_DPP */ - -+ wpa_supplicant_event = hostapd_wpa_event; -+ wpa_supplicant_event_global = hostapd_wpa_event_global; - for (;;) { - c = getopt(argc, argv, "b:Bde:f:hi:KP:sSTtu:vg:G:q"); - if (c < 0) ---- a/src/drivers/drivers.c -+++ b/src/drivers/drivers.c -@@ -10,6 +10,10 @@ - #include "utils/common.h" - #include "driver.h" - -+void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event, -+ union wpa_event_data *data); -+void (*wpa_supplicant_event_global)(void *ctx, enum wpa_event_type event, -+ union wpa_event_data *data); - - const struct wpa_driver_ops *const wpa_drivers[] = - { ---- a/wpa_supplicant/eapol_test.c -+++ b/wpa_supplicant/eapol_test.c -@@ -31,7 +31,12 @@ - #include "ctrl_iface.h" - #include "pcsc_funcs.h" - #include "wpas_glue.h" -+#include "drivers/driver.h" - -+void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event, -+ union wpa_event_data *data); -+void (*wpa_supplicant_event_global)(void *ctx, enum wpa_event_type event, -+ union wpa_event_data *data); - - const struct wpa_driver_ops *const wpa_drivers[] = { NULL }; - -@@ -1303,6 +1308,10 @@ static void usage(void) - "option several times.\n"); - } - -+extern void supplicant_event(void *ctx, enum wpa_event_type event, -+ union wpa_event_data *data); -+extern void supplicant_event_global(void *ctx, enum wpa_event_type event, -+ union wpa_event_data *data); - - int main(int argc, char *argv[]) - { -@@ -1323,6 +1332,8 @@ int main(int argc, char *argv[]) - if (os_program_init()) - return -1; - -+ wpa_supplicant_event = supplicant_event; -+ wpa_supplicant_event_global = supplicant_event_global; - hostapd_logger_register_cb(hostapd_logger_cb); - - os_memset(&eapol_test, 0, sizeof(eapol_test)); diff --git a/package/network/services/hostapd/patches/201-lto-jobserver-support.patch b/package/network/services/hostapd/patches/201-lto-jobserver-support.patch new file mode 100644 index 00000000000000..ea0dc290813790 --- /dev/null +++ b/package/network/services/hostapd/patches/201-lto-jobserver-support.patch @@ -0,0 +1,64 @@ +From: Felix Fietkau +Date: Tue, 10 Jul 2018 13:48:17 +0200 +Subject: [PATCH] hostapd: build with LTO enabled (using jobserver for parallel + build) + +--- a/hostapd/Makefile ++++ b/hostapd/Makefile +@@ -1405,7 +1405,7 @@ hostapd_multi.a: $(BCHECK) $(OBJS) + @$(AR) cr $@ hostapd_multi.o $(OBJS) + + hostapd: $(OBJS) +- $(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS) ++ +$(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS) + @$(E) " LD " $@ + + ifdef CONFIG_WPA_TRACE +@@ -1416,7 +1416,7 @@ _OBJS_VAR := OBJS_c + include ../src/objs.mk + + hostapd_cli: $(OBJS_c) +- $(Q)$(CC) $(LDFLAGS) -o hostapd_cli $(OBJS_c) $(LIBS_c) ++ +$(Q)$(CC) $(LDFLAGS) -o hostapd_cli $(OBJS_c) $(LIBS_c) + @$(E) " LD " $@ + + NOBJS = nt_password_hash.o ../src/crypto/ms_funcs.o $(SHA1OBJS) +--- a/wpa_supplicant/Makefile ++++ b/wpa_supplicant/Makefile +@@ -2103,31 +2103,31 @@ wpa_supplicant_multi.a: .config $(BCHECK + @$(AR) cr $@ wpa_supplicant_multi.o $(OBJS) + + wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs) +- $(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS) ++ +$(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS) + @$(E) " LD " $@ + + _OBJS_VAR := OBJS_t + include ../src/objs.mk + eapol_test: $(OBJS_t) +- $(Q)$(LDO) $(LDFLAGS) -o eapol_test $(OBJS_t) $(LIBS) ++ +$(Q)$(LDO) $(LDFLAGS) -o eapol_test $(OBJS_t) $(LIBS) + @$(E) " LD " $@ + + _OBJS_VAR := OBJS_t2 + include ../src/objs.mk + preauth_test: $(OBJS_t2) +- $(Q)$(LDO) $(LDFLAGS) -o preauth_test $(OBJS_t2) $(LIBS) ++ +$(Q)$(LDO) $(LDFLAGS) -o preauth_test $(OBJS_t2) $(LIBS) + @$(E) " LD " $@ + + _OBJS_VAR := OBJS_p + include ../src/objs.mk + wpa_passphrase: $(OBJS_p) +- $(Q)$(LDO) $(LDFLAGS) -o wpa_passphrase $(OBJS_p) $(LIBS_p) $(LIBS) ++ +$(Q)$(LDO) $(LDFLAGS) -o wpa_passphrase $(OBJS_p) $(LIBS_p) $(LIBS) + @$(E) " LD " $@ + + _OBJS_VAR := OBJS_c + include ../src/objs.mk + wpa_cli: $(OBJS_c) +- $(Q)$(LDO) $(LDFLAGS) -o wpa_cli $(OBJS_c) $(LIBS_c) ++ +$(Q)$(LDO) $(LDFLAGS) -o wpa_cli $(OBJS_c) $(LIBS_c) + @$(E) " LD " $@ + + LIBCTRL += ../src/common/wpa_ctrl.o diff --git a/package/network/services/hostapd/patches/210-build-de-duplicate-_DIRS-before-calling-mkdir.patch b/package/network/services/hostapd/patches/210-build-de-duplicate-_DIRS-before-calling-mkdir.patch new file mode 100644 index 00000000000000..08d4393c906d0e --- /dev/null +++ b/package/network/services/hostapd/patches/210-build-de-duplicate-_DIRS-before-calling-mkdir.patch @@ -0,0 +1,23 @@ +From: Felix Fietkau +Date: Thu, 4 Apr 2024 12:59:41 +0200 +Subject: [PATCH] build: de-duplicate _DIRS before calling mkdir + +If the build path is long, the contents of the _DIRS variable can be very long, +since it repeats the same directories very often. +In some cases, this has triggered an "Argument list too long" build error. + +Suggested-by: Eneas U de Queiroz +Signed-off-by: Felix Fietkau +--- + +--- a/src/build.rules ++++ b/src/build.rules +@@ -80,7 +80,7 @@ endif + _DIRS := $(BUILDDIR)/$(PROJ) + .PHONY: _make_dirs + _make_dirs: +- @mkdir -p $(_DIRS) ++ @mkdir -p $(sort $(_DIRS)) + + $(BUILDDIR)/$(PROJ)/src/%.o: $(ROOTDIR)src/%.c $(CONFIG_FILE) | _make_dirs + $(Q)$(CC) -c -o $@ $(CFLAGS) $< diff --git a/package/network/services/hostapd/patches/211-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch b/package/network/services/hostapd/patches/211-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch new file mode 100644 index 00000000000000..84fdea8c785231 --- /dev/null +++ b/package/network/services/hostapd/patches/211-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch @@ -0,0 +1,33 @@ +From f0e9f5aab52b3eab85d28338cc996972ced4c39c Mon Sep 17 00:00:00 2001 +From: David Bauer +Date: Tue, 17 May 2022 23:07:59 +0200 +Subject: [PATCH] ctrl: make WNM_AP functions dependant on CONFIG_AP + +This fixes linking errors found when compiling wpa_supplicant with +CONFIG_WNM_AP enabled but CONFIG_AP disabled. + +Signed-off-by: David Bauer +--- + wpa_supplicant/ctrl_iface.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/wpa_supplicant/ctrl_iface.c ++++ b/wpa_supplicant/ctrl_iface.c +@@ -13214,7 +13214,7 @@ char * wpa_supplicant_ctrl_iface_process + if (wpas_ctrl_iface_coloc_intf_report(wpa_s, buf + 18)) + reply_len = -1; + #endif /* CONFIG_WNM */ +-#ifdef CONFIG_WNM_AP ++#if defined(CONFIG_AP) && defined(CONFIG_WNM_AP) + } else if (os_strncmp(buf, "DISASSOC_IMMINENT ", 18) == 0) { + if (ap_ctrl_iface_disassoc_imminent(wpa_s, buf + 18)) + reply_len = -1; +@@ -13224,7 +13224,7 @@ char * wpa_supplicant_ctrl_iface_process + } else if (os_strncmp(buf, "BSS_TM_REQ ", 11) == 0) { + if (ap_ctrl_iface_bss_tm_req(wpa_s, buf + 11)) + reply_len = -1; +-#endif /* CONFIG_WNM_AP */ ++#endif /* CONFIG_AP && CONFIG_WNM_AP */ + } else if (os_strcmp(buf, "FLUSH") == 0) { + wpa_supplicant_ctrl_iface_flush(wpa_s); + } else if (os_strncmp(buf, "RADIO_WORK ", 11) == 0) { diff --git a/package/network/services/hostapd/patches/212-Move-definition-of-WLAN_SUPP_RATES_MAX-to-defs.h.patch b/package/network/services/hostapd/patches/212-Move-definition-of-WLAN_SUPP_RATES_MAX-to-defs.h.patch new file mode 100644 index 00000000000000..4c568c924cca23 --- /dev/null +++ b/package/network/services/hostapd/patches/212-Move-definition-of-WLAN_SUPP_RATES_MAX-to-defs.h.patch @@ -0,0 +1,56 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Eneas U de Queiroz +Date: Mon, 12 Feb 2024 14:18:24 -0300 +Subject: [PATCH] Move definition of WLAN_SUPP_RATES_MAX to defs.h + +Patch 460-wpa_supplicant-add-new-config-params-to-be-used-with.patch +("wpa_supplicant: add new config params to be used with the ibss join +command") adds the definition of unsigned char +rates[WLAN_SUPP_RATES_MAX] to driver.h, which needs to have +WLAN_SUPP_RATES_MAX defined. So it includes sta_info.h to get the +definition. + +Commit c74739250a ("AP MLD: Use a helper function to check if a STA is a +non-AP MLD") makes sta_info.h include driver.h before +it defines WLAN_SUPP_RATES_MAX, causing an error: + +src/drivers/driver.h:969:29: error: 'WLAN_SUPP_RATES_MAX' undeclared here (not in a function) + +Move the definition of WLAN_SUPP_RATES_MAX to defs.h to ensure it gets +defined before other headers are included. The inclusion of sta_info.h +in driver.h can be reverted as well. + +Signed-off-by: Eneas U de Queiroz +--- + src/ap/sta_info.h | 4 ---- + src/common/defs.h | 4 ++++ + src/drivers/driver.h | 1 - + wpa_supplicant/config_ssid.h | 1 - + 4 files changed, 4 insertions(+), 6 deletions(-) + +--- a/src/ap/sta_info.h ++++ b/src/ap/sta_info.h +@@ -49,10 +49,6 @@ + #define WLAN_STA_PENDING_DEAUTH_CB BIT(30) + #define WLAN_STA_NONERP BIT(31) + +-/* Maximum number of supported rates (from both Supported Rates and Extended +- * Supported Rates IEs). */ +-#define WLAN_SUPP_RATES_MAX 32 +- + struct hostapd_data; + + struct mbo_non_pref_chan_info { +--- a/src/common/defs.h ++++ b/src/common/defs.h +@@ -63,6 +63,10 @@ + WPA_KEY_MGMT_FT_FILS_SHA256 | \ + WPA_KEY_MGMT_FT_FILS_SHA384) + ++/* Maximum number of supported rates (from both Supported Rates and Extended ++ * Supported Rates IEs). */ ++#define WLAN_SUPP_RATES_MAX 32 ++ + static inline int wpa_key_mgmt_wpa_ieee8021x(int akm) + { + return !!(akm & (WPA_KEY_MGMT_IEEE8021X | diff --git a/package/network/services/hostapd/patches/213-wpa_supplicant-fix-warnings.patch b/package/network/services/hostapd/patches/213-wpa_supplicant-fix-warnings.patch new file mode 100644 index 00000000000000..4acd7cafe27247 --- /dev/null +++ b/package/network/services/hostapd/patches/213-wpa_supplicant-fix-warnings.patch @@ -0,0 +1,32 @@ +From: "Leon M. George" +Date: Wed, 11 Sep 2019 15:22:55 +0200 +Subject: [PATCH] hostapd: declare struct wpa_bss early + +wps_supplicant.h assumes that 'struct wpa_bss' is forward declared if +CONFIG_WPS is not defined. With the later inclusion of +600-ubus_support, the issue manifests in warnings like these: + +wps_supplicant.h:113:15: warning: 'struct wpa_bss' declared inside parameter list will not be visible outside of this definition or declaration + struct wpa_bss *bss) + ^~~~~~~ +This patch forward declares 'struct wpa_bss' regardless. + +--- a/wpa_supplicant/wps_supplicant.h ++++ b/wpa_supplicant/wps_supplicant.h +@@ -9,6 +9,7 @@ + #ifndef WPS_SUPPLICANT_H + #define WPS_SUPPLICANT_H + ++struct wpa_bss; + struct wpa_scan_results; + + #ifdef CONFIG_WPS +@@ -16,8 +17,6 @@ struct wpa_scan_results; + #include "wps/wps.h" + #include "wps/wps_defs.h" + +-struct wpa_bss; +- + struct wps_new_ap_settings { + const char *ssid_hex; + const char *auth; diff --git a/package/network/services/hostapd/patches/220-indicate-features.patch b/package/network/services/hostapd/patches/220-indicate-features.patch new file mode 100644 index 00000000000000..006a567c338c9d --- /dev/null +++ b/package/network/services/hostapd/patches/220-indicate-features.patch @@ -0,0 +1,69 @@ +From: Jo-Philipp Wich +Date: Mon, 12 Dec 2011 17:26:13 +0000 +Subject: [PATCH] hostapd: support optional argument for the -v switch of + hostapd and wpa_supplicant to query build features, e.g. hostapd -veap to + test whether 802.11i support is compiled in + +--- a/hostapd/main.c ++++ b/hostapd/main.c +@@ -31,7 +31,7 @@ + #include "config_file.h" + #include "eap_register.h" + #include "ctrl_iface.h" +- ++#include "build_features.h" + + struct hapd_global { + void **drv_priv; +@@ -806,7 +806,7 @@ int main(int argc, char *argv[]) + wpa_supplicant_event = hostapd_wpa_event; + wpa_supplicant_event_global = hostapd_wpa_event_global; + for (;;) { +- c = getopt(argc, argv, "b:Bde:f:hi:KP:sSTtu:vg:G:q"); ++ c = getopt(argc, argv, "b:Bde:f:hi:KP:sSTtu:g:G:qv::"); + if (c < 0) + break; + switch (c) { +@@ -843,6 +843,8 @@ int main(int argc, char *argv[]) + break; + #endif /* CONFIG_DEBUG_LINUX_TRACING */ + case 'v': ++ if (optarg) ++ exit(!has_feature(optarg)); + show_version(); + exit(1); + case 'g': +--- a/wpa_supplicant/main.c ++++ b/wpa_supplicant/main.c +@@ -12,6 +12,7 @@ + #endif /* __linux__ */ + + #include "common.h" ++#include "build_features.h" + #include "crypto/crypto.h" + #include "fst/fst.h" + #include "wpa_supplicant_i.h" +@@ -202,7 +203,7 @@ int main(int argc, char *argv[]) + + for (;;) { + c = getopt(argc, argv, +- "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuvW"); ++ "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuv::W"); + if (c < 0) + break; + switch (c) { +@@ -302,8 +303,12 @@ int main(int argc, char *argv[]) + break; + #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */ + case 'v': +- printf("%s\n", wpa_supplicant_version); +- exitcode = 0; ++ if (optarg) { ++ exitcode = !has_feature(optarg); ++ } else { ++ printf("%s\n", wpa_supplicant_version); ++ exitcode = 0; ++ } + goto out; + case 'W': + params.wait_for_monitor++; diff --git a/package/network/services/hostapd/patches/250-hostapd_cli_ifdef.patch b/package/network/services/hostapd/patches/250-hostapd_cli_ifdef.patch new file mode 100644 index 00000000000000..b6421e9d75957e --- /dev/null +++ b/package/network/services/hostapd/patches/250-hostapd_cli_ifdef.patch @@ -0,0 +1,61 @@ +From: Felix Fietkau +Date: Thu, 13 Sep 2012 12:39:14 +0000 +Subject: [PATCH] hostapd: support wps in hostapd_cli even when built from the + mini variant + +--- a/hostapd/hostapd_cli.c ++++ b/hostapd/hostapd_cli.c +@@ -401,7 +401,6 @@ static int hostapd_cli_cmd_disassociate( + } + + +-#ifdef CONFIG_TAXONOMY + static int hostapd_cli_cmd_signature(struct wpa_ctrl *ctrl, int argc, + char *argv[]) + { +@@ -414,7 +413,6 @@ static int hostapd_cli_cmd_signature(str + os_snprintf(buf, sizeof(buf), "SIGNATURE %s", argv[0]); + return wpa_ctrl_command(ctrl, buf); + } +-#endif /* CONFIG_TAXONOMY */ + + + static int hostapd_cli_cmd_sa_query(struct wpa_ctrl *ctrl, int argc, +@@ -431,7 +429,6 @@ static int hostapd_cli_cmd_sa_query(stru + } + + +-#ifdef CONFIG_WPS + static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, + char *argv[]) + { +@@ -657,7 +654,6 @@ static int hostapd_cli_cmd_wps_config(st + ssid_hex, argv[1]); + return wpa_ctrl_command(ctrl, buf); + } +-#endif /* CONFIG_WPS */ + + + static int hostapd_cli_cmd_disassoc_imminent(struct wpa_ctrl *ctrl, int argc, +@@ -1670,13 +1666,10 @@ static const struct hostapd_cli_cmd host + { "disassociate", hostapd_cli_cmd_disassociate, + hostapd_complete_stations, + " = disassociate a station" }, +-#ifdef CONFIG_TAXONOMY + { "signature", hostapd_cli_cmd_signature, hostapd_complete_stations, + " = get taxonomy signature for a station" }, +-#endif /* CONFIG_TAXONOMY */ + { "sa_query", hostapd_cli_cmd_sa_query, hostapd_complete_stations, + " = send SA Query to a station" }, +-#ifdef CONFIG_WPS + { "wps_pin", hostapd_cli_cmd_wps_pin, NULL, + " [timeout] [addr] = add WPS Enrollee PIN" }, + { "wps_check_pin", hostapd_cli_cmd_wps_check_pin, NULL, +@@ -1701,7 +1694,6 @@ static const struct hostapd_cli_cmd host + " = configure AP" }, + { "wps_get_status", hostapd_cli_cmd_wps_get_status, NULL, + "= show current WPS status" }, +-#endif /* CONFIG_WPS */ + { "disassoc_imminent", hostapd_cli_cmd_disassoc_imminent, NULL, + "= send Disassociation Imminent notification" }, + { "ess_disassoc", hostapd_cli_cmd_ess_disassoc, NULL, diff --git a/package/network/services/hostapd/patches/251-wpa_cli_ifdef.patch b/package/network/services/hostapd/patches/251-wpa_cli_ifdef.patch new file mode 100644 index 00000000000000..d7f967d779f683 --- /dev/null +++ b/package/network/services/hostapd/patches/251-wpa_cli_ifdef.patch @@ -0,0 +1,22 @@ +From: Felix Fietkau +Date: Mon, 2 Dec 2013 13:07:46 +0000 +Subject: [PATCH] hostapd: always include p2p options in wpa_cli + +--- a/wpa_supplicant/wpa_cli.c ++++ b/wpa_supplicant/wpa_cli.c +@@ -26,6 +26,15 @@ + #include + #endif /* ANDROID */ + ++#ifndef CONFIG_P2P ++#define CONFIG_P2P ++#endif ++#ifndef CONFIG_AP ++#define CONFIG_AP ++#endif ++#ifndef CONFIG_MESH ++#define CONFIG_MESH ++#endif + + static const char *const wpa_cli_version = + "wpa_cli v" VERSION_STR "\n" diff --git a/package/network/services/hostapd/patches/252-disable_ctrl_iface_mib.patch b/package/network/services/hostapd/patches/252-disable_ctrl_iface_mib.patch new file mode 100644 index 00000000000000..c65b2b181e3461 --- /dev/null +++ b/package/network/services/hostapd/patches/252-disable_ctrl_iface_mib.patch @@ -0,0 +1,243 @@ +From: Felix Fietkau +Date: Fri, 18 Mar 2011 02:15:52 +0000 +Subject: [PATCH] Remove some unnecessary control interface functionality + +--- a/hostapd/Makefile ++++ b/hostapd/Makefile +@@ -221,6 +221,9 @@ endif + ifdef CONFIG_NO_CTRL_IFACE + CFLAGS += -DCONFIG_NO_CTRL_IFACE + else ++ifdef CONFIG_CTRL_IFACE_MIB ++CFLAGS += -DCONFIG_CTRL_IFACE_MIB ++endif + ifeq ($(CONFIG_CTRL_IFACE), udp) + CFLAGS += -DCONFIG_CTRL_IFACE_UDP + else +--- a/hostapd/ctrl_iface.c ++++ b/hostapd/ctrl_iface.c +@@ -3897,6 +3897,7 @@ static int hostapd_ctrl_iface_receive_pr + reply_size); + } else if (os_strcmp(buf, "STATUS-DRIVER") == 0) { + reply_len = hostapd_drv_status(hapd, reply, reply_size); ++#ifdef CONFIG_CTRL_IFACE_MIB + } else if (os_strcmp(buf, "MIB") == 0) { + reply_len = ieee802_11_get_mib(hapd, reply, reply_size); + if (reply_len >= 0) { +@@ -3938,6 +3939,7 @@ static int hostapd_ctrl_iface_receive_pr + } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { + reply_len = hostapd_ctrl_iface_sta_next(hapd, buf + 9, reply, + reply_size); ++#endif + } else if (os_strcmp(buf, "ATTACH") == 0) { + if (hostapd_ctrl_iface_attach(hapd, from, fromlen, NULL)) + reply_len = -1; +--- a/src/ap/ctrl_iface_ap.c ++++ b/src/ap/ctrl_iface_ap.c +@@ -26,6 +26,26 @@ + #include "taxonomy.h" + #include "wnm_ap.h" + ++static const char * hw_mode_str(enum hostapd_hw_mode mode) ++{ ++ switch (mode) { ++ case HOSTAPD_MODE_IEEE80211B: ++ return "b"; ++ case HOSTAPD_MODE_IEEE80211G: ++ return "g"; ++ case HOSTAPD_MODE_IEEE80211A: ++ return "a"; ++ case HOSTAPD_MODE_IEEE80211AD: ++ return "ad"; ++ case HOSTAPD_MODE_IEEE80211ANY: ++ return "any"; ++ case NUM_HOSTAPD_MODES: ++ return "invalid"; ++ } ++ return "unknown"; ++} ++ ++#ifdef CONFIG_CTRL_IFACE_MIB + + static size_t hostapd_write_ht_mcs_bitmask(char *buf, size_t buflen, + size_t curr_len, const u8 *mcs_set) +@@ -212,26 +232,6 @@ static const char * timeout_next_str(int + } + + +-static const char * hw_mode_str(enum hostapd_hw_mode mode) +-{ +- switch (mode) { +- case HOSTAPD_MODE_IEEE80211B: +- return "b"; +- case HOSTAPD_MODE_IEEE80211G: +- return "g"; +- case HOSTAPD_MODE_IEEE80211A: +- return "a"; +- case HOSTAPD_MODE_IEEE80211AD: +- return "ad"; +- case HOSTAPD_MODE_IEEE80211ANY: +- return "any"; +- case NUM_HOSTAPD_MODES: +- return "invalid"; +- } +- return "unknown"; +-} +- +- + static int hostapd_ctrl_iface_sta_mib(struct hostapd_data *hapd, + struct sta_info *sta, + char *buf, size_t buflen) +@@ -539,6 +539,7 @@ int hostapd_ctrl_iface_sta_next(struct h + return hostapd_ctrl_iface_sta_mib(hapd, sta->next, buf, buflen); + } + ++#endif + + #ifdef CONFIG_P2P_MANAGER + static int p2p_manager_disconnect(struct hostapd_data *hapd, u16 stype, +@@ -951,12 +952,12 @@ int hostapd_ctrl_iface_status(struct hos + return len; + len += ret; + } +- ++#ifdef CONFIG_CTRL_IFACE_MIB + if (iface->conf->ieee80211n && !hapd->conf->disable_11n && mode) { + len = hostapd_write_ht_mcs_bitmask(buf, buflen, len, + mode->mcs_set); + } +- ++#endif /* CONFIG_CTRL_IFACE_MIB */ + if (iface->current_rates && iface->num_rates) { + ret = os_snprintf(buf + len, buflen - len, "supported_rates="); + if (os_snprintf_error(buflen - len, ret)) +--- a/src/ap/ieee802_1x.c ++++ b/src/ap/ieee802_1x.c +@@ -2837,6 +2837,7 @@ static const char * bool_txt(bool val) + return val ? "TRUE" : "FALSE"; + } + ++#ifdef CONFIG_CTRL_IFACE_MIB + + int ieee802_1x_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen) + { +@@ -3023,6 +3024,7 @@ int ieee802_1x_get_mib_sta(struct hostap + return len; + } + ++#endif + + #ifdef CONFIG_HS20 + static void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx) +--- a/src/ap/wpa_auth.c ++++ b/src/ap/wpa_auth.c +@@ -5583,6 +5583,7 @@ static const char * wpa_bool_txt(int val + return val ? "TRUE" : "FALSE"; + } + ++#ifdef CONFIG_CTRL_IFACE_MIB + + #define RSN_SUITE "%02x-%02x-%02x-%d" + #define RSN_SUITE_ARG(s) \ +@@ -5735,7 +5736,7 @@ int wpa_get_mib_sta(struct wpa_state_mac + + return len; + } +- ++#endif + + void wpa_auth_countermeasures_start(struct wpa_authenticator *wpa_auth) + { +--- a/src/rsn_supp/wpa.c ++++ b/src/rsn_supp/wpa.c +@@ -3943,6 +3943,8 @@ static u32 wpa_key_mgmt_suite(struct wpa + } + + ++#ifdef CONFIG_CTRL_IFACE_MIB ++ + #define RSN_SUITE "%02x-%02x-%02x-%d" + #define RSN_SUITE_ARG(s) \ + ((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff +@@ -4024,6 +4026,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, ch + + return (int) len; + } ++#endif + #endif /* CONFIG_CTRL_IFACE */ + + +--- a/wpa_supplicant/Makefile ++++ b/wpa_supplicant/Makefile +@@ -1038,6 +1038,9 @@ ifdef CONFIG_FILS + OBJS += ../src/ap/fils_hlp.o + endif + ifdef CONFIG_CTRL_IFACE ++ifdef CONFIG_CTRL_IFACE_MIB ++CFLAGS += -DCONFIG_CTRL_IFACE_MIB ++endif + OBJS += ../src/ap/ctrl_iface_ap.o + endif + +--- a/wpa_supplicant/ap.c ++++ b/wpa_supplicant/ap.c +@@ -1520,7 +1520,7 @@ int wpas_ap_wps_nfc_report_handover(stru + #endif /* CONFIG_WPS */ + + +-#ifdef CONFIG_CTRL_IFACE ++#if defined(CONFIG_CTRL_IFACE) && defined(CONFIG_CTRL_IFACE_MIB) + + int ap_ctrl_iface_sta_first(struct wpa_supplicant *wpa_s, + char *buf, size_t buflen) +--- a/wpa_supplicant/ctrl_iface.c ++++ b/wpa_supplicant/ctrl_iface.c +@@ -2355,7 +2355,7 @@ static int wpa_supplicant_ctrl_iface_sta + pos += ret; + } + +-#ifdef CONFIG_AP ++#if defined(CONFIG_AP) && defined(CONFIG_CTRL_IFACE_MIB) + if (wpa_s->ap_iface) { + pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos, + end - pos, +@@ -12542,6 +12542,7 @@ char * wpa_supplicant_ctrl_iface_process + reply_len = -1; + } else if (os_strncmp(buf, "NOTE ", 5) == 0) { + wpa_printf(MSG_INFO, "NOTE: %s", buf + 5); ++#ifdef CONFIG_CTRL_IFACE_MIB + } else if (os_strcmp(buf, "MIB") == 0) { + reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size); + if (reply_len >= 0) { +@@ -12554,6 +12555,7 @@ char * wpa_supplicant_ctrl_iface_process + reply_size - reply_len); + #endif /* CONFIG_MACSEC */ + } ++#endif + } else if (os_strncmp(buf, "STATUS", 6) == 0) { + reply_len = wpa_supplicant_ctrl_iface_status( + wpa_s, buf + 6, reply, reply_size); +@@ -13042,6 +13044,7 @@ char * wpa_supplicant_ctrl_iface_process + reply_len = wpa_supplicant_ctrl_iface_bss( + wpa_s, buf + 4, reply, reply_size); + #ifdef CONFIG_AP ++#ifdef CONFIG_CTRL_IFACE_MIB + } else if (os_strcmp(buf, "STA-FIRST") == 0) { + reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size); + } else if (os_strncmp(buf, "STA ", 4) == 0) { +@@ -13050,12 +13053,15 @@ char * wpa_supplicant_ctrl_iface_process + } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { + reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply, + reply_size); ++#endif ++#ifdef CONFIG_CTRL_IFACE_MIB + } else if (os_strncmp(buf, "DEAUTHENTICATE ", 15) == 0) { + if (ap_ctrl_iface_sta_deauthenticate(wpa_s, buf + 15)) + reply_len = -1; + } else if (os_strncmp(buf, "DISASSOCIATE ", 13) == 0) { + if (ap_ctrl_iface_sta_disassociate(wpa_s, buf + 13)) + reply_len = -1; ++#endif + } else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) { + if (ap_ctrl_iface_chanswitch(wpa_s, buf + 12)) + reply_len = -1; diff --git a/package/network/services/hostapd/patches/253-qos_map_set_without_interworking.patch b/package/network/services/hostapd/patches/253-qos_map_set_without_interworking.patch new file mode 100644 index 00000000000000..4072ff5664567c --- /dev/null +++ b/package/network/services/hostapd/patches/253-qos_map_set_without_interworking.patch @@ -0,0 +1,103 @@ +From: Felix Fietkau +Date: Thu, 4 Nov 2021 11:45:18 +0100 +Subject: [PATCH] hostapd: support qos_map_set without CONFIG_INTERWORKING + +This feature is useful on its own even without full interworking support + +--- a/hostapd/config_file.c ++++ b/hostapd/config_file.c +@@ -1680,6 +1680,8 @@ static int parse_anqp_elem(struct hostap + return 0; + } + ++#endif /* CONFIG_INTERWORKING */ ++ + + static int parse_qos_map_set(struct hostapd_bss_config *bss, + char *buf, int line) +@@ -1721,8 +1723,6 @@ static int parse_qos_map_set(struct host + return 0; + } + +-#endif /* CONFIG_INTERWORKING */ +- + + #ifdef CONFIG_HS20 + static int hs20_parse_conn_capab(struct hostapd_bss_config *bss, char *buf, +@@ -4260,10 +4260,10 @@ static int hostapd_config_fill(struct ho + bss->gas_frag_limit = val; + } else if (os_strcmp(buf, "gas_comeback_delay") == 0) { + bss->gas_comeback_delay = atoi(pos); ++#endif /* CONFIG_INTERWORKING */ + } else if (os_strcmp(buf, "qos_map_set") == 0) { + if (parse_qos_map_set(bss, pos, line) < 0) + return 1; +-#endif /* CONFIG_INTERWORKING */ + #ifdef CONFIG_RADIUS_TEST + } else if (os_strcmp(buf, "dump_msk_file") == 0) { + os_free(bss->dump_msk_file); +--- a/src/ap/hostapd.c ++++ b/src/ap/hostapd.c +@@ -1548,6 +1548,7 @@ static int hostapd_setup_bss(struct host + wpa_printf(MSG_ERROR, "GAS server initialization failed"); + return -1; + } ++#endif /* CONFIG_INTERWORKING */ + + if (conf->qos_map_set_len && + hostapd_drv_set_qos_map(hapd, conf->qos_map_set, +@@ -1555,7 +1556,6 @@ static int hostapd_setup_bss(struct host + wpa_printf(MSG_ERROR, "Failed to initialize QoS Map"); + return -1; + } +-#endif /* CONFIG_INTERWORKING */ + + if (conf->bss_load_update_period && bss_load_update_init(hapd)) { + wpa_printf(MSG_ERROR, "BSS Load initialization failed"); +--- a/src/ap/ieee802_11_shared.c ++++ b/src/ap/ieee802_11_shared.c +@@ -1138,13 +1138,11 @@ u8 * hostapd_eid_rsnxe(struct hostapd_da + u16 check_ext_capab(struct hostapd_data *hapd, struct sta_info *sta, + const u8 *ext_capab_ie, size_t ext_capab_ie_len) + { +-#ifdef CONFIG_INTERWORKING + /* check for QoS Map support */ + if (ext_capab_ie_len >= 5) { + if (ext_capab_ie[4] & 0x01) + sta->qos_map_enabled = 1; + } +-#endif /* CONFIG_INTERWORKING */ + + if (ext_capab_ie_len > 0) { + sta->ecsa_supported = !!(ext_capab_ie[0] & BIT(2)); +--- a/wpa_supplicant/events.c ++++ b/wpa_supplicant/events.c +@@ -2935,8 +2935,6 @@ void wnm_bss_keep_alive_deinit(struct wp + } + + +-#ifdef CONFIG_INTERWORKING +- + static int wpas_qos_map_set(struct wpa_supplicant *wpa_s, const u8 *qos_map, + size_t len) + { +@@ -2969,8 +2967,6 @@ static void interworking_process_assoc_r + } + } + +-#endif /* CONFIG_INTERWORKING */ +- + + static void wpa_supplicant_set_4addr_mode(struct wpa_supplicant *wpa_s) + { +@@ -3350,10 +3346,8 @@ static int wpa_supplicant_event_associnf + wnm_process_assoc_resp(wpa_s, data->assoc_info.resp_ies, + data->assoc_info.resp_ies_len); + #endif /* CONFIG_WNM */ +-#ifdef CONFIG_INTERWORKING + interworking_process_assoc_resp(wpa_s, data->assoc_info.resp_ies, + data->assoc_info.resp_ies_len); +-#endif /* CONFIG_INTERWORKING */ + if (wpa_s->hw_capab == CAPAB_VHT && + get_ie(data->assoc_info.resp_ies, + data->assoc_info.resp_ies_len, WLAN_EID_VHT_CAP)) diff --git a/package/network/services/hostapd/patches/300-noscan.patch b/package/network/services/hostapd/patches/300-noscan.patch index 9573916bb4dccf..9b3f401b035348 100644 --- a/package/network/services/hostapd/patches/300-noscan.patch +++ b/package/network/services/hostapd/patches/300-noscan.patch @@ -1,6 +1,11 @@ +From c61daab867671af884a7bb707f9bc0f086241bcd Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Wed, 20 Jan 2010 02:26:00 +0000 +Subject: [PATCH] Add noscan, no_ht_coex config options + --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -3450,6 +3450,10 @@ static int hostapd_config_fill(struct ho +@@ -3656,6 +3656,10 @@ static int hostapd_config_fill(struct ho if (bss->ocv && !bss->ieee80211w) bss->ieee80211w = 1; #endif /* CONFIG_OCV */ @@ -13,7 +18,7 @@ } else if (os_strcmp(buf, "ht_capab") == 0) { --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h -@@ -1076,6 +1076,8 @@ struct hostapd_config { +@@ -1093,6 +1093,8 @@ struct hostapd_config { int ht_op_mode_fixed; u16 ht_capab; @@ -24,7 +29,7 @@ int no_pri_sec_switch; --- a/src/ap/hw_features.c +++ b/src/ap/hw_features.c -@@ -546,7 +546,8 @@ static int ieee80211n_check_40mhz(struct +@@ -544,7 +544,8 @@ static int ieee80211n_check_40mhz(struct int ret; /* Check that HT40 is used and PRI / SEC switch is allowed */ diff --git a/package/network/services/hostapd/patches/301-mesh-noscan.patch b/package/network/services/hostapd/patches/301-mesh-noscan.patch index ceb6d0c161f50b..64a2eed30e522f 100644 --- a/package/network/services/hostapd/patches/301-mesh-noscan.patch +++ b/package/network/services/hostapd/patches/301-mesh-noscan.patch @@ -1,6 +1,11 @@ +From: Daniel Golle +Date: Fri, 20 Apr 2018 07:41:03 +0200 +Subject: [PATCH] Allow HT40 also on 2.4GHz if noscan option is set, which also + skips secondary channel scan just like noscan works in AP mode. + --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c -@@ -2600,6 +2600,7 @@ static const struct parse_data ssid_fiel +@@ -2639,6 +2639,7 @@ static const struct parse_data ssid_fiel #else /* CONFIG_MESH */ { INT_RANGE(mode, 0, 4) }, #endif /* CONFIG_MESH */ @@ -18,6 +23,17 @@ INT(mesh_fwding); INT(frequency); INT(enable_edmg); +--- a/wpa_supplicant/config_ssid.h ++++ b/wpa_supplicant/config_ssid.h +@@ -1035,6 +1035,8 @@ struct wpa_ssid { + */ + int no_auto_peer; + ++ int noscan; ++ + /** + * mesh_rssi_threshold - Set mesh parameter mesh_rssi_threshold (dBm) + * --- a/wpa_supplicant/mesh.c +++ b/wpa_supplicant/mesh.c @@ -506,6 +506,8 @@ static int wpa_supplicant_mesh_init(stru @@ -31,7 +47,7 @@ /* --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c -@@ -2710,7 +2710,7 @@ static bool ibss_mesh_can_use_vht(struct +@@ -2770,7 +2770,7 @@ static bool ibss_mesh_can_use_vht(struct const struct wpa_ssid *ssid, struct hostapd_hw_modes *mode) { @@ -40,25 +56,25 @@ return false; if (!drv_supports_vht(wpa_s, ssid)) -@@ -2783,7 +2783,7 @@ static void ibss_mesh_select_40mhz(struc +@@ -2843,7 +2843,7 @@ static void ibss_mesh_select_40mhz(struc int i, res; unsigned int j; static const int ht40plus[] = { -- 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157, 165, 173, -+ 1, 2, 3, 4, 5, 6, 7, 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157, 165, 173, - 184, 192 +- 36, 44, 52, 60, 100, 108, 116, 124, 132, 140, ++ 1, 2, 3, 4, 5, 6, 7, 36, 44, 52, 60, 100, 108, 116, 124, 132, 140, + 149, 157, 165, 173, 184, 192 }; int ht40 = -1; -@@ -3033,7 +3033,7 @@ void ibss_mesh_setup_freq(struct wpa_sup +@@ -3093,7 +3093,7 @@ void ibss_mesh_setup_freq(struct wpa_sup int ieee80211_mode = wpas_mode_to_ieee80211_mode(ssid->mode); enum hostapd_hw_mode hw_mode; struct hostapd_hw_modes *mode = NULL; - int i, obss_scan = 1; + int i, obss_scan = !(ssid->noscan); u8 channel; - bool is_6ghz; + bool is_6ghz, is_24ghz; bool dfs_enabled = wpa_s->conf->country[0] && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_RADAR); -@@ -3080,6 +3080,8 @@ void ibss_mesh_setup_freq(struct wpa_sup +@@ -3143,6 +3143,8 @@ void ibss_mesh_setup_freq(struct wpa_sup freq->he_enabled = ibss_mesh_can_use_he(wpa_s, ssid, mode, ieee80211_mode); freq->channel = channel; @@ -67,14 +83,3 @@ /* Setup higher BW only for 5 GHz */ if (mode->mode == HOSTAPD_MODE_IEEE80211A) { ibss_mesh_select_40mhz(wpa_s, ssid, mode, freq, obss_scan, dfs_enabled); ---- a/wpa_supplicant/config_ssid.h -+++ b/wpa_supplicant/config_ssid.h -@@ -1035,6 +1035,8 @@ struct wpa_ssid { - */ - int no_auto_peer; - -+ int noscan; -+ - /** - * mesh_rssi_threshold - Set mesh parameter mesh_rssi_threshold (dBm) - * diff --git a/package/network/services/hostapd/patches/310-rescan_immediately.patch b/package/network/services/hostapd/patches/310-rescan_immediately.patch index 6e0244bca29236..57e13dec8bd8c9 100644 --- a/package/network/services/hostapd/patches/310-rescan_immediately.patch +++ b/package/network/services/hostapd/patches/310-rescan_immediately.patch @@ -1,6 +1,11 @@ +From 64268c716596edbad395cfa82ff30eb84a2f8488 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Sat, 23 Jan 2010 08:28:26 +0000 +Subject: [PATCH] rescan_immediately.patch + --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c -@@ -5769,7 +5769,7 @@ wpa_supplicant_alloc(struct wpa_supplica +@@ -5870,7 +5870,7 @@ wpa_supplicant_alloc(struct wpa_supplica if (wpa_s == NULL) return NULL; wpa_s->scan_req = INITIAL_SCAN_REQ; diff --git a/package/network/services/hostapd/patches/320-optional_rfkill.patch b/package/network/services/hostapd/patches/320-optional_rfkill.patch index 01537790e052a3..dd6fa1d05302b8 100644 --- a/package/network/services/hostapd/patches/320-optional_rfkill.patch +++ b/package/network/services/hostapd/patches/320-optional_rfkill.patch @@ -1,3 +1,7 @@ +From: Felix Fietkau +Date: Thu, 8 Jul 2010 18:36:22 +0000 +Subject: [PATCH] hostapd: make rfkill support optional + --- a/src/drivers/drivers.mak +++ b/src/drivers/drivers.mak @@ -54,7 +54,6 @@ NEED_SME=y diff --git a/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch b/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch index c11c9572169ffe..70ec6dc63b0dd2 100644 --- a/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch +++ b/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch @@ -1,6 +1,11 @@ +From ee68734929edb30f90a95bc3150038333b345476 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Sun, 30 Jun 2013 21:01:13 +0000 +Subject: [PATCH] nl80211_fix_set_freq.patch + --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c -@@ -5407,7 +5407,7 @@ static int nl80211_set_channel(struct i8 +@@ -5483,7 +5483,7 @@ static int nl80211_set_channel(struct i8 freq->he_enabled, freq->eht_enabled, freq->bandwidth, freq->center_freq1, freq->center_freq2); diff --git a/package/network/services/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch b/package/network/services/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch index 2173f0eb686a05..4a5852af2e4558 100644 --- a/package/network/services/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch +++ b/package/network/services/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch @@ -1,6 +1,11 @@ +From: Felix Fietkau +Date: Mon, 28 Jan 2019 21:36:44 +0100 +Subject: [PATCH] wpa_supplicant: fix calling channel switch via wpa_cli on + mesh interfaces + --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c -@@ -1837,15 +1837,35 @@ int ap_switch_channel(struct wpa_supplic +@@ -1846,17 +1846,37 @@ int ap_switch_channel(struct wpa_supplic #ifdef CONFIG_CTRL_IFACE @@ -24,15 +29,19 @@ struct csa_settings settings; int ret = hostapd_parse_csa_settings(pos, &settings); +- if (ret) +- return ret; + if (!(wpa_s->ap_iface && wpa_s->ap_iface->bss[0]) && + !(wpa_s->ifmsh && wpa_s->ifmsh->bss[0])) + return -1; -+ -+ ret = __ap_ctrl_iface_chanswitch(wpa_s->ap_iface, &settings); - if (ret) - return ret; + + settings.link_id = -1; - return ap_switch_channel(wpa_s, &settings); ++ ret = __ap_ctrl_iface_chanswitch(wpa_s->ap_iface, &settings); ++ if (ret) ++ return ret; ++ + return __ap_ctrl_iface_chanswitch(wpa_s->ifmsh, &settings); } #endif /* CONFIG_CTRL_IFACE */ diff --git a/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch b/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch index 647ca2cbf9751e..5ad4d6387fb633 100644 --- a/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch +++ b/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch @@ -1,6 +1,10 @@ +From: Felix Fietkau +Date: Sat, 23 Oct 2010 23:39:54 +0000 +Subject: [PATCH] nl80211_del_beacon_bss.patch + --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c -@@ -3008,12 +3008,12 @@ static int wpa_driver_nl80211_del_beacon +@@ -3075,12 +3075,12 @@ static int wpa_driver_nl80211_del_beacon return 0; wpa_printf(MSG_DEBUG, "nl80211: Remove beacon (ifindex=%d)", @@ -15,16 +19,17 @@ if (!msg) return -ENOBUFS; -@@ -6100,7 +6100,7 @@ static void nl80211_teardown_ap(struct i +@@ -6176,8 +6176,7 @@ static void nl80211_teardown_ap(struct i nl80211_mgmt_unsubscribe(bss, "AP teardown"); nl80211_put_wiphy_data_ap(bss); -- bss->flink->beacon_set = 0; +- if (bss->flink) +- bss->flink->beacon_set = 0; + wpa_driver_nl80211_del_beacon_all(bss); } -@@ -8859,8 +8859,6 @@ static int wpa_driver_nl80211_if_remove( +@@ -8977,8 +8976,6 @@ static int wpa_driver_nl80211_if_remove( } else { wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context"); nl80211_teardown_ap(bss); diff --git a/package/network/services/hostapd/patches/381-hostapd_cli_UNKNOWN-COMMAND.patch b/package/network/services/hostapd/patches/381-hostapd_cli_UNKNOWN-COMMAND.patch index e9083f6ecc6d58..e68edacb44062c 100644 --- a/package/network/services/hostapd/patches/381-hostapd_cli_UNKNOWN-COMMAND.patch +++ b/package/network/services/hostapd/patches/381-hostapd_cli_UNKNOWN-COMMAND.patch @@ -1,6 +1,17 @@ +From: Denton Gentry +Date: Wed, 30 May 2018 15:05:42 +0000 +Subject: [PATCH] hostapd: make cli treat UNKNOWN COMMAND as failing + +Avoid infinite loop at 100% CPU when running hostapd_cli +if CONFIG_CTRL_IFACE_MIB is not defined. + + _newselect(4, [3], NULL, NULL, ...) + recvfrom(3, "UNKNOWN COMMAND\n", 4095, 0, NULL, NULL) = 16 + sendto(3, "STA-NEXT UNKNOWN COMMAND", 24, 0, NULL, 0) = 24 + --- a/hostapd/hostapd_cli.c +++ b/hostapd/hostapd_cli.c -@@ -757,7 +757,7 @@ static int wpa_ctrl_command_sta(struct w +@@ -753,7 +753,7 @@ static int wpa_ctrl_command_sta(struct w } buf[len] = '\0'; diff --git a/package/network/services/hostapd/patches/400-wps_single_auth_enc_type.patch b/package/network/services/hostapd/patches/400-wps_single_auth_enc_type.patch index edcd98525743ed..65452a7c407967 100644 --- a/package/network/services/hostapd/patches/400-wps_single_auth_enc_type.patch +++ b/package/network/services/hostapd/patches/400-wps_single_auth_enc_type.patch @@ -1,3 +1,10 @@ +From: Felix Fietkau +Date: Sat, 9 Jul 2011 07:19:55 +0000 +Subject: [PATCH] hostapd: only advertise a single encryption type via WPS if + multiple are supported + +Fixes windows 7 interop issues + --- a/src/ap/wps_hostapd.c +++ b/src/ap/wps_hostapd.c @@ -394,9 +394,8 @@ static int hapd_wps_reconfig_in_memory(s diff --git a/package/network/services/hostapd/patches/410-limit_debug_messages.patch b/package/network/services/hostapd/patches/410-limit_debug_messages.patch index 48a5589200f198..58dd415f0969cb 100644 --- a/package/network/services/hostapd/patches/410-limit_debug_messages.patch +++ b/package/network/services/hostapd/patches/410-limit_debug_messages.patch @@ -1,3 +1,8 @@ +From: Felix Fietkau +Date: Mon, 20 Feb 2012 23:41:52 +0000 +Subject: [PATCH] hostapd: add configurable debug message minimum priority to + cut down on bloat generated by excessive debug messages + --- a/src/utils/wpa_debug.c +++ b/src/utils/wpa_debug.c @@ -206,7 +206,7 @@ void wpa_debug_close_linux_tracing(void) diff --git a/package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch b/package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch index 8084b593dcd049..ac1c9280b75656 100644 --- a/package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch +++ b/package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch @@ -14,15 +14,7 @@ Signed-hostap: Antonio Quartulli --- a/src/drivers/driver.h +++ b/src/drivers/driver.h -@@ -19,6 +19,7 @@ - - #define WPA_SUPPLICANT_DRIVER_VERSION 4 - -+#include "ap/sta_info.h" - #include "common/defs.h" - #include "common/ieee802_11_defs.h" - #include "common/wpa_common.h" -@@ -960,6 +961,9 @@ struct wpa_driver_associate_params { +@@ -971,6 +971,9 @@ struct wpa_driver_associate_params { * responsible for selecting with which BSS to associate. */ const u8 *bssid; @@ -42,7 +34,7 @@ Signed-hostap: Antonio Quartulli #include "config.h" -@@ -2389,6 +2390,97 @@ static char * wpa_config_write_mac_value +@@ -2421,6 +2422,97 @@ static char * wpa_config_write_mac_value #endif /* NO_CONFIG_WRITE */ @@ -140,7 +132,7 @@ Signed-hostap: Antonio Quartulli /* Helper macros for network block parser */ #ifdef OFFSET -@@ -2674,6 +2766,8 @@ static const struct parse_data ssid_fiel +@@ -2713,6 +2805,8 @@ static const struct parse_data ssid_fiel { INT(ap_max_inactivity) }, { INT(dtim_period) }, { INT(beacon_int) }, @@ -151,18 +143,7 @@ Signed-hostap: Antonio Quartulli { INT_RANGE(macsec_integ_only, 0, 1) }, --- a/wpa_supplicant/config_ssid.h +++ b/wpa_supplicant/config_ssid.h -@@ -10,8 +10,10 @@ - #define CONFIG_SSID_H - - #include "common/defs.h" -+#include "ap/sta_info.h" - #include "utils/list.h" - #include "eap_peer/eap_config.h" -+#include "drivers/nl80211_copy.h" - - - #define DEFAULT_EAP_WORKAROUND ((unsigned int) -1) -@@ -879,6 +881,9 @@ struct wpa_ssid { +@@ -879,6 +879,9 @@ struct wpa_ssid { */ void *parent_cred; @@ -174,7 +155,7 @@ Signed-hostap: Antonio Quartulli * macsec_policy - Determines the policy for MACsec secure session --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c -@@ -4177,6 +4177,12 @@ static void wpas_start_assoc_cb(struct w +@@ -4249,6 +4249,12 @@ static void wpas_start_assoc_cb(struct w params.beacon_int = ssid->beacon_int; else params.beacon_int = wpa_s->conf->beacon_int; diff --git a/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch b/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch index f46c95fab77935..c24ca46e969faf 100644 --- a/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch +++ b/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch @@ -19,7 +19,7 @@ Tested-by: Simon Wunderlich --- a/src/drivers/driver.h +++ b/src/drivers/driver.h -@@ -1834,6 +1834,7 @@ struct wpa_driver_mesh_join_params { +@@ -1876,6 +1876,7 @@ struct wpa_driver_mesh_join_params { #define WPA_DRIVER_MESH_FLAG_AMPE 0x00000008 unsigned int flags; bool handle_dfs; @@ -29,7 +29,7 @@ Tested-by: Simon Wunderlich struct wpa_driver_set_key_params { --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c -@@ -11677,6 +11677,18 @@ static int nl80211_put_mesh_id(struct nl +@@ -11850,6 +11850,18 @@ static int nl80211_put_mesh_id(struct nl } @@ -48,7 +48,7 @@ Tested-by: Simon Wunderlich static int nl80211_put_mesh_config(struct nl_msg *msg, struct wpa_driver_mesh_bss_params *params) { -@@ -11738,6 +11750,7 @@ static int nl80211_join_mesh(struct i802 +@@ -11911,6 +11923,7 @@ static int nl80211_join_mesh(struct i802 nl80211_put_basic_rates(msg, params->basic_rates) || nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) || nl80211_put_beacon_int(msg, params->beacon_int) || diff --git a/package/network/services/hostapd/patches/464-fix-mesh-obss-check.patch b/package/network/services/hostapd/patches/464-fix-mesh-obss-check.patch index 4d7d85f4ab8ea5..664f27bd63ad64 100644 --- a/package/network/services/hostapd/patches/464-fix-mesh-obss-check.patch +++ b/package/network/services/hostapd/patches/464-fix-mesh-obss-check.patch @@ -1,6 +1,11 @@ +From: Felix Fietkau +Date: Tue, 14 Nov 2017 12:38:08 +0100 +Subject: [PATCH] Fix issues with disabling obss scan when using fixed_freq on + mesh + --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c -@@ -3040,6 +3040,10 @@ void ibss_mesh_setup_freq(struct wpa_sup +@@ -3100,6 +3100,10 @@ void ibss_mesh_setup_freq(struct wpa_sup freq->freq = ssid->frequency; diff --git a/package/network/services/hostapd/patches/465-hostapd-config-support-random-BSS-color.patch b/package/network/services/hostapd/patches/465-hostapd-config-support-random-BSS-color.patch index ec10db8ed1494b..8da7a2948eaca9 100644 --- a/package/network/services/hostapd/patches/465-hostapd-config-support-random-BSS-color.patch +++ b/package/network/services/hostapd/patches/465-hostapd-config-support-random-BSS-color.patch @@ -13,7 +13,7 @@ Signed-off-by: David Bauer --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -3502,6 +3502,8 @@ static int hostapd_config_fill(struct ho +@@ -3708,6 +3708,8 @@ static int hostapd_config_fill(struct ho } else if (os_strcmp(buf, "he_bss_color") == 0) { conf->he_op.he_bss_color = atoi(pos) & 0x3f; conf->he_op.he_bss_color_disabled = 0; diff --git a/package/network/services/hostapd/patches/470-survey_data_fallback.patch b/package/network/services/hostapd/patches/470-survey_data_fallback.patch index 79ab48c5c27486..1ae2c599ebb0a7 100644 --- a/package/network/services/hostapd/patches/470-survey_data_fallback.patch +++ b/package/network/services/hostapd/patches/470-survey_data_fallback.patch @@ -1,6 +1,10 @@ +From: Felix Fietkau +Date: Wed, 15 Jun 2016 17:31:48 +0200 +Subject: [PATCH] hostapd: implement fallback for incomplete survey data + --- a/src/ap/acs.c +++ b/src/ap/acs.c -@@ -455,17 +455,17 @@ static int acs_get_bw_center_chan(int fr +@@ -467,17 +467,17 @@ static int acs_get_bw_center_chan(int fr static int acs_survey_is_sufficient(struct freq_survey *survey) { if (!(survey->filled & SURVEY_HAS_NF)) { @@ -20,7 +24,7 @@ } if (!(survey->filled & SURVEY_HAS_CHAN_TIME_BUSY) && -@@ -473,7 +473,6 @@ static int acs_survey_is_sufficient(stru +@@ -485,7 +485,6 @@ static int acs_survey_is_sufficient(stru wpa_printf(MSG_INFO, "ACS: Survey for freq %d is missing RX and busy time (at least one is required)", survey->freq); diff --git a/package/network/services/hostapd/patches/590-rrm-wnm-statistics.patch b/package/network/services/hostapd/patches/590-rrm-wnm-statistics.patch index 0efa6db9085f2b..e1bb37ea55f109 100644 --- a/package/network/services/hostapd/patches/590-rrm-wnm-statistics.patch +++ b/package/network/services/hostapd/patches/590-rrm-wnm-statistics.patch @@ -1,3 +1,13 @@ +From: David Bauer +Date: Sat, 27 Nov 2021 22:08:28 +0100 +Subject: [PATCH] hostapd: add OpenWrt specific statistic counters + +This adds a new struct for storing statistics not (yet) tracked by +hostapd regarding RRM and WNM activity. + +These statistics can be read using the get_status hostapd interface ubus +method. + --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -163,6 +163,21 @@ struct hostapd_sae_commit_queue { @@ -32,9 +42,20 @@ int num_sta; /* number of entries in sta_list */ struct sta_info *sta_list; /* STA info list head */ #define STA_HASH_SIZE 256 +--- a/src/ap/rrm.c ++++ b/src/ap/rrm.c +@@ -269,6 +269,8 @@ static void hostapd_send_nei_report_resp + } + } + ++ hapd->openwrt_stats.rrm.neighbor_report_tx++; ++ + hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr, + wpabuf_head(buf), wpabuf_len(buf)); + wpabuf_free(buf); --- a/src/ap/wnm_ap.c +++ b/src/ap/wnm_ap.c -@@ -386,6 +386,7 @@ static int ieee802_11_send_bss_trans_mgm +@@ -410,6 +410,7 @@ static int ieee802_11_send_bss_trans_mgm mgmt->u.action.u.bss_tm_req.validity_interval = 1; pos = mgmt->u.action.u.bss_tm_req.variable; @@ -42,7 +63,7 @@ wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to " MACSTR " dialog_token=%u req_mode=0x%x disassoc_timer=%u " "validity_interval=%u", -@@ -790,10 +791,12 @@ int ieee802_11_rx_wnm_action_ap(struct h +@@ -814,10 +815,12 @@ int ieee802_11_rx_wnm_action_ap(struct h plen); return 0; case WNM_BSS_TRANS_MGMT_QUERY: @@ -55,7 +76,7 @@ ieee802_11_rx_bss_trans_mgmt_resp(hapd, mgmt->sa, payload, plen); return 0; -@@ -840,6 +843,7 @@ int wnm_send_disassoc_imminent(struct ho +@@ -865,6 +868,7 @@ int wnm_send_disassoc_imminent(struct ho pos = mgmt->u.action.u.bss_tm_req.variable; @@ -63,7 +84,7 @@ wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request frame to indicate imminent disassociation (disassoc_timer=%d) to " MACSTR, disassoc_timer, MAC2STR(sta->addr)); if (hostapd_drv_send_mlme(hapd, buf, pos - buf, 0, NULL, 0, 0) < 0) { -@@ -921,6 +925,7 @@ int wnm_send_ess_disassoc_imminent(struc +@@ -947,6 +951,7 @@ int wnm_send_ess_disassoc_imminent(struc return -1; } @@ -71,22 +92,11 @@ if (disassoc_timer) { /* send disassociation frame after time-out */ set_disassoc_timer(hapd, sta, disassoc_timer); -@@ -1001,6 +1006,7 @@ int wnm_send_bss_tm_req(struct hostapd_d +@@ -1028,6 +1033,7 @@ int wnm_send_bss_tm_req(struct hostapd_d } os_free(buf); + hapd->openwrt_stats.wnm.bss_transition_request_tx++; if (disassoc_timer) { - /* send disassociation frame after time-out */ - set_disassoc_timer(hapd, sta, disassoc_timer); ---- a/src/ap/rrm.c -+++ b/src/ap/rrm.c -@@ -269,6 +269,8 @@ static void hostapd_send_nei_report_resp - } - } - -+ hapd->openwrt_stats.rrm.neighbor_report_tx++; -+ - hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr, - wpabuf_head(buf), wpabuf_len(buf)); - wpabuf_free(buf); + #ifdef CONFIG_IEEE80211BE + if (ap_sta_is_mld(hapd, sta)) { diff --git a/package/network/services/hostapd/patches/600-ubus_support.patch b/package/network/services/hostapd/patches/600-ubus_support.patch index 10ca946050c72d..0457f37f74c982 100644 --- a/package/network/services/hostapd/patches/600-ubus_support.patch +++ b/package/network/services/hostapd/patches/600-ubus_support.patch @@ -1,3 +1,10 @@ +From: Felix Fietkau +Date: Sun, 17 Mar 2013 20:47:18 +0000 +Subject: [PATCH] hostapd: initial prototype of an ubus binding + +Supports listing, removing and banning clients, and hooking into +probe/assoc/auth requests via object subscribe. + --- a/hostapd/Makefile +++ b/hostapd/Makefile @@ -166,6 +166,12 @@ OBJS += ../src/common/hw_features_common @@ -12,36 +19,106 @@ +endif ifdef CONFIG_CODE_COVERAGE - CFLAGS += -O0 -fprofile-arcs -ftest-coverage ---- a/src/ap/hostapd.h -+++ b/src/ap/hostapd.h -@@ -18,6 +18,7 @@ - #include "utils/list.h" - #include "ap_config.h" - #include "drivers/driver.h" -+#include "ubus.h" + CFLAGS += -O0 -fprofile-arcs -ftest-coverage -U_FORTIFY_SOURCE +--- a/src/ap/airtime_policy.c ++++ b/src/ap/airtime_policy.c +@@ -112,8 +112,14 @@ static void set_sta_weights(struct hosta + { + struct sta_info *sta; - #define OCE_STA_CFON_ENABLED(hapd) \ - ((hapd->conf->oce & OCE_STA_CFON) && \ -@@ -184,6 +185,7 @@ struct hostapd_data { - struct hostapd_iface *iface; - struct hostapd_config *iconf; - struct hostapd_bss_config *conf; -+ struct hostapd_ubus_bss ubus; - int interface_added; /* virtual interface added for this BSS */ - unsigned int started:1; - unsigned int disabled:1; -@@ -695,6 +697,7 @@ hostapd_alloc_bss_data(struct hostapd_if - struct hostapd_bss_config *bss); - int hostapd_setup_interface(struct hostapd_iface *iface); - int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err); -+void hostapd_set_own_neighbor_report(struct hostapd_data *hapd); - void hostapd_interface_deinit(struct hostapd_iface *iface); - void hostapd_interface_free(struct hostapd_iface *iface); - struct hostapd_iface * hostapd_alloc_iface(void); +- for (sta = hapd->sta_list; sta; sta = sta->next) +- sta_set_airtime_weight(hapd, sta, weight); ++ for (sta = hapd->sta_list; sta; sta = sta->next) { ++ unsigned int sta_weight = weight; ++ ++ if (sta->dyn_airtime_weight) ++ sta_weight = (weight * sta->dyn_airtime_weight) / 256; ++ ++ sta_set_airtime_weight(hapd, sta, sta_weight); ++ } + } + + +@@ -244,7 +250,10 @@ int airtime_policy_new_sta(struct hostap + unsigned int weight; + + if (hapd->iconf->airtime_mode == AIRTIME_MODE_STATIC) { +- weight = get_weight_for_sta(hapd, sta->addr); ++ if (sta->dyn_airtime_weight) ++ weight = sta->dyn_airtime_weight; ++ else ++ weight = get_weight_for_sta(hapd, sta->addr); + if (weight) + return sta_set_airtime_weight(hapd, sta, weight); + } +--- a/src/ap/beacon.c ++++ b/src/ap/beacon.c +@@ -1351,6 +1351,12 @@ void handle_probe_req(struct hostapd_dat + int mld_id; + u16 links; + #endif /* CONFIG_IEEE80211BE */ ++ struct hostapd_ubus_request req = { ++ .type = HOSTAPD_UBUS_PROBE_REQ, ++ .mgmt_frame = mgmt, ++ .ssi_signal = ssi_signal, ++ .elems = &elems, ++ }; + + if (hapd->iconf->rssi_ignore_probe_request && ssi_signal && + ssi_signal < hapd->iconf->rssi_ignore_probe_request) +@@ -1537,6 +1543,12 @@ void handle_probe_req(struct hostapd_dat + } + #endif /* CONFIG_P2P */ + ++ if (hostapd_ubus_handle_event(hapd, &req)) { ++ wpa_printf(MSG_DEBUG, "Probe request for " MACSTR " rejected by ubus handler.\n", ++ MAC2STR(mgmt->sa)); ++ return; ++ } ++ + /* TODO: verify that supp_rates contains at least one matching rate + * with AP configuration */ + +--- a/src/ap/dfs.c ++++ b/src/ap/dfs.c +@@ -1225,6 +1225,8 @@ int hostapd_dfs_pre_cac_expired(struct h + "freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d", + freq, ht_enabled, chan_offset, chan_width, cf1, cf2); + ++ hostapd_ubus_notify_radar_detected(iface, freq, chan_width, cf1, cf2); ++ + /* Proceed only if DFS is not offloaded to the driver */ + if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) + return 0; +--- a/src/ap/drv_callbacks.c ++++ b/src/ap/drv_callbacks.c +@@ -268,6 +268,10 @@ int hostapd_notif_assoc(struct hostapd_d + struct hostapd_iface *iface = hapd->iface; + #endif /* CONFIG_OWE */ + bool updated = false; ++ struct hostapd_ubus_request req = { ++ .type = HOSTAPD_UBUS_ASSOC_REQ, ++ .addr = addr, ++ }; + + if (addr == NULL) { + /* +@@ -412,6 +416,12 @@ int hostapd_notif_assoc(struct hostapd_d + goto fail; + } + ++ if (hostapd_ubus_handle_event(hapd, &req)) { ++ wpa_printf(MSG_DEBUG, "Station " MACSTR " assoc rejected by ubus handler.\n", ++ MAC2STR(req.addr)); ++ goto fail; ++ } ++ + #ifdef CONFIG_P2P + if (elems.p2p) { + wpabuf_free(sta->p2p_ie); --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c -@@ -435,6 +435,7 @@ void hostapd_free_hapd_data(struct hosta +@@ -493,6 +493,7 @@ void hostapd_free_hapd_data(struct hosta hapd->beacon_set_done = 0; wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); @@ -49,7 +126,7 @@ accounting_deinit(hapd); hostapd_deinit_wpa(hapd); vlan_deinit(hapd); -@@ -1187,6 +1188,8 @@ static int hostapd_start_beacon(struct h +@@ -1274,6 +1275,8 @@ static int hostapd_start_beacon(struct h if (hapd->driver && hapd->driver->set_operstate) hapd->driver->set_operstate(hapd->drv_priv, 1); @@ -58,7 +135,7 @@ return 0; } -@@ -2275,6 +2278,7 @@ static int hostapd_setup_interface_compl +@@ -2367,6 +2370,7 @@ static int hostapd_setup_interface_compl if (err) goto fail; @@ -66,7 +143,7 @@ wpa_printf(MSG_DEBUG, "Completing interface initialization"); if (iface->freq) { #ifdef NEED_AP_MLME -@@ -2494,6 +2498,7 @@ dfs_offload: +@@ -2586,6 +2590,7 @@ dfs_offload: fail: wpa_printf(MSG_ERROR, "Interface initialization failed"); @@ -74,7 +151,7 @@ if (iface->is_no_ir) { hostapd_set_state(iface, HAPD_IFACE_NO_IR); -@@ -2984,6 +2989,7 @@ void hostapd_interface_deinit_free(struc +@@ -3076,6 +3081,7 @@ void hostapd_interface_deinit_free(struc (unsigned int) iface->conf->num_bss); driver = iface->bss[0]->driver; drv_priv = iface->bss[0]->drv_priv; @@ -82,9 +159,35 @@ hostapd_interface_deinit(iface); wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", __func__, driver, drv_priv); +--- a/src/ap/hostapd.h ++++ b/src/ap/hostapd.h +@@ -18,6 +18,7 @@ + #include "utils/list.h" + #include "ap_config.h" + #include "drivers/driver.h" ++#include "ubus.h" + + #define OCE_STA_CFON_ENABLED(hapd) \ + ((hapd->conf->oce & OCE_STA_CFON) && \ +@@ -184,6 +185,7 @@ struct hostapd_data { + struct hostapd_iface *iface; + struct hostapd_config *iconf; + struct hostapd_bss_config *conf; ++ struct hostapd_ubus_bss ubus; + int interface_added; /* virtual interface added for this BSS */ + unsigned int started:1; + unsigned int disabled:1; +@@ -707,6 +709,7 @@ hostapd_alloc_bss_data(struct hostapd_if + struct hostapd_bss_config *bss); + int hostapd_setup_interface(struct hostapd_iface *iface); + int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err); ++void hostapd_set_own_neighbor_report(struct hostapd_data *hapd); + void hostapd_interface_deinit(struct hostapd_iface *iface); + void hostapd_interface_free(struct hostapd_iface *iface); + struct hostapd_iface * hostapd_alloc_iface(void); --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c -@@ -2786,7 +2786,7 @@ static void handle_auth(struct hostapd_d +@@ -2798,7 +2798,7 @@ static void handle_auth(struct hostapd_d u16 auth_alg, auth_transaction, status_code; u16 resp = WLAN_STATUS_SUCCESS; struct sta_info *sta = NULL; @@ -93,7 +196,7 @@ u16 fc; const u8 *challenge = NULL; u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN]; -@@ -2795,6 +2795,11 @@ static void handle_auth(struct hostapd_d +@@ -2807,6 +2807,11 @@ static void handle_auth(struct hostapd_d struct radius_sta rad_info; const u8 *dst, *sa, *bssid; bool mld_sta = false; @@ -105,7 +208,7 @@ if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) { wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)", -@@ -2986,6 +2991,13 @@ static void handle_auth(struct hostapd_d +@@ -2998,6 +3003,13 @@ static void handle_auth(struct hostapd_d resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } @@ -119,7 +222,7 @@ if (res == HOSTAPD_ACL_PENDING) return; -@@ -5156,7 +5168,7 @@ static void handle_assoc(struct hostapd_ +@@ -5242,7 +5254,7 @@ static void handle_assoc(struct hostapd_ int resp = WLAN_STATUS_SUCCESS; u16 reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE; const u8 *pos; @@ -128,7 +231,7 @@ struct sta_info *sta; u8 *tmp = NULL; #ifdef CONFIG_FILS -@@ -5374,6 +5386,11 @@ static void handle_assoc(struct hostapd_ +@@ -5484,6 +5496,11 @@ static void handle_assoc(struct hostapd_ left = res; } #endif /* CONFIG_FILS */ @@ -140,9 +243,9 @@ /* followed by SSID and Supported rates; and HT capabilities if 802.11n * is used */ -@@ -5472,6 +5489,13 @@ static void handle_assoc(struct hostapd_ - } - #endif /* CONFIG_FILS */ +@@ -5586,6 +5603,13 @@ static void handle_assoc(struct hostapd_ + if (set_beacon) + ieee802_11_set_beacons(hapd->iface); + ubus_resp = hostapd_ubus_handle_event(hapd, &req); + if (ubus_resp) { @@ -154,7 +257,7 @@ fail: /* -@@ -5753,6 +5777,7 @@ static void handle_disassoc(struct hosta +@@ -5836,6 +5860,7 @@ static void handle_disassoc(struct hosta (unsigned long) len); return; } @@ -162,7 +265,7 @@ sta = ap_get_sta(hapd, mgmt->sa); if (!sta) { -@@ -5784,6 +5809,8 @@ static void handle_deauth(struct hostapd +@@ -5867,6 +5892,8 @@ static void handle_deauth(struct hostapd /* Clear the PTKSA cache entries for PASN */ ptksa_cache_flush(hapd->ptksa, mgmt->sa, WPA_CIPHER_NONE); @@ -171,63 +274,31 @@ sta = ap_get_sta(hapd, mgmt->sa); if (!sta) { wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -1045,6 +1045,12 @@ void handle_probe_req(struct hostapd_dat - u16 csa_offs[2]; - size_t csa_offs_len; - struct radius_sta rad_info; -+ struct hostapd_ubus_request req = { -+ .type = HOSTAPD_UBUS_PROBE_REQ, -+ .mgmt_frame = mgmt, -+ .ssi_signal = ssi_signal, -+ .elems = &elems, -+ }; - - if (hapd->iconf->rssi_ignore_probe_request && ssi_signal && - ssi_signal < hapd->iconf->rssi_ignore_probe_request) -@@ -1231,6 +1237,12 @@ void handle_probe_req(struct hostapd_dat - } - #endif /* CONFIG_P2P */ - -+ if (hostapd_ubus_handle_event(hapd, &req)) { -+ wpa_printf(MSG_DEBUG, "Probe request for " MACSTR " rejected by ubus handler.\n", -+ MAC2STR(mgmt->sa)); +--- a/src/ap/rrm.c ++++ b/src/ap/rrm.c +@@ -89,6 +89,9 @@ static void hostapd_handle_beacon_report + return; + wpa_msg(hapd->msg_ctx, MSG_INFO, BEACON_RESP_RX MACSTR " %u %02x %s", + MAC2STR(addr), token, rep_mode, report); ++ if (len < sizeof(struct rrm_measurement_beacon_report)) + return; -+ } -+ - /* TODO: verify that supp_rates contains at least one matching rate - * with AP configuration */ ++ hostapd_ubus_notify_beacon_report(hapd, addr, token, rep_mode, (struct rrm_measurement_beacon_report*) pos, len); + } ---- a/src/ap/drv_callbacks.c -+++ b/src/ap/drv_callbacks.c -@@ -260,6 +260,10 @@ int hostapd_notif_assoc(struct hostapd_d - u16 reason = WLAN_REASON_UNSPECIFIED; - int status = WLAN_STATUS_SUCCESS; - const u8 *p2p_dev_addr = NULL; -+ struct hostapd_ubus_request req = { -+ .type = HOSTAPD_UBUS_ASSOC_REQ, -+ .addr = addr, -+ }; - if (addr == NULL) { - /* -@@ -404,6 +408,12 @@ int hostapd_notif_assoc(struct hostapd_d - goto fail; - } +@@ -352,6 +355,9 @@ void hostapd_handle_radio_measurement(st + mgmt->u.action.u.rrm.action, MAC2STR(mgmt->sa)); -+ if (hostapd_ubus_handle_event(hapd, &req)) { -+ wpa_printf(MSG_DEBUG, "Station " MACSTR " assoc rejected by ubus handler.\n", -+ MAC2STR(req.addr)); -+ goto fail; -+ } -+ - #ifdef CONFIG_P2P - if (elems.p2p) { - wpabuf_free(sta->p2p_ie); + switch (mgmt->u.action.u.rrm.action) { ++ case WLAN_RRM_LINK_MEASUREMENT_REPORT: ++ hostapd_ubus_handle_link_measurement(hapd, buf, len); ++ break; + case WLAN_RRM_RADIO_MEASUREMENT_REPORT: + hostapd_handle_radio_msmt_report(hapd, buf, len); + break; --- a/src/ap/sta_info.c +++ b/src/ap/sta_info.c -@@ -471,6 +471,7 @@ void ap_handle_timer(void *eloop_ctx, vo +@@ -476,6 +476,7 @@ void ap_handle_timer(void *eloop_ctx, vo hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "deauthenticated due to " "local deauth request"); @@ -235,7 +306,7 @@ ap_free_sta(hapd, sta); return; } -@@ -626,6 +627,7 @@ skip_poll: +@@ -631,6 +632,7 @@ skip_poll: mlme_deauthenticate_indication( hapd, sta, WLAN_REASON_PREV_AUTH_NOT_VALID); @@ -243,8 +314,8 @@ ap_free_sta(hapd, sta); break; } -@@ -1344,15 +1346,28 @@ void ap_sta_set_authorized(struct hostap - sta->addr, authorized, dev_addr); +@@ -1448,15 +1450,28 @@ void ap_sta_set_authorized_event(struct + os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(sta->addr)); if (authorized) { + static const char * const auth_algs[] = { @@ -272,202 +343,54 @@ #ifdef CONFIG_P2P if (wpa_auth_get_ip_addr(sta->wpa_sm, ip_addr_buf) == 0) { os_snprintf(ip_addr, sizeof(ip_addr), -@@ -1362,6 +1377,13 @@ void ap_sta_set_authorized(struct hostap - } - #endif /* CONFIG_P2P */ - -+ if (sta->auth_alg < ARRAY_SIZE(auth_algs)) -+ auth_alg = auth_algs[sta->auth_alg]; -+ -+ if (auth_alg) -+ os_snprintf(alg_buf, sizeof(alg_buf), -+ " auth_alg=%s", auth_alg); -+ - keyid = ap_sta_wpa_get_keyid(hapd, sta); - if (keyid) { - os_snprintf(keyid_buf, sizeof(keyid_buf), -@@ -1380,17 +1402,19 @@ void ap_sta_set_authorized(struct hostap - dpp_pkhash, SHA256_MAC_LEN); - } - -- wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s", -- buf, ip_addr, keyid_buf, dpp_pkhash_buf); -+ hostapd_ubus_notify_authorized(hapd, sta, auth_alg); -+ wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s%s", -+ buf, ip_addr, keyid_buf, dpp_pkhash_buf, alg_buf); - - if (hapd->msg_ctx_parent && - hapd->msg_ctx_parent != hapd->msg_ctx) - wpa_msg_no_global(hapd->msg_ctx_parent, MSG_INFO, -- AP_STA_CONNECTED "%s%s%s%s", -+ AP_STA_CONNECTED "%s%s%s%s%s", - buf, ip_addr, keyid_buf, -- dpp_pkhash_buf); -+ dpp_pkhash_buf, alg_buf); - } else { - wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf); -+ hostapd_ubus_notify(hapd, "disassoc", sta->addr); - - if (hapd->msg_ctx_parent && - hapd->msg_ctx_parent != hapd->msg_ctx) ---- a/src/ap/wpa_auth_glue.c -+++ b/src/ap/wpa_auth_glue.c -@@ -269,6 +269,7 @@ static void hostapd_wpa_auth_psk_failure - struct hostapd_data *hapd = ctx; - wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POSSIBLE_PSK_MISMATCH MACSTR, - MAC2STR(addr)); -+ hostapd_ubus_notify(hapd, "key-mismatch", addr); - } - - ---- a/wpa_supplicant/Makefile -+++ b/wpa_supplicant/Makefile -@@ -192,6 +192,13 @@ ifdef CONFIG_EAPOL_TEST - CFLAGS += -Werror -DEAPOL_TEST - endif - -+ifdef CONFIG_UBUS -+CFLAGS += -DUBUS_SUPPORT -+OBJS += ubus.o -+OBJS += ../src/utils/uloop.o -+LIBS += -lubox -lubus -+endif -+ - ifdef CONFIG_CODE_COVERAGE - CFLAGS += -O0 -fprofile-arcs -ftest-coverage - LIBS += -lgcov -@@ -987,6 +994,9 @@ ifdef CONFIG_CTRL_IFACE_MIB - CFLAGS += -DCONFIG_CTRL_IFACE_MIB - endif - OBJS += ../src/ap/ctrl_iface_ap.o -+ifdef CONFIG_UBUS -+OBJS += ../src/ap/ubus.o -+endif - endif - - CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY ---- a/wpa_supplicant/wpa_supplicant.c -+++ b/wpa_supplicant/wpa_supplicant.c -@@ -7600,6 +7600,8 @@ struct wpa_supplicant * wpa_supplicant_a - } - #endif /* CONFIG_P2P */ - -+ wpas_ubus_add_bss(wpa_s); -+ - return wpa_s; - } - -@@ -7626,6 +7628,8 @@ int wpa_supplicant_remove_iface(struct w - struct wpa_supplicant *parent = wpa_s->parent; - #endif /* CONFIG_MESH */ - -+ wpas_ubus_free_bss(wpa_s); -+ - /* Remove interface from the global list of interfaces */ - prev = global->ifaces; - if (prev == wpa_s) { -@@ -7972,8 +7976,12 @@ int wpa_supplicant_run(struct wpa_global - eloop_register_signal_terminate(wpa_supplicant_terminate, global); - eloop_register_signal_reconfig(wpa_supplicant_reconfig, global); - -+ wpas_ubus_add(global); -+ - eloop_run(); - -+ wpas_ubus_free(global); -+ - return 0; - } - ---- a/wpa_supplicant/wpa_supplicant_i.h -+++ b/wpa_supplicant/wpa_supplicant_i.h -@@ -21,6 +21,7 @@ - #include "config_ssid.h" - #include "wmm_ac.h" - #include "pasn/pasn_common.h" -+#include "ubus.h" - - extern const char *const wpa_supplicant_version; - extern const char *const wpa_supplicant_license; -@@ -319,6 +320,8 @@ struct wpa_global { - #endif /* CONFIG_WIFI_DISPLAY */ - - struct psk_list_entry *add_psk; /* From group formation */ -+ -+ struct ubus_object ubus_global; - }; - - -@@ -685,6 +688,7 @@ struct wpa_supplicant { - unsigned char own_addr[ETH_ALEN]; - unsigned char perm_addr[ETH_ALEN]; - char ifname[100]; -+ struct wpas_ubus_bss ubus; - #ifdef CONFIG_MATCH_IFACE - int matched; - #endif /* CONFIG_MATCH_IFACE */ ---- a/wpa_supplicant/wps_supplicant.c -+++ b/wpa_supplicant/wps_supplicant.c -@@ -33,6 +33,7 @@ - #include "p2p/p2p.h" - #include "p2p_supplicant.h" - #include "wps_supplicant.h" -+#include "ubus.h" - - - #ifndef WPS_PIN_SCAN_IGNORE_SEL_REG -@@ -402,6 +403,8 @@ static int wpa_supplicant_wps_cred(void - wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute", - cred->cred_attr, cred->cred_attr_len); - -+ wpas_ubus_notify(wpa_s, cred); -+ - if (wpa_s->conf->wps_cred_processing == 1) - return 0; +@@ -1467,6 +1482,13 @@ void ap_sta_set_authorized_event(struct + } + #endif /* CONFIG_P2P */ ---- a/wpa_supplicant/main.c -+++ b/wpa_supplicant/main.c -@@ -203,7 +203,7 @@ int main(int argc, char *argv[]) ++ if (sta->auth_alg < ARRAY_SIZE(auth_algs)) ++ auth_alg = auth_algs[sta->auth_alg]; ++ ++ if (auth_alg) ++ os_snprintf(alg_buf, sizeof(alg_buf), ++ " auth_alg=%s", auth_alg); ++ + keyid = ap_sta_wpa_get_keyid(hapd, sta); + if (keyid) { + os_snprintf(keyid_buf, sizeof(keyid_buf), +@@ -1485,17 +1507,19 @@ void ap_sta_set_authorized_event(struct + dpp_pkhash, SHA256_MAC_LEN); + } - for (;;) { - c = getopt(argc, argv, -- "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuv::W"); -+ "b:Bc:C:D:de:f:g:G:hi:I:KLMm:nNo:O:p:P:qsTtuv::W"); - if (c < 0) - break; - switch (c) { -@@ -268,6 +268,9 @@ int main(int argc, char *argv[]) - params.conf_p2p_dev = optarg; - break; - #endif /* CONFIG_P2P */ -+ case 'n': -+ iface_count = 0; -+ break; - case 'o': - params.override_driver = optarg; - break; ---- a/src/ap/rrm.c -+++ b/src/ap/rrm.c -@@ -89,6 +89,9 @@ static void hostapd_handle_beacon_report - return; - wpa_msg(hapd->msg_ctx, MSG_INFO, BEACON_RESP_RX MACSTR " %u %02x %s", - MAC2STR(addr), token, rep_mode, report); -+ if (len < sizeof(struct rrm_measurement_beacon_report)) -+ return; -+ hostapd_ubus_notify_beacon_report(hapd, addr, token, rep_mode, (struct rrm_measurement_beacon_report*) pos, len); - } +- wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s", +- buf, ip_addr, keyid_buf, dpp_pkhash_buf); ++ hostapd_ubus_notify_authorized(hapd, sta, auth_alg); ++ wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s%s", ++ buf, ip_addr, keyid_buf, dpp_pkhash_buf, alg_buf); + if (hapd->msg_ctx_parent && + hapd->msg_ctx_parent != hapd->msg_ctx) + wpa_msg_no_global(hapd->msg_ctx_parent, MSG_INFO, +- AP_STA_CONNECTED "%s%s%s%s", ++ AP_STA_CONNECTED "%s%s%s%s%s", + buf, ip_addr, keyid_buf, +- dpp_pkhash_buf); ++ dpp_pkhash_buf, alg_buf); + } else { + wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf); ++ hostapd_ubus_notify(hapd, "disassoc", sta->addr); -@@ -352,6 +355,9 @@ void hostapd_handle_radio_measurement(st - mgmt->u.action.u.rrm.action, MAC2STR(mgmt->sa)); + if (hapd->msg_ctx_parent && + hapd->msg_ctx_parent != hapd->msg_ctx) +--- a/src/ap/sta_info.h ++++ b/src/ap/sta_info.h +@@ -319,6 +319,7 @@ struct sta_info { + #endif /* CONFIG_TESTING_OPTIONS */ + #ifdef CONFIG_AIRTIME_POLICY + unsigned int airtime_weight; ++ unsigned int dyn_airtime_weight; + struct os_reltime backlogged_until; + #endif /* CONFIG_AIRTIME_POLICY */ - switch (mgmt->u.action.u.rrm.action) { -+ case WLAN_RRM_LINK_MEASUREMENT_REPORT: -+ hostapd_ubus_handle_link_measurement(hapd, buf, len); -+ break; - case WLAN_RRM_RADIO_MEASUREMENT_REPORT: - hostapd_handle_radio_msmt_report(hapd, buf, len); - break; --- a/src/ap/vlan_init.c +++ b/src/ap/vlan_init.c @@ -22,6 +22,7 @@ @@ -506,61 +429,9 @@ return hostapd_vlan_if_remove(hapd, vlan->ifname); } ---- a/src/ap/dfs.c -+++ b/src/ap/dfs.c -@@ -1216,6 +1216,8 @@ int hostapd_dfs_pre_cac_expired(struct h - "freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d", - freq, ht_enabled, chan_offset, chan_width, cf1, cf2); - -+ hostapd_ubus_notify_radar_detected(iface, freq, chan_width, cf1, cf2); -+ - /* Proceed only if DFS is not offloaded to the driver */ - if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) - return 0; ---- a/src/ap/airtime_policy.c -+++ b/src/ap/airtime_policy.c -@@ -112,8 +112,14 @@ static void set_sta_weights(struct hosta - { - struct sta_info *sta; - -- for (sta = hapd->sta_list; sta; sta = sta->next) -- sta_set_airtime_weight(hapd, sta, weight); -+ for (sta = hapd->sta_list; sta; sta = sta->next) { -+ unsigned int sta_weight = weight; -+ -+ if (sta->dyn_airtime_weight) -+ sta_weight = (weight * sta->dyn_airtime_weight) / 256; -+ -+ sta_set_airtime_weight(hapd, sta, sta_weight); -+ } - } - - -@@ -244,7 +250,10 @@ int airtime_policy_new_sta(struct hostap - unsigned int weight; - - if (hapd->iconf->airtime_mode == AIRTIME_MODE_STATIC) { -- weight = get_weight_for_sta(hapd, sta->addr); -+ if (sta->dyn_airtime_weight) -+ weight = sta->dyn_airtime_weight; -+ else -+ weight = get_weight_for_sta(hapd, sta->addr); - if (weight) - return sta_set_airtime_weight(hapd, sta, weight); - } ---- a/src/ap/sta_info.h -+++ b/src/ap/sta_info.h -@@ -322,6 +322,7 @@ struct sta_info { - #endif /* CONFIG_TESTING_OPTIONS */ - #ifdef CONFIG_AIRTIME_POLICY - unsigned int airtime_weight; -+ unsigned int dyn_airtime_weight; - struct os_reltime backlogged_until; - #endif /* CONFIG_AIRTIME_POLICY */ - --- a/src/ap/wnm_ap.c +++ b/src/ap/wnm_ap.c -@@ -455,7 +455,8 @@ static void ieee802_11_rx_bss_trans_mgmt +@@ -479,7 +479,8 @@ static void ieee802_11_rx_bss_trans_mgmt MAC2STR(addr), reason, hex ? " neighbor=" : "", hex); os_free(hex); @@ -570,7 +441,7 @@ } -@@ -477,7 +478,7 @@ static void ieee802_11_rx_bss_trans_mgmt +@@ -501,7 +502,7 @@ static void ieee802_11_rx_bss_trans_mgmt size_t len) { u8 dialog_token, status_code, bss_termination_delay; @@ -579,7 +450,7 @@ int enabled = hapd->conf->bss_transition; struct sta_info *sta; -@@ -524,6 +525,7 @@ static void ieee802_11_rx_bss_trans_mgmt +@@ -548,6 +549,7 @@ static void ieee802_11_rx_bss_trans_mgmt wpa_printf(MSG_DEBUG, "WNM: not enough room for Target BSSID field"); return; } @@ -587,7 +458,7 @@ sta->agreed_to_steer = 1; eloop_cancel_timeout(ap_sta_reset_steer_flag_timer, hapd, sta); eloop_register_timeout(2, 0, ap_sta_reset_steer_flag_timer, -@@ -543,6 +545,10 @@ static void ieee802_11_rx_bss_trans_mgmt +@@ -567,6 +569,10 @@ static void ieee802_11_rx_bss_trans_mgmt MAC2STR(addr), status_code, bss_termination_delay); } @@ -598,6 +469,16 @@ wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries", pos, end - pos); } +--- a/src/ap/wpa_auth_glue.c ++++ b/src/ap/wpa_auth_glue.c +@@ -275,6 +275,7 @@ static void hostapd_wpa_auth_psk_failure + struct hostapd_data *hapd = ctx; + wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POSSIBLE_PSK_MISMATCH MACSTR, + MAC2STR(addr)); ++ hostapd_ubus_notify(hapd, "key-mismatch", addr); + } + + --- a/src/utils/eloop.c +++ b/src/utils/eloop.c @@ -77,6 +77,9 @@ struct eloop_sock_table { @@ -746,3 +627,129 @@ + + eloop_register_cb(uloop_poll_handler, uloop_timeout_poll_handler); +} +--- a/wpa_supplicant/Makefile ++++ b/wpa_supplicant/Makefile +@@ -189,6 +189,13 @@ ifdef CONFIG_EAPOL_TEST + CFLAGS += -Werror -DEAPOL_TEST + endif + ++ifdef CONFIG_UBUS ++CFLAGS += -DUBUS_SUPPORT ++OBJS += ubus.o ++OBJS += ../src/utils/uloop.o ++LIBS += -lubox -lubus ++endif ++ + ifdef CONFIG_CODE_COVERAGE + CFLAGS += -O0 -fprofile-arcs -ftest-coverage -U_FORTIFY_SOURCE + LIBS += -lgcov +@@ -1042,6 +1049,9 @@ ifdef CONFIG_CTRL_IFACE_MIB + CFLAGS += -DCONFIG_CTRL_IFACE_MIB + endif + OBJS += ../src/ap/ctrl_iface_ap.o ++ifdef CONFIG_UBUS ++OBJS += ../src/ap/ubus.o ++endif + endif + + CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY +--- a/wpa_supplicant/main.c ++++ b/wpa_supplicant/main.c +@@ -203,7 +203,7 @@ int main(int argc, char *argv[]) + + for (;;) { + c = getopt(argc, argv, +- "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuv::W"); ++ "b:Bc:C:D:de:f:g:G:hi:I:KLMm:nNo:O:p:P:qsTtuv::W"); + if (c < 0) + break; + switch (c) { +@@ -268,6 +268,9 @@ int main(int argc, char *argv[]) + params.conf_p2p_dev = optarg; + break; + #endif /* CONFIG_P2P */ ++ case 'n': ++ iface_count = 0; ++ break; + case 'o': + params.override_driver = optarg; + break; +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -7716,6 +7716,8 @@ struct wpa_supplicant * wpa_supplicant_a + } + #endif /* CONFIG_P2P */ + ++ wpas_ubus_add_bss(wpa_s); ++ + return wpa_s; + } + +@@ -7742,6 +7744,8 @@ int wpa_supplicant_remove_iface(struct w + struct wpa_supplicant *parent = wpa_s->parent; + #endif /* CONFIG_MESH */ + ++ wpas_ubus_free_bss(wpa_s); ++ + /* Remove interface from the global list of interfaces */ + prev = global->ifaces; + if (prev == wpa_s) { +@@ -8088,8 +8092,12 @@ int wpa_supplicant_run(struct wpa_global + eloop_register_signal_terminate(wpa_supplicant_terminate, global); + eloop_register_signal_reconfig(wpa_supplicant_reconfig, global); + ++ wpas_ubus_add(global); ++ + eloop_run(); + ++ wpas_ubus_free(global); ++ + return 0; + } + +--- a/wpa_supplicant/wpa_supplicant_i.h ++++ b/wpa_supplicant/wpa_supplicant_i.h +@@ -21,6 +21,7 @@ + #include "config_ssid.h" + #include "wmm_ac.h" + #include "pasn/pasn_common.h" ++#include "ubus.h" + + extern const char *const wpa_supplicant_version; + extern const char *const wpa_supplicant_license; +@@ -319,6 +320,8 @@ struct wpa_global { + #endif /* CONFIG_WIFI_DISPLAY */ + + struct psk_list_entry *add_psk; /* From group formation */ ++ ++ struct ubus_object ubus_global; + }; + + +@@ -693,6 +696,7 @@ struct wpa_supplicant { + unsigned char own_addr[ETH_ALEN]; + unsigned char perm_addr[ETH_ALEN]; + char ifname[100]; ++ struct wpas_ubus_bss ubus; + #ifdef CONFIG_MATCH_IFACE + int matched; + #endif /* CONFIG_MATCH_IFACE */ +--- a/wpa_supplicant/wps_supplicant.c ++++ b/wpa_supplicant/wps_supplicant.c +@@ -33,6 +33,7 @@ + #include "p2p/p2p.h" + #include "p2p_supplicant.h" + #include "wps_supplicant.h" ++#include "ubus.h" + + + #ifndef WPS_PIN_SCAN_IGNORE_SEL_REG +@@ -401,6 +402,8 @@ static int wpa_supplicant_wps_cred(void + wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute", + cred->cred_attr, cred->cred_attr_len); + ++ wpas_ubus_notify(wpa_s, cred); ++ + if (wpa_s->conf->wps_cred_processing == 1) + return 0; + diff --git a/package/network/services/hostapd/patches/601-ucode_support.patch b/package/network/services/hostapd/patches/601-ucode_support.patch index 1f2f3d5364a553..b826363248a640 100644 --- a/package/network/services/hostapd/patches/601-ucode_support.patch +++ b/package/network/services/hostapd/patches/601-ucode_support.patch @@ -1,3 +1,11 @@ +From: Felix Fietkau +Date: Fri, 26 May 2023 10:23:59 +0200 +Subject: [PATCH] Add ucode support, use ucode for the main ubus object + +This implements vastly improved dynamic configuration reload support. +It can handle configuration changes on individual wifi interfaces, as well +as adding/removing interfaces. + --- a/hostapd/Makefile +++ b/hostapd/Makefile @@ -168,9 +168,21 @@ OBJS += ../src/eapol_auth/eapol_auth_sm. @@ -24,9 +32,27 @@ endif ifdef CONFIG_CODE_COVERAGE +--- a/hostapd/ctrl_iface.c ++++ b/hostapd/ctrl_iface.c +@@ -5487,6 +5487,7 @@ try_again: + return -1; + } + ++ interface->ctrl_iface_recv = hostapd_ctrl_iface_receive_process; + wpa_msg_register_cb(hostapd_ctrl_iface_msg_cb); + + return 0; +@@ -5588,6 +5589,7 @@ fail: + os_free(fname); + + interface->global_ctrl_sock = s; ++ interface->ctrl_iface_recv = hostapd_ctrl_iface_receive_process; + eloop_register_read_sock(s, hostapd_global_ctrl_iface_receive, + interface, NULL); + --- a/hostapd/main.c +++ b/hostapd/main.c -@@ -1007,6 +1007,7 @@ int main(int argc, char *argv[]) +@@ -1014,6 +1014,7 @@ int main(int argc, char *argv[]) } hostapd_global_ctrl_iface_init(&interfaces); @@ -34,7 +60,7 @@ if (hostapd_global_run(&interfaces, daemonize, pid_file)) { wpa_printf(MSG_ERROR, "Failed to start eloop"); -@@ -1016,6 +1017,7 @@ int main(int argc, char *argv[]) +@@ -1023,6 +1024,7 @@ int main(int argc, char *argv[]) ret = 0; out: @@ -42,55 +68,35 @@ hostapd_global_ctrl_iface_deinit(&interfaces); /* Deinitialize all interfaces */ for (i = 0; i < interfaces.count; i++) { ---- a/src/ap/hostapd.h -+++ b/src/ap/hostapd.h -@@ -19,6 +19,7 @@ - #include "ap_config.h" - #include "drivers/driver.h" - #include "ubus.h" -+#include "ucode.h" +--- a/src/ap/ap_drv_ops.h ++++ b/src/ap/ap_drv_ops.h +@@ -399,6 +399,23 @@ static inline int hostapd_drv_stop_ap(st + return hapd->driver->stop_ap(hapd->drv_priv, link_id); + } - #define OCE_STA_CFON_ENABLED(hapd) \ - ((hapd->conf->oce & OCE_STA_CFON) && \ -@@ -51,6 +52,10 @@ struct hapd_interfaces { - struct hostapd_config * (*config_read_cb)(const char *config_fname); - int (*ctrl_iface_init)(struct hostapd_data *hapd); - void (*ctrl_iface_deinit)(struct hostapd_data *hapd); -+ int (*ctrl_iface_recv)(struct hostapd_data *hapd, -+ char *buf, char *reply, int reply_size, -+ struct sockaddr_storage *from, -+ socklen_t fromlen); - int (*for_each_interface)(struct hapd_interfaces *interfaces, - int (*cb)(struct hostapd_iface *iface, - void *ctx), void *ctx); -@@ -186,6 +191,7 @@ struct hostapd_data { - struct hostapd_config *iconf; - struct hostapd_bss_config *conf; - struct hostapd_ubus_bss ubus; -+ struct hostapd_ucode_bss ucode; - int interface_added; /* virtual interface added for this BSS */ - unsigned int started:1; - unsigned int disabled:1; -@@ -506,6 +512,7 @@ struct hostapd_sta_info { - */ - struct hostapd_iface { - struct hapd_interfaces *interfaces; -+ struct hostapd_ucode_iface ucode; - void *owner; - char *config_fname; - struct hostapd_config *conf; -@@ -706,6 +713,8 @@ struct hostapd_iface * hostapd_init(stru - struct hostapd_iface * - hostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy, - const char *config_fname, int debug); -+int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool start_beacon); -+void hostapd_bss_deinit(struct hostapd_data *hapd); - void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, - int reassoc); - void hostapd_interface_deinit_free(struct hostapd_iface *iface); ++static inline int hostapd_drv_if_rename(struct hostapd_data *hapd, ++ enum wpa_driver_if_type type, ++ const char *ifname, ++ const char *new_name) ++{ ++ if (!hapd->driver || !hapd->driver->if_rename || !hapd->drv_priv) ++ return -1; ++ return hapd->driver->if_rename(hapd->drv_priv, type, ifname, new_name); ++} ++ ++static inline int hostapd_drv_set_first_bss(struct hostapd_data *hapd) ++{ ++ if (!hapd->driver || !hapd->driver->set_first_bss || !hapd->drv_priv) ++ return 0; ++ return hapd->driver->set_first_bss(hapd->drv_priv); ++} ++ + static inline int hostapd_drv_channel_info(struct hostapd_data *hapd, + struct wpa_channel_info *ci) + { --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c -@@ -252,6 +252,8 @@ int hostapd_reload_config(struct hostapd +@@ -255,6 +255,8 @@ int hostapd_reload_config(struct hostapd struct hostapd_config *newconf, *oldconf; size_t j; @@ -99,7 +105,7 @@ if (iface->config_fname == NULL) { /* Only in-memory config in use - assume it has been updated */ hostapd_clear_old(iface); -@@ -435,6 +437,7 @@ void hostapd_free_hapd_data(struct hosta +@@ -493,6 +495,7 @@ void hostapd_free_hapd_data(struct hosta hapd->beacon_set_done = 0; wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); @@ -107,7 +113,7 @@ hostapd_ubus_free_bss(hapd); accounting_deinit(hapd); hostapd_deinit_wpa(hapd); -@@ -600,6 +603,7 @@ void hostapd_cleanup_iface_partial(struc +@@ -687,6 +690,7 @@ void hostapd_cleanup_iface_partial(struc static void hostapd_cleanup_iface(struct hostapd_iface *iface) { wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); @@ -115,7 +121,7 @@ eloop_cancel_timeout(hostapd_interface_setup_failure_handler, iface, NULL); -@@ -1189,6 +1193,7 @@ static int hostapd_start_beacon(struct h +@@ -1276,6 +1280,7 @@ static int hostapd_start_beacon(struct h hapd->driver->set_operstate(hapd->drv_priv, 1); hostapd_ubus_add_bss(hapd); @@ -123,7 +129,7 @@ return 0; } -@@ -1211,8 +1216,7 @@ static int hostapd_start_beacon(struct h +@@ -1298,8 +1303,7 @@ static int hostapd_start_beacon(struct h * initialized. Most of the modules that are initialized here will be * deinitialized in hostapd_cleanup(). */ @@ -133,7 +139,7 @@ { struct hostapd_bss_config *conf = hapd->conf; u8 ssid[SSID_MAX_LEN + 1]; -@@ -2698,7 +2702,7 @@ hostapd_alloc_bss_data(struct hostapd_if +@@ -2790,7 +2794,7 @@ hostapd_alloc_bss_data(struct hostapd_if } @@ -142,7 +148,7 @@ { if (!hapd) return; -@@ -3491,7 +3495,8 @@ int hostapd_remove_iface(struct hapd_int +@@ -3608,7 +3612,8 @@ int hostapd_remove_iface(struct hapd_int hapd_iface = interfaces->iface[i]; if (hapd_iface == NULL) return -1; @@ -152,135 +158,55 @@ wpa_printf(MSG_INFO, "Remove interface '%s'", buf); hapd_iface->driver_ap_teardown = !!(hapd_iface->drv_flags & ---- a/wpa_supplicant/Makefile -+++ b/wpa_supplicant/Makefile -@@ -195,8 +195,20 @@ endif - ifdef CONFIG_UBUS - CFLAGS += -DUBUS_SUPPORT - OBJS += ubus.o -+LIBS += -lubus -+NEED_ULOOP:=y -+endif -+ -+ifdef CONFIG_UCODE -+CFLAGS += -DUCODE_SUPPORT -+OBJS += ../src/utils/ucode.o -+OBJS += ucode.o -+NEED_ULOOP:=y -+endif -+ -+ifdef NEED_ULOOP - OBJS += ../src/utils/uloop.o --LIBS += -lubox -lubus -+LIBS += -lubox - endif - - ifdef CONFIG_CODE_COVERAGE -@@ -997,6 +1009,9 @@ OBJS += ../src/ap/ctrl_iface_ap.o - ifdef CONFIG_UBUS - OBJS += ../src/ap/ubus.o - endif -+ifdef CONFIG_UCODE -+OBJS += ../src/ap/ucode.o -+endif - endif - - CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY ---- a/wpa_supplicant/wpa_supplicant.c -+++ b/wpa_supplicant/wpa_supplicant.c -@@ -1044,6 +1044,7 @@ void wpa_supplicant_set_state(struct wpa - sme_sched_obss_scan(wpa_s, 0); - } - wpa_s->wpa_state = state; -+ wpas_ucode_update_state(wpa_s); - - #ifdef CONFIG_BGSCAN - if (state == WPA_COMPLETED && wpa_s->current_ssid != wpa_s->bgscan_ssid) -@@ -7601,6 +7602,7 @@ struct wpa_supplicant * wpa_supplicant_a - #endif /* CONFIG_P2P */ - - wpas_ubus_add_bss(wpa_s); -+ wpas_ucode_add_bss(wpa_s); - - return wpa_s; - } -@@ -7628,6 +7630,7 @@ int wpa_supplicant_remove_iface(struct w - struct wpa_supplicant *parent = wpa_s->parent; - #endif /* CONFIG_MESH */ - -+ wpas_ucode_free_bss(wpa_s); - wpas_ubus_free_bss(wpa_s); - - /* Remove interface from the global list of interfaces */ -@@ -7938,6 +7941,7 @@ struct wpa_global * wpa_supplicant_init( - - eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0, - wpas_periodic, global, NULL); -+ wpas_ucode_init(global); - - return global; - } -@@ -7976,12 +7980,8 @@ int wpa_supplicant_run(struct wpa_global - eloop_register_signal_terminate(wpa_supplicant_terminate, global); - eloop_register_signal_reconfig(wpa_supplicant_reconfig, global); - -- wpas_ubus_add(global); -- - eloop_run(); - -- wpas_ubus_free(global); -- - return 0; - } - -@@ -8014,6 +8014,8 @@ void wpa_supplicant_deinit(struct wpa_gl - - wpas_notify_supplicant_deinitialized(global); - -+ wpas_ucode_free(); -+ - eap_peer_unregister_methods(); - #ifdef CONFIG_AP - eap_server_unregister_methods(); ---- a/wpa_supplicant/wpa_supplicant_i.h -+++ b/wpa_supplicant/wpa_supplicant_i.h -@@ -22,6 +22,7 @@ - #include "wmm_ac.h" - #include "pasn/pasn_common.h" +--- a/src/ap/hostapd.h ++++ b/src/ap/hostapd.h +@@ -19,6 +19,7 @@ + #include "ap_config.h" + #include "drivers/driver.h" #include "ubus.h" +#include "ucode.h" - extern const char *const wpa_supplicant_version; - extern const char *const wpa_supplicant_license; -@@ -689,6 +690,7 @@ struct wpa_supplicant { - unsigned char perm_addr[ETH_ALEN]; - char ifname[100]; - struct wpas_ubus_bss ubus; -+ struct wpas_ucode_bss ucode; - #ifdef CONFIG_MATCH_IFACE - int matched; - #endif /* CONFIG_MATCH_IFACE */ ---- a/hostapd/ctrl_iface.c -+++ b/hostapd/ctrl_iface.c -@@ -4856,6 +4856,7 @@ try_again: - return -1; - } - -+ interface->ctrl_iface_recv = hostapd_ctrl_iface_receive_process; - wpa_msg_register_cb(hostapd_ctrl_iface_msg_cb); - - return 0; -@@ -4957,6 +4958,7 @@ fail: - os_free(fname); - - interface->global_ctrl_sock = s; -+ interface->ctrl_iface_recv = hostapd_ctrl_iface_receive_process; - eloop_register_read_sock(s, hostapd_global_ctrl_iface_receive, - interface, NULL); - + #define OCE_STA_CFON_ENABLED(hapd) \ + ((hapd->conf->oce & OCE_STA_CFON) && \ +@@ -51,6 +52,10 @@ struct hapd_interfaces { + struct hostapd_config * (*config_read_cb)(const char *config_fname); + int (*ctrl_iface_init)(struct hostapd_data *hapd); + void (*ctrl_iface_deinit)(struct hostapd_data *hapd); ++ int (*ctrl_iface_recv)(struct hostapd_data *hapd, ++ char *buf, char *reply, int reply_size, ++ struct sockaddr_storage *from, ++ socklen_t fromlen); + int (*for_each_interface)(struct hapd_interfaces *interfaces, + int (*cb)(struct hostapd_iface *iface, + void *ctx), void *ctx); +@@ -186,6 +191,7 @@ struct hostapd_data { + struct hostapd_config *iconf; + struct hostapd_bss_config *conf; + struct hostapd_ubus_bss ubus; ++ struct hostapd_ucode_bss ucode; + int interface_added; /* virtual interface added for this BSS */ + unsigned int started:1; + unsigned int disabled:1; +@@ -518,6 +524,7 @@ struct hostapd_sta_info { + */ + struct hostapd_iface { + struct hapd_interfaces *interfaces; ++ struct hostapd_ucode_iface ucode; + void *owner; + char *config_fname; + struct hostapd_config *conf; +@@ -718,6 +725,8 @@ struct hostapd_iface * hostapd_init(stru + struct hostapd_iface * + hostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy, + const char *config_fname, int debug); ++int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool start_beacon); ++void hostapd_bss_deinit(struct hostapd_data *hapd); + void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, + int reassoc); + void hostapd_interface_deinit_free(struct hostapd_iface *iface); --- a/src/drivers/driver.h +++ b/src/drivers/driver.h -@@ -3796,6 +3796,25 @@ struct wpa_driver_ops { +@@ -3856,6 +3856,25 @@ struct wpa_driver_ops { const char *ifname); /** @@ -306,7 +232,7 @@ * set_sta_vlan - Bind a station into a specific interface (AP only) * @priv: Private driver interface data * @ifname: Interface (main or virtual BSS or VLAN) -@@ -6449,6 +6468,7 @@ union wpa_event_data { +@@ -6510,6 +6529,7 @@ union wpa_event_data { /** * struct ch_switch @@ -314,7 +240,7 @@ * @freq: Frequency of new channel in MHz * @ht_enabled: Whether this is an HT channel * @ch_offset: Secondary channel offset -@@ -6459,6 +6479,7 @@ union wpa_event_data { +@@ -6520,6 +6540,7 @@ union wpa_event_data { * @punct_bitmap: Puncturing bitmap */ struct ch_switch { @@ -322,80 +248,9 @@ int freq; int ht_enabled; int ch_offset; ---- a/src/drivers/driver_nl80211_event.c -+++ b/src/drivers/driver_nl80211_event.c -@@ -1203,6 +1203,7 @@ static void mlme_event_ch_switch(struct - struct nlattr *bw, struct nlattr *cf1, - struct nlattr *cf2, - struct nlattr *punct_bitmap, -+ struct nlattr *count, - int finished) - { - struct i802_bss *bss; -@@ -1266,6 +1267,8 @@ static void mlme_event_ch_switch(struct - data.ch_switch.cf1 = nla_get_u32(cf1); - if (cf2) - data.ch_switch.cf2 = nla_get_u32(cf2); -+ if (count) -+ data.ch_switch.count = nla_get_u32(count); - - if (finished) - bss->flink->freq = data.ch_switch.freq; -@@ -3913,6 +3916,7 @@ static void do_process_drv_event(struct - tb[NL80211_ATTR_CENTER_FREQ1], - tb[NL80211_ATTR_CENTER_FREQ2], - tb[NL80211_ATTR_PUNCT_BITMAP], -+ tb[NL80211_ATTR_CH_SWITCH_COUNT], - 0); - break; - case NL80211_CMD_CH_SWITCH_NOTIFY: -@@ -3925,6 +3929,7 @@ static void do_process_drv_event(struct - tb[NL80211_ATTR_CENTER_FREQ1], - tb[NL80211_ATTR_CENTER_FREQ2], - tb[NL80211_ATTR_PUNCT_BITMAP], -+ NULL, - 1); - break; - case NL80211_CMD_DISCONNECT: ---- a/wpa_supplicant/events.c -+++ b/wpa_supplicant/events.c -@@ -5566,6 +5566,7 @@ void supplicant_event(void *ctx, enum wp - event_to_string(event), event); - #endif /* CONFIG_NO_STDOUT_DEBUG */ - -+ wpas_ucode_event(wpa_s, event, data); - switch (event) { - case EVENT_AUTH: - #ifdef CONFIG_FST ---- a/src/ap/ap_drv_ops.h -+++ b/src/ap/ap_drv_ops.h -@@ -393,6 +393,23 @@ static inline int hostapd_drv_stop_ap(st - return hapd->driver->stop_ap(hapd->drv_priv); - } - -+static inline int hostapd_drv_if_rename(struct hostapd_data *hapd, -+ enum wpa_driver_if_type type, -+ const char *ifname, -+ const char *new_name) -+{ -+ if (!hapd->driver || !hapd->driver->if_rename || !hapd->drv_priv) -+ return -1; -+ return hapd->driver->if_rename(hapd->drv_priv, type, ifname, new_name); -+} -+ -+static inline int hostapd_drv_set_first_bss(struct hostapd_data *hapd) -+{ -+ if (!hapd->driver || !hapd->driver->set_first_bss || !hapd->drv_priv) -+ return 0; -+ return hapd->driver->set_first_bss(hapd->drv_priv); -+} -+ - static inline int hostapd_drv_channel_info(struct hostapd_data *hapd, - struct wpa_channel_info *ci) - { --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c -@@ -73,6 +73,16 @@ enum nlmsgerr_attrs { +@@ -75,6 +75,16 @@ enum nlmsgerr_attrs { #endif /* ANDROID */ @@ -412,7 +267,7 @@ static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg) { -@@ -379,6 +389,11 @@ static int no_seq_check(struct nl_msg *m +@@ -429,6 +439,11 @@ static int no_seq_check(struct nl_msg *m return NL_OK; } @@ -424,23 +279,24 @@ static void nl80211_nlmsg_clear(struct nl_msg *msg) { -@@ -415,6 +430,7 @@ static int send_and_recv(struct nl80211_ +@@ -502,6 +517,8 @@ int send_and_recv(struct nl80211_global if (!msg) return -ENOMEM; + handle_nl_debug_hook(msg, 1); - cb = nl_cb_clone(global->nl_cb); - if (!cb) - goto out; -@@ -443,6 +459,7 @@ static int send_and_recv(struct nl80211_ ++ + err.err = -ENOMEM; - err = 1; + s_nl_cb = nl_socket_get_cb(nl_handle); +@@ -536,6 +553,7 @@ int send_and_recv(struct nl80211_global + err.orig_msg = msg; + err.err_info = err_info; + nl_cb_set(cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL); nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); - nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); + nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err.err); if (ack_handler_custom) { -@@ -919,6 +936,7 @@ nl80211_get_wiphy_data_ap(struct i802_bs +@@ -939,6 +957,7 @@ nl80211_get_wiphy_data_ap(struct i802_bs os_free(w); return NULL; } @@ -448,7 +304,7 @@ nl_cb_set(w->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); nl_cb_set(w->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, -@@ -1333,7 +1351,7 @@ static void wpa_driver_nl80211_event_rtm +@@ -1353,7 +1372,7 @@ static void wpa_driver_nl80211_event_rtm } wpa_printf(MSG_DEBUG, "nl80211: Interface down (%s/%s)", namebuf, ifname); @@ -457,7 +313,7 @@ wpa_printf(MSG_DEBUG, "nl80211: Not the main interface (%s) - do not indicate interface down", drv->first_bss->ifname); -@@ -1369,7 +1387,7 @@ static void wpa_driver_nl80211_event_rtm +@@ -1389,7 +1408,7 @@ static void wpa_driver_nl80211_event_rtm } wpa_printf(MSG_DEBUG, "nl80211: Interface up (%s/%s)", namebuf, ifname); @@ -466,15 +322,15 @@ wpa_printf(MSG_DEBUG, "nl80211: Not the main interface (%s) - do not indicate interface up", drv->first_bss->ifname); -@@ -1992,6 +2010,7 @@ static int wpa_driver_nl80211_init_nl_gl - /* Continue without vendor events */ - } +@@ -2035,6 +2054,7 @@ static int wpa_driver_nl80211_init_nl_gl + genl_family_put(family); + nl_cache_free(cache); + nl_cb_set(global->nl_cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL); nl_cb_set(global->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); nl_cb_set(global->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, -@@ -2160,6 +2179,7 @@ static int nl80211_init_bss(struct i802_ +@@ -2205,6 +2225,7 @@ static int nl80211_init_bss(struct i802_ if (!bss->nl_cb) return -1; @@ -482,7 +338,7 @@ nl_cb_set(bss->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); nl_cb_set(bss->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, -@@ -8432,6 +8452,7 @@ static void *i802_init(struct hostapd_da +@@ -8554,6 +8575,7 @@ static void *i802_init(struct hostapd_da char master_ifname[IFNAMSIZ]; int ifindex, br_ifindex = 0; int br_added = 0; @@ -490,7 +346,7 @@ bss = wpa_driver_nl80211_drv_init(hapd, params->ifname, params->global_priv, 1, -@@ -8491,21 +8512,17 @@ static void *i802_init(struct hostapd_da +@@ -8613,21 +8635,17 @@ static void *i802_init(struct hostapd_da (params->num_bridge == 0 || !params->bridge[0])) add_ifidx(drv, br_ifindex, drv->ifindex); @@ -522,7 +378,7 @@ } if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) { -@@ -8875,6 +8892,50 @@ static int wpa_driver_nl80211_if_remove( +@@ -8992,6 +9010,50 @@ static int wpa_driver_nl80211_if_remove( return 0; } @@ -573,7 +429,7 @@ static int cookie_handler(struct nl_msg *msg, void *arg) { -@@ -10513,6 +10574,37 @@ static int driver_nl80211_if_remove(void +@@ -10688,6 +10750,37 @@ static int driver_nl80211_if_remove(void } @@ -611,7 +467,7 @@ static int driver_nl80211_send_mlme(void *priv, const u8 *data, size_t data_len, int noack, unsigned int freq, -@@ -13707,6 +13779,8 @@ const struct wpa_driver_ops wpa_driver_n +@@ -13881,6 +13974,8 @@ const struct wpa_driver_ops wpa_driver_n .set_acl = wpa_driver_nl80211_set_acl, .if_add = wpa_driver_nl80211_if_add, .if_remove = driver_nl80211_if_remove, @@ -620,6 +476,41 @@ .send_mlme = driver_nl80211_send_mlme, .get_hw_feature_data = nl80211_get_hw_feature_data, .sta_add = wpa_driver_nl80211_sta_add, +--- a/src/drivers/driver_nl80211_event.c ++++ b/src/drivers/driver_nl80211_event.c +@@ -1196,6 +1196,7 @@ static void mlme_event_ch_switch(struct + struct nlattr *bw, struct nlattr *cf1, + struct nlattr *cf2, + struct nlattr *punct_bitmap, ++ struct nlattr *count, + int finished) + { + struct i802_bss *bss; +@@ -1259,6 +1260,8 @@ static void mlme_event_ch_switch(struct + data.ch_switch.cf1 = nla_get_u32(cf1); + if (cf2) + data.ch_switch.cf2 = nla_get_u32(cf2); ++ if (count) ++ data.ch_switch.count = nla_get_u32(count); + + if (finished) + bss->flink->freq = data.ch_switch.freq; +@@ -3961,6 +3964,7 @@ static void do_process_drv_event(struct + tb[NL80211_ATTR_CENTER_FREQ1], + tb[NL80211_ATTR_CENTER_FREQ2], + tb[NL80211_ATTR_PUNCT_BITMAP], ++ tb[NL80211_ATTR_CH_SWITCH_COUNT], + 0); + break; + case NL80211_CMD_CH_SWITCH_NOTIFY: +@@ -3973,6 +3977,7 @@ static void do_process_drv_event(struct + tb[NL80211_ATTR_CENTER_FREQ1], + tb[NL80211_ATTR_CENTER_FREQ2], + tb[NL80211_ATTR_PUNCT_BITMAP], ++ NULL, + 1); + break; + case NL80211_CMD_DISCONNECT: --- a/src/utils/wpa_debug.c +++ b/src/utils/wpa_debug.c @@ -26,6 +26,10 @@ static FILE *wpa_debug_tracing_file = NU @@ -669,3 +560,121 @@ extern int wpa_debug_level; extern int wpa_debug_show_keys; extern int wpa_debug_timestamp; +--- a/wpa_supplicant/Makefile ++++ b/wpa_supplicant/Makefile +@@ -192,8 +192,20 @@ endif + ifdef CONFIG_UBUS + CFLAGS += -DUBUS_SUPPORT + OBJS += ubus.o ++LIBS += -lubus ++NEED_ULOOP:=y ++endif ++ ++ifdef CONFIG_UCODE ++CFLAGS += -DUCODE_SUPPORT ++OBJS += ../src/utils/ucode.o ++OBJS += ucode.o ++NEED_ULOOP:=y ++endif ++ ++ifdef NEED_ULOOP + OBJS += ../src/utils/uloop.o +-LIBS += -lubox -lubus ++LIBS += -lubox + endif + + ifdef CONFIG_CODE_COVERAGE +@@ -1052,6 +1064,9 @@ OBJS += ../src/ap/ctrl_iface_ap.o + ifdef CONFIG_UBUS + OBJS += ../src/ap/ubus.o + endif ++ifdef CONFIG_UCODE ++OBJS += ../src/ap/ucode.o ++endif + endif + + CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY +--- a/wpa_supplicant/events.c ++++ b/wpa_supplicant/events.c +@@ -5949,6 +5949,7 @@ void supplicant_event(void *ctx, enum wp + event_to_string(event), event); + #endif /* CONFIG_NO_STDOUT_DEBUG */ + ++ wpas_ucode_event(wpa_s, event, data); + switch (event) { + case EVENT_AUTH: + #ifdef CONFIG_FST +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -1060,6 +1060,7 @@ void wpa_supplicant_set_state(struct wpa + sme_sched_obss_scan(wpa_s, 0); + } + wpa_s->wpa_state = state; ++ wpas_ucode_update_state(wpa_s); + + #ifdef CONFIG_BGSCAN + if (state == WPA_COMPLETED && wpa_s->current_ssid != wpa_s->bgscan_ssid) +@@ -7717,6 +7718,7 @@ struct wpa_supplicant * wpa_supplicant_a + #endif /* CONFIG_P2P */ + + wpas_ubus_add_bss(wpa_s); ++ wpas_ucode_add_bss(wpa_s); + + return wpa_s; + } +@@ -7744,6 +7746,7 @@ int wpa_supplicant_remove_iface(struct w + struct wpa_supplicant *parent = wpa_s->parent; + #endif /* CONFIG_MESH */ + ++ wpas_ucode_free_bss(wpa_s); + wpas_ubus_free_bss(wpa_s); + + /* Remove interface from the global list of interfaces */ +@@ -8054,6 +8057,7 @@ struct wpa_global * wpa_supplicant_init( + + eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0, + wpas_periodic, global, NULL); ++ wpas_ucode_init(global); + + return global; + } +@@ -8092,12 +8096,8 @@ int wpa_supplicant_run(struct wpa_global + eloop_register_signal_terminate(wpa_supplicant_terminate, global); + eloop_register_signal_reconfig(wpa_supplicant_reconfig, global); + +- wpas_ubus_add(global); +- + eloop_run(); + +- wpas_ubus_free(global); +- + return 0; + } + +@@ -8130,6 +8130,8 @@ void wpa_supplicant_deinit(struct wpa_gl + + wpas_notify_supplicant_deinitialized(global); + ++ wpas_ucode_free(); ++ + eap_peer_unregister_methods(); + #ifdef CONFIG_AP + eap_server_unregister_methods(); +--- a/wpa_supplicant/wpa_supplicant_i.h ++++ b/wpa_supplicant/wpa_supplicant_i.h +@@ -22,6 +22,7 @@ + #include "wmm_ac.h" + #include "pasn/pasn_common.h" + #include "ubus.h" ++#include "ucode.h" + + extern const char *const wpa_supplicant_version; + extern const char *const wpa_supplicant_license; +@@ -697,6 +698,7 @@ struct wpa_supplicant { + unsigned char perm_addr[ETH_ALEN]; + char ifname[100]; + struct wpas_ubus_bss ubus; ++ struct wpas_ucode_bss ucode; + #ifdef CONFIG_MATCH_IFACE + int matched; + #endif /* CONFIG_MATCH_IFACE */ diff --git a/package/network/services/hostapd/patches/610-hostapd_cli_ujail_permission.patch b/package/network/services/hostapd/patches/610-hostapd_cli_ujail_permission.patch index a03fcc9f92be6a..30f675573a324a 100644 --- a/package/network/services/hostapd/patches/610-hostapd_cli_ujail_permission.patch +++ b/package/network/services/hostapd/patches/610-hostapd_cli_ujail_permission.patch @@ -1,3 +1,43 @@ +From: Mark Mentovai +Date: Tue, 23 Nov 2021 12:28:55 -0500 +Subject: [PATCH] hostapd: allow hostapd under ujail to communicate with + hostapd_cli + +When procd-ujail is available, 1f78538 runs hostapd as user +"network", with only limited additional capabilities (CAP_NET_ADMIN and +CAP_NET_RAW). + +hostapd_cli (CONFIG_PACKAGE_hostapd-utils) communicates with hostapd +over a named UNIX-domain socket. hostapd_cli is responsible for creating +this socket at /tmp/wpa_ctrl_$pid_$counter. Since it typically runs as +root, this endpoint is normally created with uid root, gid root, mode +0755. As a result, hostapd running as uid network is able to receive +control messages sent through this interface, but is not able to respond +to them. If debug-level logging is enabled (CONFIG_WPA_MSG_MIN_PRIORITY +<= 2 at build, and log_level <= 2 in /etc/config/wireless wifi-device), +this message will appear from hostapd: + +CTRL: sendto failed: Permission denied + +As a fix, hostapd_cli should create the socket node in the filesystem +with uid network, gid network, mode 0770. This borrows the presently +Android-only strategy already in hostapd intended to solve the same +problem on Android. + +If procd-ujail is not available and hostapd falls back to running as +root, it will still be able to read from and write to the socket even if +the node in the filesystem has been restricted to the network user and +group. This matches the logic in +package/network/services/hostapd/files/wpad.init, which sets the uid and +gid of /var/run/hostapd to network regardless of whether procd-ujail is +available. + +As it appears that the "network" user and group are statically allocated +uid 101 and gid 101, respectively, per +package/base-files/files/etc/passwd and USERID in +package/network/services/hostapd/Makefile, this patch also uses a +constant 101 for the uid and gid. + --- a/src/common/wpa_ctrl.c +++ b/src/common/wpa_ctrl.c @@ -135,7 +135,7 @@ try_again: diff --git a/package/network/services/hostapd/patches/701-reload_config_inline.patch b/package/network/services/hostapd/patches/701-reload_config_inline.patch index e654f2f433194a..260e832ddba7a3 100644 --- a/package/network/services/hostapd/patches/701-reload_config_inline.patch +++ b/package/network/services/hostapd/patches/701-reload_config_inline.patch @@ -1,6 +1,14 @@ +From: Felix Fietkau +Date: Fri, 26 May 2023 10:23:59 +0200 +Subject: [PATCH] Add ucode support, use ucode for the main ubus object #2 + +This implements vastly improved dynamic configuration reload support. +It can handle configuration changes on individual wifi interfaces, as well +as adding/removing interfaces. + --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -4818,7 +4818,12 @@ struct hostapd_config * hostapd_config_r +@@ -5065,7 +5065,12 @@ struct hostapd_config * hostapd_config_r int errors = 0; size_t i; diff --git a/package/network/services/hostapd/patches/710-vlan_no_bridge.patch b/package/network/services/hostapd/patches/710-vlan_no_bridge.patch index f625f4bda4b46b..d3f797ed35abf6 100644 --- a/package/network/services/hostapd/patches/710-vlan_no_bridge.patch +++ b/package/network/services/hostapd/patches/710-vlan_no_bridge.patch @@ -1,3 +1,22 @@ +From: Felix Fietkau +Date: Tue, 18 May 2021 12:50:17 +0200 +Subject: [PATCH] hostapd: add patch for disabling automatic bridging of vlan + interfaces + +netifd is responsible for handling that, except if the vlan bridge +was provided by the config + +--- a/hostapd/config_file.c ++++ b/hostapd/config_file.c +@@ -3559,6 +3559,8 @@ static int hostapd_config_fill(struct ho + #ifndef CONFIG_NO_VLAN + } else if (os_strcmp(buf, "dynamic_vlan") == 0) { + bss->ssid.dynamic_vlan = atoi(pos); ++ } else if (os_strcmp(buf, "vlan_no_bridge") == 0) { ++ bss->ssid.vlan_no_bridge = atoi(pos); + } else if (os_strcmp(buf, "per_sta_vif") == 0) { + bss->ssid.per_sta_vif = atoi(pos); + } else if (os_strcmp(buf, "vlan_file") == 0) { --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -121,6 +121,7 @@ struct hostapd_ssid { @@ -28,14 +47,3 @@ ifconfig_up(ifname); } ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -3353,6 +3353,8 @@ static int hostapd_config_fill(struct ho - #ifndef CONFIG_NO_VLAN - } else if (os_strcmp(buf, "dynamic_vlan") == 0) { - bss->ssid.dynamic_vlan = atoi(pos); -+ } else if (os_strcmp(buf, "vlan_no_bridge") == 0) { -+ bss->ssid.vlan_no_bridge = atoi(pos); - } else if (os_strcmp(buf, "per_sta_vif") == 0) { - bss->ssid.per_sta_vif = atoi(pos); - } else if (os_strcmp(buf, "vlan_file") == 0) { diff --git a/package/network/services/hostapd/patches/711-wds_bridge_force.patch b/package/network/services/hostapd/patches/711-wds_bridge_force.patch index c0f2c31c4482a0..dbd75658ae4a94 100644 --- a/package/network/services/hostapd/patches/711-wds_bridge_force.patch +++ b/package/network/services/hostapd/patches/711-wds_bridge_force.patch @@ -1,6 +1,17 @@ +From: Felix Fietkau +Date: Wed, 20 Oct 2021 21:13:10 +0200 +Subject: [PATCH] hostpad: fix a race condition on adding AP mode wds sta + interfaces + +Both hostapd and netifd attempt to add a VLAN device to a bridge. +Depending on which one wins the race, bridge vlan settings might be incomplete, +or hostapd might run into an error and refuse to service the client. +Fix this by preventing hostapd from adding interfaces to the bridge and +instead rely entirely on netifd handling this properly + --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -2318,6 +2318,8 @@ static int hostapd_config_fill(struct ho +@@ -2447,6 +2447,8 @@ static int hostapd_config_fill(struct ho sizeof(conf->bss[0]->iface)); } else if (os_strcmp(buf, "bridge") == 0) { os_strlcpy(bss->bridge, pos, sizeof(bss->bridge)); @@ -11,7 +22,7 @@ } else if (os_strcmp(buf, "vlan_bridge") == 0) { --- a/src/ap/ap_drv_ops.c +++ b/src/ap/ap_drv_ops.c -@@ -348,8 +348,6 @@ int hostapd_set_wds_sta(struct hostapd_d +@@ -387,8 +387,6 @@ int hostapd_set_wds_sta(struct hostapd_d return -1; if (hapd->conf->wds_bridge[0]) bridge = hapd->conf->wds_bridge; diff --git a/package/network/services/hostapd/patches/720-iface_max_num_sta.patch b/package/network/services/hostapd/patches/720-iface_max_num_sta.patch index 598f8dfe7b39bb..fb00313f3d9198 100644 --- a/package/network/services/hostapd/patches/720-iface_max_num_sta.patch +++ b/package/network/services/hostapd/patches/720-iface_max_num_sta.patch @@ -1,6 +1,14 @@ +From: Felix Fietkau +Date: Wed, 26 May 2021 14:34:46 +0200 +Subject: [PATCH] hostapd: add support for specifying the maxassoc parameter as + a device option + +It allows enforcing a limit on associated stations to be enforced for the +full device, e.g. in order to deal with hardware/driver limitations + --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -2850,6 +2850,14 @@ static int hostapd_config_fill(struct ho +@@ -3041,6 +3041,14 @@ static int hostapd_config_fill(struct ho line, bss->max_num_sta, MAX_STA_COUNT); return 1; } @@ -15,19 +23,31 @@ } else if (os_strcmp(buf, "wpa") == 0) { bss->wpa = atoi(pos); } else if (os_strcmp(buf, "extended_key_id") == 0) { ---- a/src/ap/hostapd.h -+++ b/src/ap/hostapd.h -@@ -742,6 +742,7 @@ void hostapd_cleanup_cs_params(struct ho - void hostapd_periodic_iface(struct hostapd_iface *iface); - int hostapd_owe_trans_get_info(struct hostapd_data *hapd); - void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx); -+int hostapd_check_max_sta(struct hostapd_data *hapd); +--- a/src/ap/ap_config.h ++++ b/src/ap/ap_config.h +@@ -1057,6 +1057,8 @@ struct hostapd_config { + unsigned int track_sta_max_num; + unsigned int track_sta_max_age; - void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap); - void hostapd_cleanup_cca_params(struct hostapd_data *hapd); ++ int max_num_sta; ++ + char country[3]; /* first two octets: country code as described in + * ISO/IEC 3166-1. Third octet: + * ' ' (ascii 32): all environments +--- a/src/ap/beacon.c ++++ b/src/ap/beacon.c +@@ -1567,7 +1567,7 @@ void handle_probe_req(struct hostapd_dat + if (hapd->conf->no_probe_resp_if_max_sta && + is_multicast_ether_addr(mgmt->da) && + is_multicast_ether_addr(mgmt->bssid) && +- hapd->num_sta >= hapd->conf->max_num_sta && ++ hostapd_check_max_sta(hapd) && + !ap_get_sta(hapd, mgmt->sa)) { + wpa_printf(MSG_MSGDUMP, "%s: Ignore Probe Request from " MACSTR + " since no room for additional STA", --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c -@@ -244,6 +244,29 @@ static int hostapd_iface_conf_changed(st +@@ -247,6 +247,29 @@ static int hostapd_iface_conf_changed(st return 0; } @@ -57,25 +77,13 @@ int hostapd_reload_config(struct hostapd_iface *iface) { ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -1261,7 +1261,7 @@ void handle_probe_req(struct hostapd_dat - if (hapd->conf->no_probe_resp_if_max_sta && - is_multicast_ether_addr(mgmt->da) && - is_multicast_ether_addr(mgmt->bssid) && -- hapd->num_sta >= hapd->conf->max_num_sta && -+ hostapd_check_max_sta(hapd) && - !ap_get_sta(hapd, mgmt->sa)) { - wpa_printf(MSG_MSGDUMP, "%s: Ignore Probe Request from " MACSTR - " since no room for additional STA", ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -1040,6 +1040,8 @@ struct hostapd_config { - unsigned int track_sta_max_num; - unsigned int track_sta_max_age; +--- a/src/ap/hostapd.h ++++ b/src/ap/hostapd.h +@@ -754,6 +754,7 @@ void hostapd_cleanup_cs_params(struct ho + void hostapd_periodic_iface(struct hostapd_iface *iface); + int hostapd_owe_trans_get_info(struct hostapd_data *hapd); + void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx); ++int hostapd_check_max_sta(struct hostapd_data *hapd); -+ int max_num_sta; -+ - char country[3]; /* first two octets: country code as described in - * ISO/IEC 3166-1. Third octet: - * ' ' (ascii 32): all environments + void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap); + void hostapd_cleanup_cca_params(struct hostapd_data *hapd); diff --git a/package/network/services/hostapd/patches/730-ft_iface.patch b/package/network/services/hostapd/patches/730-ft_iface.patch index 348005162d6ecd..2f47f17d969574 100644 --- a/package/network/services/hostapd/patches/730-ft_iface.patch +++ b/package/network/services/hostapd/patches/730-ft_iface.patch @@ -1,6 +1,14 @@ +From: Felix Fietkau +Date: Fri, 4 Jun 2021 09:12:07 +0200 +Subject: [PATCH] hostapd: configure inter-AP communication interface for + 802.11r + +In setups using VLAN bridge filtering, hostapd may need to communicate using +a VLAN interface on top of the bridge, instead of using the bridge directly + --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -3009,6 +3009,8 @@ static int hostapd_config_fill(struct ho +@@ -3200,6 +3200,8 @@ static int hostapd_config_fill(struct ho wpa_printf(MSG_INFO, "Line %d: Obsolete peerkey parameter ignored", line); #ifdef CONFIG_IEEE80211R_AP @@ -21,7 +29,7 @@ int bridge_hairpin; /* hairpin_mode on bridge members */ --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c -@@ -1736,8 +1736,12 @@ int hostapd_setup_wpa(struct hostapd_dat +@@ -1777,8 +1777,12 @@ int hostapd_setup_wpa(struct hostapd_dat wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt)) { const char *ft_iface; diff --git a/package/network/services/hostapd/patches/740-snoop_iface.patch b/package/network/services/hostapd/patches/740-snoop_iface.patch index add46d3ebc08fe..f4b3ac33b10369 100644 --- a/package/network/services/hostapd/patches/740-snoop_iface.patch +++ b/package/network/services/hostapd/patches/740-snoop_iface.patch @@ -1,3 +1,22 @@ +From: Felix Fietkau +Date: Tue, 27 Jul 2021 20:28:58 +0200 +Subject: [PATCH] hostapd: make the snooping interface (for proxyarp) + configurable + +Use the VLAN interface instead of the bridge, to ensure that hostapd receives +untagged DHCP packets + +--- a/hostapd/config_file.c ++++ b/hostapd/config_file.c +@@ -2451,6 +2451,8 @@ static int hostapd_config_fill(struct ho + os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge)); + } else if (os_strcmp(buf, "bridge_hairpin") == 0) { + bss->bridge_hairpin = atoi(pos); ++ } else if (os_strcmp(buf, "snoop_iface") == 0) { ++ os_strlcpy(bss->snoop_iface, pos, sizeof(bss->snoop_iface)); + } else if (os_strcmp(buf, "vlan_bridge") == 0) { + os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge)); + } else if (os_strcmp(buf, "wds_bridge") == 0) { --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -284,6 +284,7 @@ struct hostapd_bss_config { @@ -8,6 +27,23 @@ char vlan_bridge[IFNAMSIZ + 1]; char wds_bridge[IFNAMSIZ + 1]; int bridge_hairpin; /* hairpin_mode on bridge members */ +--- a/src/ap/ap_drv_ops.h ++++ b/src/ap/ap_drv_ops.h +@@ -366,12 +366,12 @@ static inline int hostapd_drv_br_port_se + + static inline int hostapd_drv_br_set_net_param(struct hostapd_data *hapd, + enum drv_br_net_param param, +- unsigned int val) ++ const char *ifname, unsigned int val) + { + if (hapd->driver == NULL || hapd->drv_priv == NULL || + hapd->driver->br_set_net_param == NULL) + return -1; +- return hapd->driver->br_set_net_param(hapd->drv_priv, param, val); ++ return hapd->driver->br_set_net_param(hapd->drv_priv, param, ifname, val); + } + + static inline int hostapd_drv_vendor_cmd(struct hostapd_data *hapd, --- a/src/ap/x_snoop.c +++ b/src/ap/x_snoop.c @@ -33,28 +33,31 @@ int x_snoop_init(struct hostapd_data *ha @@ -74,37 +110,9 @@ hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 0); hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE, 0); hapd->x_snoop_initialized = false; ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -2322,6 +2322,8 @@ static int hostapd_config_fill(struct ho - os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge)); - } else if (os_strcmp(buf, "bridge_hairpin") == 0) { - bss->bridge_hairpin = atoi(pos); -+ } else if (os_strcmp(buf, "snoop_iface") == 0) { -+ os_strlcpy(bss->snoop_iface, pos, sizeof(bss->snoop_iface)); - } else if (os_strcmp(buf, "vlan_bridge") == 0) { - os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge)); - } else if (os_strcmp(buf, "wds_bridge") == 0) { ---- a/src/ap/ap_drv_ops.h -+++ b/src/ap/ap_drv_ops.h -@@ -366,12 +366,12 @@ static inline int hostapd_drv_br_port_se - - static inline int hostapd_drv_br_set_net_param(struct hostapd_data *hapd, - enum drv_br_net_param param, -- unsigned int val) -+ const char *ifname, unsigned int val) - { - if (hapd->driver == NULL || hapd->drv_priv == NULL || - hapd->driver->br_set_net_param == NULL) - return -1; -- return hapd->driver->br_set_net_param(hapd->drv_priv, param, val); -+ return hapd->driver->br_set_net_param(hapd->drv_priv, param, ifname, val); - } - - static inline int hostapd_drv_vendor_cmd(struct hostapd_data *hapd, --- a/src/drivers/driver.h +++ b/src/drivers/driver.h -@@ -4218,7 +4218,7 @@ struct wpa_driver_ops { +@@ -4278,7 +4278,7 @@ struct wpa_driver_ops { * Returns: 0 on success, negative (<0) on failure */ int (*br_set_net_param)(void *priv, enum drv_br_net_param param, @@ -115,7 +123,7 @@ * get_wowlan - Get wake-on-wireless status --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c -@@ -12178,7 +12178,7 @@ static const char * drv_br_net_param_str +@@ -12376,7 +12376,7 @@ static const char * drv_br_net_param_str static int wpa_driver_br_set_net_param(void *priv, enum drv_br_net_param param, @@ -124,7 +132,7 @@ { struct i802_bss *bss = priv; char path[128]; -@@ -12204,8 +12204,11 @@ static int wpa_driver_br_set_net_param(v +@@ -12402,8 +12402,11 @@ static int wpa_driver_br_set_net_param(v return -EINVAL; } diff --git a/package/network/services/hostapd/patches/751-qos_map_ignore_when_unsupported.patch b/package/network/services/hostapd/patches/751-qos_map_ignore_when_unsupported.patch index f5ebab70d1db36..86394d78a4db5d 100644 --- a/package/network/services/hostapd/patches/751-qos_map_ignore_when_unsupported.patch +++ b/package/network/services/hostapd/patches/751-qos_map_ignore_when_unsupported.patch @@ -1,6 +1,13 @@ +From: Felix Fietkau +Date: Thu, 23 Dec 2021 19:18:33 +0100 +Subject: [PATCH] hostapd: only attempt to set qos map if supported by the + driver + +Fixes issues with brcmfmac + --- a/src/ap/ap_drv_ops.c +++ b/src/ap/ap_drv_ops.c -@@ -927,7 +927,8 @@ int hostapd_start_dfs_cac(struct hostapd +@@ -998,7 +998,8 @@ int hostapd_start_dfs_cac(struct hostapd int hostapd_drv_set_qos_map(struct hostapd_data *hapd, const u8 *qos_map_set, u8 qos_map_set_len) { diff --git a/package/network/services/hostapd/patches/760-dynamic_own_ip.patch b/package/network/services/hostapd/patches/760-dynamic_own_ip.patch index 946b4533bf241a..c4b14d41b00942 100644 --- a/package/network/services/hostapd/patches/760-dynamic_own_ip.patch +++ b/package/network/services/hostapd/patches/760-dynamic_own_ip.patch @@ -1,3 +1,21 @@ +From: Felix Fietkau +Date: Thu, 15 Dec 2022 13:57:04 +0100 +Subject: [PATCH] hostapd: add support for automatically setting RADIUS own-ip + dynamically + +Some servers use the NAS-IP-Address attribute as a destination address + +--- a/hostapd/config_file.c ++++ b/hostapd/config_file.c +@@ -2819,6 +2819,8 @@ static int hostapd_config_fill(struct ho + } else if (os_strcmp(buf, "iapp_interface") == 0) { + wpa_printf(MSG_INFO, "DEPRECATED: iapp_interface not used"); + #endif /* CONFIG_IAPP */ ++ } else if (os_strcmp(buf, "dynamic_own_ip_addr") == 0) { ++ bss->dynamic_own_ip_addr = atoi(pos); + } else if (os_strcmp(buf, "own_ip_addr") == 0) { + if (hostapd_parse_ip_addr(pos, &bss->own_ip_addr)) { + wpa_printf(MSG_ERROR, --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -310,6 +310,7 @@ struct hostapd_bss_config { @@ -8,9 +26,22 @@ char *nas_identifier; struct hostapd_radius_servers *radius; int acct_interim_interval; +--- a/src/ap/ieee802_1x.c ++++ b/src/ap/ieee802_1x.c +@@ -601,6 +601,10 @@ int add_common_radius_attr(struct hostap + struct hostapd_radius_attr *attr; + int len; + ++ if (hapd->conf->dynamic_own_ip_addr) ++ radius_client_get_local_addr(hapd->radius, ++ &hapd->conf->own_ip_addr); ++ + if (!hostapd_config_get_radius_attr(req_attr, + RADIUS_ATTR_NAS_IP_ADDRESS) && + hapd->conf->own_ip_addr.af == AF_INET && --- a/src/radius/radius_client.c +++ b/src/radius/radius_client.c -@@ -163,6 +163,8 @@ struct radius_client_data { +@@ -165,6 +165,8 @@ struct radius_client_data { */ void *ctx; @@ -19,7 +50,7 @@ /** * conf - RADIUS client configuration (list of RADIUS servers to use) */ -@@ -720,6 +722,30 @@ static void radius_client_list_add(struc +@@ -819,6 +821,30 @@ static void radius_close_acct_socket(str /** @@ -50,7 +81,7 @@ * radius_client_send - Send a RADIUS request * @radius: RADIUS client context from radius_client_init() * @msg: RADIUS message to be sent -@@ -1238,6 +1264,10 @@ radius_change_server(struct radius_clien +@@ -1711,6 +1737,10 @@ radius_change_server(struct radius_clien wpa_printf(MSG_DEBUG, "RADIUS local address: %s:%u", inet_ntoa(claddr.sin_addr), ntohs(claddr.sin_port)); @@ -61,7 +92,7 @@ } break; #ifdef CONFIG_IPV6 -@@ -1249,6 +1279,10 @@ radius_change_server(struct radius_clien +@@ -1722,6 +1752,10 @@ radius_change_server(struct radius_clien inet_ntop(AF_INET6, &claddr6.sin6_addr, abuf, sizeof(abuf)), ntohs(claddr6.sin6_port)); @@ -74,7 +105,7 @@ } --- a/src/radius/radius_client.h +++ b/src/radius/radius_client.h -@@ -249,6 +249,8 @@ int radius_client_register(struct radius +@@ -274,6 +274,8 @@ int radius_client_register(struct radius void radius_client_set_interim_error_cb(struct radius_client_data *radius, void (*cb)(const u8 *addr, void *ctx), void *ctx); @@ -83,27 +114,3 @@ int radius_client_send(struct radius_client_data *radius, struct radius_msg *msg, RadiusType msg_type, const u8 *addr); ---- a/src/ap/ieee802_1x.c -+++ b/src/ap/ieee802_1x.c -@@ -598,6 +598,10 @@ int add_common_radius_attr(struct hostap - struct hostapd_radius_attr *attr; - int len; - -+ if (hapd->conf->dynamic_own_ip_addr) -+ radius_client_get_local_addr(hapd->radius, -+ &hapd->conf->own_ip_addr); -+ - if (!hostapd_config_get_radius_attr(req_attr, - RADIUS_ATTR_NAS_IP_ADDRESS) && - hapd->conf->own_ip_addr.af == AF_INET && ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -2690,6 +2690,8 @@ static int hostapd_config_fill(struct ho - } else if (os_strcmp(buf, "iapp_interface") == 0) { - wpa_printf(MSG_INFO, "DEPRECATED: iapp_interface not used"); - #endif /* CONFIG_IAPP */ -+ } else if (os_strcmp(buf, "dynamic_own_ip_addr") == 0) { -+ bss->dynamic_own_ip_addr = atoi(pos); - } else if (os_strcmp(buf, "own_ip_addr") == 0) { - if (hostapd_parse_ip_addr(pos, &bss->own_ip_addr)) { - wpa_printf(MSG_ERROR, diff --git a/package/network/services/hostapd/patches/761-shared_das_port.patch b/package/network/services/hostapd/patches/761-shared_das_port.patch index cbb2a1be3c4718..5ca10d23bdb664 100644 --- a/package/network/services/hostapd/patches/761-shared_das_port.patch +++ b/package/network/services/hostapd/patches/761-shared_das_port.patch @@ -1,16 +1,13 @@ ---- a/src/radius/radius_das.h -+++ b/src/radius/radius_das.h -@@ -44,6 +44,7 @@ struct radius_das_attrs { - struct radius_das_conf { - int port; - const u8 *shared_secret; -+ const u8 *nas_identifier; - size_t shared_secret_len; - const struct hostapd_ip_addr *client_addr; - unsigned int time_window; +From: Felix Fietkau +Date: Fri, 16 Dec 2022 13:32:48 +0100 +Subject: [PATCH] hostapd: allow sharing the incoming DAS port across multiple + interfaces + +Use the NAS identifier to find the right receiver context on incoming messages + --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c -@@ -1423,6 +1423,7 @@ int hostapd_setup_bss(struct hostapd_dat +@@ -1510,6 +1510,7 @@ int hostapd_setup_bss(struct hostapd_dat os_memset(&das_conf, 0, sizeof(das_conf)); das_conf.port = conf->radius_das_port; @@ -296,3 +293,13 @@ os_free(das->shared_secret); os_free(das); } +--- a/src/radius/radius_das.h ++++ b/src/radius/radius_das.h +@@ -44,6 +44,7 @@ struct radius_das_attrs { + struct radius_das_conf { + int port; + const u8 *shared_secret; ++ const u8 *nas_identifier; + size_t shared_secret_len; + const struct hostapd_ip_addr *client_addr; + unsigned int time_window; diff --git a/package/network/services/hostapd/patches/770-radius_server.patch b/package/network/services/hostapd/patches/770-radius_server.patch index 8837a26257b3d9..73b2c8643ba2c7 100644 --- a/package/network/services/hostapd/patches/770-radius_server.patch +++ b/package/network/services/hostapd/patches/770-radius_server.patch @@ -1,3 +1,11 @@ +From: Felix Fietkau +Date: Thu, 16 Mar 2023 11:35:50 +0100 +Subject: [PATCH] hostapd: add experimental radius server + +This can be used to run a standalone EAP server that can be used from +other APs. It uses json as user database format and can automatically +handle reload. + --- a/hostapd/Makefile +++ b/hostapd/Makefile @@ -63,6 +63,10 @@ endif @@ -21,7 +29,7 @@ #ifndef CONFIG_NO_HOSTAPD_LOGGER static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module, -@@ -771,6 +772,11 @@ int main(int argc, char *argv[]) +@@ -778,6 +779,11 @@ int main(int argc, char *argv[]) if (os_program_init()) return -1; From 4209022699fe4f72ac88bab61c68c75dcc08ba36 Mon Sep 17 00:00:00 2001 From: Sean Khan Date: Mon, 29 Apr 2024 21:50:56 -0400 Subject: [PATCH 179/225] qualcommax: qca-mcs support for kernel >= 6.6.29 Signed-off-by: Sean Khan --- .../0604-1-qca-add-mcs-support.patch | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/target/linux/qualcommax/patches-6.6/0604-1-qca-add-mcs-support.patch b/target/linux/qualcommax/patches-6.6/0604-1-qca-add-mcs-support.patch index edf21700c3e94c..4b87366d84966a 100644 --- a/target/linux/qualcommax/patches-6.6/0604-1-qca-add-mcs-support.patch +++ b/target/linux/qualcommax/patches-6.6/0604-1-qca-add-mcs-support.patch @@ -39,15 +39,15 @@ * added to the bridge private HW address list and all required ports --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h -@@ -906,6 +906,7 @@ void br_manage_promisc(struct net_bridge +@@ -907,6 +907,7 @@ void br_manage_promisc(struct net_bridge int nbp_backup_change(struct net_bridge_port *p, struct net_device *backup_dev); /* br_input.c */ -+int br_pass_frame_up(struct sk_buff *skb); /* QCA qca-mcs support */ ++int br_pass_frame_up(struct sk_buff *skb, bool promisc); /* QCA qca-mcs support */ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb); rx_handler_func_t *br_get_rx_handler(const struct net_device *dev); -@@ -2268,4 +2269,14 @@ struct nd_msg *br_is_nd_neigh_msg(struct +@@ -2269,4 +2270,14 @@ struct nd_msg *br_is_nd_neigh_msg(struct bool br_is_neigh_suppress_enabled(const struct net_bridge_port *p, u16 vid); #define __br_get(__hook, __default, __args ...) \ (__hook ? (__hook(__args)) : (__default)) /* QCA NSS ECM support */ @@ -109,7 +109,7 @@ return netif_receive_skb(skb); } --static int br_pass_frame_up(struct sk_buff *skb) +-static int br_pass_frame_up(struct sk_buff *skb, bool promisc) +/* QCA qca-mcs support - Start */ +/* Hook for external Multicast handler */ +br_multicast_handle_hook_t __rcu *br_multicast_handle_hook __read_mostly; @@ -120,11 +120,11 @@ +EXPORT_SYMBOL_GPL(br_get_dst_hook); +/* QCA qca-mcs support - End */ + -+int br_pass_frame_up(struct sk_buff *skb) ++int br_pass_frame_up(struct sk_buff *skb, bool promisc) { struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev; struct net_bridge *br = netdev_priv(brdev); -@@ -69,6 +79,7 @@ static int br_pass_frame_up(struct sk_bu +@@ -71,6 +81,7 @@ static int br_pass_frame_up(struct sk_bu dev_net(indev), NULL, skb, indev, NULL, br_netif_receive_skb); } @@ -132,7 +132,7 @@ /* note: already called with rcu_read_lock */ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb) -@@ -82,6 +93,11 @@ int br_handle_frame_finish(struct net *n +@@ -84,6 +95,11 @@ int br_handle_frame_finish(struct net *n struct net_bridge_mcast *brmctx; struct net_bridge_vlan *vlan; struct net_bridge *br; @@ -141,10 +141,10 @@ + struct net_bridge_port *pdst = NULL; + br_get_dst_hook_t *get_dst_hook = rcu_dereference(br_get_dst_hook); + /* QCA qca-mcs support - End */ + bool promisc; u16 vid = 0; u8 state; - -@@ -175,6 +191,12 @@ int br_handle_frame_finish(struct net *n +@@ -180,6 +196,12 @@ int br_handle_frame_finish(struct net *n switch (pkt_type) { case BR_PKT_MULTICAST: @@ -157,7 +157,7 @@ mdst = br_mdb_get(brmctx, skb, vid); if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) && br_multicast_querier_exists(brmctx, eth_hdr(skb), mdst)) { -@@ -190,8 +212,15 @@ int br_handle_frame_finish(struct net *n +@@ -195,8 +217,15 @@ int br_handle_frame_finish(struct net *n } break; case BR_PKT_UNICAST: @@ -175,7 +175,7 @@ default: break; } -@@ -206,6 +235,13 @@ int br_handle_frame_finish(struct net *n +@@ -211,6 +240,13 @@ int br_handle_frame_finish(struct net *n dst->used = now; br_forward(dst->dst, skb, local_rcv, false); } else { From edb7711692b92a39aba86943d8cf9acdc1cbed9c Mon Sep 17 00:00:00 2001 From: Sean Khan Date: Sun, 5 May 2024 04:43:41 -0400 Subject: [PATCH 180/225] kernel: qca-ssdk: update to 12.5 for kernel 6.6 Qualcomm recently committed a new branch (12.5.r2) targeting kernel 6.6. This lets us clean up a few patches particularly the one for "C22/C45" mdio. A quick way to see what changed for IPQ807x/6018 was to list the files produced during build (**/*.o), replace the extension with ".c", and doing a `git log`. Filtering from those commits, ones of particular interest are listed below: ``` 2024-04-16 - 0d8f30aa - fix compile issue on hk with linux style build 2024-01-29 - 636464f7 - update the check for port link notify 2024-01-24 - 30c10e7f - enable and disable loopback for xgmac to fix qm stuck issue 2024-01-15 - b6ea10aa - update the the APIs to access switch 2024-01-08 - a1687502 - Disable Tx bridge mac before power off the PHY 2024-01-07 - 3eafb613 - support led configure for malibu phy 2024-01-07 - 5c1af60d - remove phy type check from mac reset when mode switch 2023-12-17 - 79d0b1e8 - remove the PHY access APIs in ssdk_plat.c 2023-12-16 - b2953740 - Update mii read/write functions 2023-12-11 - 37f2eac3 - add port id check for fdb entry 2023-12-11 - d040ca4d - support mdio clause45 on kernel6.6 2023-12-07 - 11494fbc - use barrier mw() during access fdb entry table 2023-12-03 - 8e40a284 - fix build warnings on kernel6.6 2023-11-10 - 10aa0a02 - change speed value when call ssdk_port_link_notify 2023-11-06 - ee4c4a60 - Update mac bitmap value of L3 table on MAC delete 2023-11-03 - 7cd27d39 - support 10G phy common feature 2023-10-30 - 383cc0d2 - fix mactype and mux select issue 2023-10-24 - decf534a - support autoneg status query on force port 2023-10-11 - 111d574e - move ssdk_led_init to regi_init 2023-10-08 - 6b14c142 - the combo port also need to parse SFP pins 2023-10-03 - fb2e0401 - fix port5 interface mode switch issue in erp case ``` Verified with users on QNAP 301W, NBG7815, and myself on Dynalink DL-WRX36 that everything is functional, including LEDS. Signed-off-by: Sean Khan --- package/kernel/qca-ssdk/Makefile | 8 +- .../0001-config-identify-kernel-6.6.patch | 47 --------- ...-selecting-PCS-channel-for-PORT3-on-.patch | 20 ++-- ...dapt-to-C22-and-C45-read-write-split.patch | 98 ------------------- .../patches/201-fix-compile-warnings.patch | 19 +--- 5 files changed, 16 insertions(+), 176 deletions(-) delete mode 100644 package/kernel/qca-ssdk/patches/0001-config-identify-kernel-6.6.patch delete mode 100644 package/kernel/qca-ssdk/patches/103-mdio-adapt-to-C22-and-C45-read-write-split.patch diff --git a/package/kernel/qca-ssdk/Makefile b/package/kernel/qca-ssdk/Makefile index bbe9f120514627..ed18f17504dbef 100644 --- a/package/kernel/qca-ssdk/Makefile +++ b/package/kernel/qca-ssdk/Makefile @@ -1,13 +1,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=qca-ssdk -PKG_RELEASE:=6 +PKG_RELEASE:=1 PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/qca-ssdk.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2023-10-04 -PKG_SOURCE_VERSION:=23a5aa4a4d5834da7a07efb58baebfbee91786b0 -PKG_MIRROR_HASH:=53fb201053b3aca004c4da07b06a0608b0b3322a2062b1f7ab3b3a7871ddabcb +PKG_SOURCE_DATE:=2024-04-17 +PKG_SOURCE_VERSION:=3d060f7ad70d087f6b0452abe79ab6d042e8cd53 +PKG_MIRROR_HASH:=6f5e390b294e699491584094f5d7eb941de6237ad8c5320191e9e306fbcd8eb5 PKG_FLAGS:=nonshared PKG_BUILD_PARALLEL:=1 diff --git a/package/kernel/qca-ssdk/patches/0001-config-identify-kernel-6.6.patch b/package/kernel/qca-ssdk/patches/0001-config-identify-kernel-6.6.patch deleted file mode 100644 index 2dc092326306b3..00000000000000 --- a/package/kernel/qca-ssdk/patches/0001-config-identify-kernel-6.6.patch +++ /dev/null @@ -1,47 +0,0 @@ -From f6c0115daaac586740e873a3b8145c5370a73dce Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Sat, 17 Feb 2024 13:02:31 +0100 -Subject: [PATCH] config: identify kernel 6.6 - -Identify kernel 6.6 so it can be compiled against. - -Signed-off-by: Robert Marko ---- - config | 5 +++++ - make/linux_opt.mk | 4 ++-- - 2 files changed, 7 insertions(+), 2 deletions(-) - ---- a/config -+++ b/config -@@ -27,6 +27,11 @@ endif - ifeq ($(KVER),$(filter 6.1%,$(KVER))) - OS_VER=6_1 - endif -+ -+ifeq ($(KVER),$(filter 6.6%,$(KVER))) -+ OS_VER=6_6 -+endif -+ - ifeq ($(KVER), 3.4.0) - OS_VER=3_4 - endif ---- a/make/linux_opt.mk -+++ b/make/linux_opt.mk -@@ -450,7 +450,7 @@ ifeq (KSLIB, $(MODULE_TYPE)) - KASAN_SHADOW_SCALE_SHIFT := 3 - endif - -- ifeq ($(OS_VER),$(filter 5_4 6_1, $(OS_VER))) -+ ifeq ($(OS_VER),$(filter 5_4 6_1 6_6, $(OS_VER))) - ifeq ($(ARCH), arm64) - KASAN_OPTION += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT) - endif -@@ -481,7 +481,7 @@ ifeq (KSLIB, $(MODULE_TYPE)) - - endif - -- ifeq ($(OS_VER),$(filter 4_4 5_4 6_1, $(OS_VER))) -+ ifeq ($(OS_VER),$(filter 4_4 5_4 6_1 6_6, $(OS_VER))) - MODULE_CFLAG += -DKVER34 - MODULE_CFLAG += -DKVER32 - MODULE_CFLAG += -DLNX26_22 diff --git a/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch b/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch index 5e390d8ee339c0..fc4e6e0bad1cb8 100644 --- a/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch +++ b/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch @@ -24,15 +24,15 @@ Signed-off-by: Mantas Pucka --- a/include/init/ssdk_dts.h +++ b/include/init/ssdk_dts.h -@@ -101,6 +101,7 @@ typedef struct +@@ -99,6 +99,7 @@ typedef struct a_uint32_t emu_chip_ver; /*only valid when is_emulation is true*/ a_uint32_t clk_mode; a_uint32_t pcie_hw_base; + a_uint32_t port3_pcs_channel; + led_ctrl_pattern_t source_pattern[SSDK_MAX_PORT_NUM][PORT_LED_SOURCE_MAX]; } ssdk_dt_cfg; - #define SSDK_MAX_NR_ETH 6 -@@ -162,6 +163,7 @@ a_uint32_t ssdk_device_id_get(a_uint32_t +@@ -161,6 +162,7 @@ a_uint32_t ssdk_device_id_get(a_uint32_t struct device_node *ssdk_dts_node_get(a_uint32_t dev_id); struct clk *ssdk_dts_essclk_get(a_uint32_t dev_id); struct clk *ssdk_dts_cmnclk_get(a_uint32_t dev_id); @@ -62,7 +62,7 @@ Signed-off-by: Mantas Pucka cppe_port_mux_ctrl.bf.port4_pcs_sel = --- a/src/adpt/hppe/adpt_hppe_uniphy.c +++ b/src/adpt/hppe/adpt_hppe_uniphy.c -@@ -1122,9 +1122,6 @@ __adpt_hppe_uniphy_psgmii_mode_set(a_uin +@@ -1160,9 +1160,6 @@ __adpt_hppe_uniphy_psgmii_mode_set(a_uin { a_uint32_t i; sw_error_t rv = SW_OK; @@ -72,7 +72,7 @@ Signed-off-by: Mantas Pucka union uniphy_mode_ctrl_u uniphy_mode_ctrl; -@@ -1134,9 +1131,7 @@ __adpt_hppe_uniphy_psgmii_mode_set(a_uin +@@ -1172,9 +1169,7 @@ __adpt_hppe_uniphy_psgmii_mode_set(a_uin SSDK_DEBUG("uniphy %d is psgmii mode\n", uniphy_index); #if defined(CPPE) if (adpt_ppe_type_get(dev_id) == CPPE_TYPE) { @@ -92,14 +92,14 @@ Signed-off-by: Mantas Pucka +a_uint32_t ssdk_dts_port3_pcs_channel_get(a_uint32_t dev_id) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; -+ ++ + return cfg->port3_pcs_channel; +} + - #ifndef BOARD_AR71XX #if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) static void ssdk_dt_parse_mac_mode(a_uint32_t dev_id, -@@ -306,6 +313,25 @@ static void ssdk_dt_parse_mac_mode(a_uin + struct device_node *switch_node, ssdk_init_cfg *cfg) +@@ -305,6 +312,25 @@ static void ssdk_dt_parse_mac_mode(a_uin return; } @@ -109,7 +109,7 @@ Signed-off-by: Mantas Pucka +{ + const __be32 *port3_pcs_channel; + a_uint32_t len = 0; -+ ++ + port3_pcs_channel = of_get_property(switch_node, "port3_pcs_channel", &len); + if (!port3_pcs_channel) { + ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->port3_pcs_channel = 2; @@ -125,7 +125,7 @@ Signed-off-by: Mantas Pucka #ifdef IN_UNIPHY static void ssdk_dt_parse_uniphy(a_uint32_t dev_id) { -@@ -1292,6 +1318,7 @@ sw_error_t ssdk_dt_parse(ssdk_init_cfg * +@@ -1347,6 +1373,7 @@ sw_error_t ssdk_dt_parse(ssdk_init_cfg * rv = ssdk_dt_parse_access_mode(switch_node, ssdk_dt_priv); SW_RTN_ON_ERROR(rv); ssdk_dt_parse_mac_mode(*dev_id, switch_node, cfg); diff --git a/package/kernel/qca-ssdk/patches/103-mdio-adapt-to-C22-and-C45-read-write-split.patch b/package/kernel/qca-ssdk/patches/103-mdio-adapt-to-C22-and-C45-read-write-split.patch deleted file mode 100644 index 7ddca554ecbd50..00000000000000 --- a/package/kernel/qca-ssdk/patches/103-mdio-adapt-to-C22-and-C45-read-write-split.patch +++ /dev/null @@ -1,98 +0,0 @@ -From bdae481e89cbe551068a99028bb57119b59f5ff4 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Tue, 26 Mar 2024 12:19:49 +0100 -Subject: [PATCH] mdio: adapt to C22 and C45 read/write split - -Kernel 6.3 has introduced separate C45 read/write operations, and thus -split them out of the C22 operations completely so the old way of marking -C45 reads and writes via the register value does not work anymore. - -This is causing SSDK to fail and find C45 only PHY-s such as Aquantia ones: -[ 22.187877] ssdk_phy_driver_init[371]:INFO:dev_id = 0, phy_adress = 8, phy_id = 0x0 phytype doesn't match -[ 22.209924] ssdk_phy_driver_init[371]:INFO:dev_id = 0, phy_adress = 0, phy_id = 0x0 phytype doesn't match - -This in turn causes USXGMII MAC autoneg bit to not get set and then UNIPHY -autoneg will time out, causing the 10G ports not to work: -[ 37.292784] uniphy autoneg time out! - -So, lets detect C45 reads and writes by the magic BIT(30) in the register -argument and if so call separate C45 mdiobus read/write functions. - -Signed-off-by: Robert Marko ---- - include/init/ssdk_plat.h | 7 +++++++ - src/init/ssdk_plat.c | 30 ++++++++++++++++++++++++++++++ - 2 files changed, 37 insertions(+) - ---- a/include/init/ssdk_plat.h -+++ b/include/init/ssdk_plat.h -@@ -505,3 +505,10 @@ void ssdk_plat_exit(a_uint32_t dev_id); - - #endif - /*qca808x_end*/ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,3,0)) -+#define MII_ADDR_C45 (1<<30) -+#define MII_DEVADDR_C45_SHIFT 16 -+#define MII_DEVADDR_C45_MASK GENMASK(20, 16) -+#define MII_REGADDR_C45_MASK GENMASK(15, 0) -+#endif ---- a/src/init/ssdk_plat.c -+++ b/src/init/ssdk_plat.c -@@ -356,6 +356,18 @@ phy_addr_validation_check(a_uint32_t phy - return A_TRUE; - } - -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,3,0)) -+static inline u16 mdiobus_c45_regad(u32 regnum) -+{ -+ return FIELD_GET(MII_REGADDR_C45_MASK, regnum); -+} -+ -+static inline u16 mdiobus_c45_devad(u32 regnum) -+{ -+ return FIELD_GET(MII_DEVADDR_C45_MASK, regnum); -+} -+#endif -+ - sw_error_t - qca_ar8327_phy_read(a_uint32_t dev_id, a_uint32_t phy_addr, - a_uint32_t reg, a_uint16_t* data) -@@ -371,9 +383,18 @@ qca_ar8327_phy_read(a_uint32_t dev_id, a - if (!bus) - return SW_NOT_SUPPORTED; - phy_addr = TO_PHY_ADDR(phy_addr); -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,3,0)) -+ mutex_lock(&bus->mdio_lock); -+ if (reg & MII_ADDR_C45) -+ *data = __mdiobus_c45_read(bus, phy_addr, mdiobus_c45_devad(reg), mdiobus_c45_regad(reg)); -+ else -+ *data = __mdiobus_read(bus, phy_addr, reg); -+ mutex_unlock(&bus->mdio_lock); -+#else - mutex_lock(&bus->mdio_lock); - *data = __mdiobus_read(bus, phy_addr, reg); - mutex_unlock(&bus->mdio_lock); -+#endif - - return 0; - } -@@ -393,9 +414,18 @@ qca_ar8327_phy_write(a_uint32_t dev_id, - if (!bus) - return SW_NOT_SUPPORTED; - phy_addr = TO_PHY_ADDR(phy_addr); -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,3,0)) -+ mutex_lock(&bus->mdio_lock); -+ if (reg & MII_ADDR_C45) -+ __mdiobus_c45_write(bus, phy_addr, mdiobus_c45_devad(reg), mdiobus_c45_regad(reg), data); -+ else -+ __mdiobus_write(bus, phy_addr, reg, data); -+ mutex_unlock(&bus->mdio_lock); -+#else - mutex_lock(&bus->mdio_lock); - __mdiobus_write(bus, phy_addr, reg, data); - mutex_unlock(&bus->mdio_lock); -+#endif - - return 0; - } diff --git a/package/kernel/qca-ssdk/patches/201-fix-compile-warnings.patch b/package/kernel/qca-ssdk/patches/201-fix-compile-warnings.patch index 48807888fb008a..4161a61ba3e670 100644 --- a/package/kernel/qca-ssdk/patches/201-fix-compile-warnings.patch +++ b/package/kernel/qca-ssdk/patches/201-fix-compile-warnings.patch @@ -1,17 +1,3 @@ ---- a/src/adpt/adpt.c -+++ b/src/adpt/adpt.c -@@ -394,11 +394,6 @@ sw_error_t adpt_init(a_uint32_t dev_id, - #endif - #endif - #if defined(HPPE) --#if defined(FALLTHROUGH) -- fallthrough; --#else -- /* fall through */ --#endif - case CHIP_HPPE: - if (g_adpt_api[dev_id] == NULL) { - g_adpt_api[dev_id] = aos_mem_alloc(sizeof(adpt_api_t)); --- a/src/fal/fal_port_ctrl.c +++ b/src/fal/fal_port_ctrl.c @@ -2089,7 +2089,7 @@ fal_port_hibernate_get (a_uint32_t dev_i @@ -22,7 +8,7 @@ + fal_cable_status_t * cable_status, a_uint32_t * cable_len) { sw_error_t rv; - + --- a/src/fal/fal_portvlan.c +++ b/src/fal/fal_portvlan.c @@ -2173,7 +2173,7 @@ fal_netisolate_get(a_uint32_t dev_id, a_ @@ -33,7 +19,7 @@ +fal_eg_trans_filter_bypass_en_set(a_uint32_t dev_id, a_uint32_t enable) { sw_error_t rv; - + @@ -2190,7 +2190,7 @@ fal_eg_trans_filter_bypass_en_set(a_uint * @return SW_OK or error code */ @@ -42,4 +28,3 @@ +fal_eg_trans_filter_bypass_en_get(a_uint32_t dev_id, a_uint32_t* enable) { sw_error_t rv; - From 1346f145636e7721e503f53bee628ce8ac716205 Mon Sep 17 00:00:00 2001 From: Sean Khan Date: Sun, 5 May 2024 00:59:15 -0400 Subject: [PATCH 181/225] feeds: nss-packages: switch to branch 12.5-6.x --- feeds.conf.default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feeds.conf.default b/feeds.conf.default index 68c55d271c0819..5e40f047d6b5f4 100644 --- a/feeds.conf.default +++ b/feeds.conf.default @@ -2,7 +2,7 @@ src-git packages https://git.openwrt.org/feed/packages.git src-git luci https://git.openwrt.org/project/luci.git src-git routing https://git.openwrt.org/feed/routing.git src-git telephony https://git.openwrt.org/feed/telephony.git -src-git nss_packages https://github.com/qosmio/nss-packages.git;NSS-12.4-K6.x +src-git nss_packages https://github.com/qosmio/nss-packages.git;NSS-12.5-K6.x src-git sqm_scripts_nss https://github.com/qosmio/sqm-scripts-nss.git #src-git video https://github.com/openwrt/video.git #src-git targets https://github.com/openwrt/targets.git From 489fcafd0e0f27dd8fe105912aa1cb43a6e5b241 Mon Sep 17 00:00:00 2001 From: Sean Khan Date: Sun, 5 May 2024 01:02:03 -0400 Subject: [PATCH 182/225] ath11k_nss: fix invalid access to memory In ath11k_dp_rx_msdu_coalesce(), rxcb is fetched from skb and bool is_continuation is part of rxcb. Currently, after freeing the skb, the rxcb->is_continuation accessed again which is wrong since the memory is already freed. Hence fix the issue by locally defining bool is_continuation from rxcb, so that after freeing skb also we can use is_continuation. Signed-off-by: Sean Khan --- ...-ath11k-fix-invalid-access-to-memory.patch | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/909-wifi-ath11k-fix-invalid-access-to-memory.patch diff --git a/package/kernel/mac80211/patches/nss/ath11k/909-wifi-ath11k-fix-invalid-access-to-memory.patch b/package/kernel/mac80211/patches/nss/ath11k/909-wifi-ath11k-fix-invalid-access-to-memory.patch new file mode 100644 index 00000000000000..cafff3137e6ba1 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/909-wifi-ath11k-fix-invalid-access-to-memory.patch @@ -0,0 +1,51 @@ +From cea94c73e068ce4e015327bf251f782545d8e365 Mon Sep 17 00:00:00 2001 +From: Sarika Sharma +Date: Mon, 29 Jan 2024 16:01:23 +0530 +Subject: [PATCH] wifi: ath11k: fix invalid access to memory + +In ath11k_dp_rx_msdu_coalesce(), rxcb is fetched from skb and bool +is_continuation is part of rxcb. +Currently, after freeing the skb, the rxcb->is_continuation accessed +again which is wrong since the memory is already freed. + +Hence fix the issue by locally defining bool is_continuation from rxcb, +so that after freeing skb also we can use is_continuation. + +Signed-off-by: Sarika Sharma +--- + drivers/net/wireless/ath/ath11k/dp_rx.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c +index de71bc7..2c88986 100644 +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -2278,6 +2278,7 @@ static int ath11k_dp_rx_msdu_coalesce(struct ath11k *ar, + struct hal_rx_desc *ldesc; + int space_extra, rem_len, buf_len; + u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; ++ bool is_continuation; + + /* As the msdu is spread across multiple rx buffers, + * find the offset to the start of msdu for computing +@@ -2326,7 +2327,8 @@ static int ath11k_dp_rx_msdu_coalesce(struct ath11k *ar, + rem_len = msdu_len - buf_first_len; + while ((skb = __skb_dequeue(msdu_list)) != NULL && rem_len > 0) { + rxcb = ATH11K_SKB_RXCB(skb); +- if (rxcb->is_continuation) ++ is_continuation = rxcb->is_continuation; ++ if (is_continuation) + buf_len = DP_RX_BUFFER_SIZE - hal_rx_desc_sz; + else + buf_len = rem_len; +@@ -2344,7 +2346,7 @@ static int ath11k_dp_rx_msdu_coalesce(struct ath11k *ar, + dev_kfree_skb_any(skb); + + rem_len -= buf_len; +- if (!rxcb->is_continuation) ++ if (!is_continuation) + break; + } + +-- +2.34.1 From d67934b717a3b9c2cbf3109e317da708aca02bc6 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 19 Jul 2022 19:52:34 +0300 Subject: [PATCH 183/225] feeds: use forked bitthief/nss-packages Signed-off-by: bitthief --- feeds.conf.default | 1 + 1 file changed, 1 insertion(+) diff --git a/feeds.conf.default b/feeds.conf.default index fc679335e0e47f..e0bad42753507c 100644 --- a/feeds.conf.default +++ b/feeds.conf.default @@ -2,6 +2,7 @@ src-git packages https://git.openwrt.org/feed/packages.git src-git luci https://git.openwrt.org/project/luci.git src-git routing https://git.openwrt.org/feed/routing.git src-git telephony https://git.openwrt.org/feed/telephony.git +src-git nss_packages https://github.com/bitthief/nss-packages.git #src-git video https://github.com/openwrt/video.git #src-git targets https://github.com/openwrt/targets.git #src-git oldpackages http://git.openwrt.org/packages.git From 5ef5f3d563a62edb27734f7a28a8bf3de92543f7 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 01:51:06 +0300 Subject: [PATCH 184/225] qualcommax: crypto, ktls, netfilter, misc. Signed-off-by: bitthief Co-Developed-by: Sean Khan --- .../linux/qualcommax/ipq807x/config-default | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/target/linux/qualcommax/ipq807x/config-default b/target/linux/qualcommax/ipq807x/config-default index 18483d05b449a2..68a750e6edb4ac 100644 --- a/target/linux/qualcommax/ipq807x/config-default +++ b/target/linux/qualcommax/ipq807x/config-default @@ -1,9 +1,92 @@ CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y +CONFIG_ARM_QCOM_CPUFREQ_HW=y +CONFIG_ASN1=y +CONFIG_ASN1_ENCODER=y +CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_ASYMMETRIC_KEY_TYPE=y +# CONFIG_ASYMMETRIC_TPM_KEY_SUBTYPE is not set +CONFIG_AT803X_PHY=y +CONFIG_BPFILTER=y +CONFIG_BPFILTER_UMH=m +CONFIG_CLZ_TAB=y +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set +CONFIG_CRYPTO_AES_ARM64=y +CONFIG_CRYPTO_AES_ARM64_BS=y +CONFIG_CRYPTO_AES_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y +CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=y +CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=y +CONFIG_CRYPTO_BLAKE2B=y +CONFIG_CRYPTO_BLAKE2S=y +CONFIG_CRYPTO_CFB=y +CONFIG_CRYPTO_CHACHA20=y +CONFIG_CRYPTO_CHACHA20POLY1305=y +CONFIG_CRYPTO_CHACHA20_NEON=y +CONFIG_CRYPTO_CMAC=y +CONFIG_CRYPTO_CRCT10DIF=y +CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=y +CONFIG_CRYPTO_CRYPTD=y +CONFIG_CRYPTO_CURVE25519=y +CONFIG_CRYPTO_DH=y +CONFIG_CRYPTO_DH_RFC7919_GROUPS=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_ECC=y +CONFIG_CRYPTO_ECDH=y +CONFIG_CRYPTO_ECDSA=y +CONFIG_CRYPTO_ECRDSA=y +CONFIG_CRYPTO_GF128MUL=y +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_KEYWRAP=y +CONFIG_CRYPTO_LIB_CHACHA_GENERIC=y +CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=y +CONFIG_CRYPTO_LIB_POLY1305_GENERIC=y +CONFIG_CRYPTO_LIB_SM4=y +CONFIG_CRYPTO_LRW=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_NULL2=y +CONFIG_CRYPTO_NHPOLY1305_NEON=y +CONFIG_CRYPTO_OFB=y +CONFIG_CRYPTO_POLY1305=y +CONFIG_CRYPTO_POLY1305_NEON=y +CONFIG_CRYPTO_POLYVAL_ARM64_CE=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_RSA=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +CONFIG_CRYPTO_SHA256_ARM64=y +CONFIG_CRYPTO_SHA3=y +CONFIG_CRYPTO_SHA3_ARM64=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_SHA512_ARM64=y +CONFIG_CRYPTO_SHA512_ARM64_CE=y +CONFIG_CRYPTO_SIMD=y +CONFIG_CRYPTO_SM2=y +CONFIG_CRYPTO_SM3=y +CONFIG_CRYPTO_SM3_ARM64_CE=y +CONFIG_CRYPTO_SM3_NEON=y +CONFIG_CRYPTO_SM4_ARM64_CE=y +CONFIG_CRYPTO_SM4_ARM64_CE_BLK=y +CONFIG_CRYPTO_SM4_ARM64_NEON_BLK=y +CONFIG_CRYPTO_STREEBOG=y +CONFIG_CRYPTO_XXHASH=y CONFIG_DT_IDLE_GENPD=y +CONFIG_IP6_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_MASQUERADE=y CONFIG_IPQ_GCC_8074=y # CONFIG_MFD_HI6421_SPMI is not set CONFIG_MFD_SPMI_PMIC=y +CONFIG_MPILIB=y # CONFIG_NVMEM_SPMI_SDAM is not set +CONFIG_OID_REGISTRY=y CONFIG_PINCTRL_IPQ8074=y CONFIG_PINCTRL_QCOM_SPMI_PMIC=y # CONFIG_PM8916_WATCHDOG is not set @@ -13,9 +96,14 @@ CONFIG_PM_GENERIC_DOMAINS_OF=y CONFIG_QCOM_APM=y # CONFIG_QCOM_COINCELL is not set CONFIG_QCOM_GDSC=y +# CONFIG_QCOM_IPA is not set +CONFIG_QCOM_QFPROM=y +# CONFIG_QCOM_QMI_HELPERS is not set CONFIG_QCOM_SPMI_ADC5=y # CONFIG_QCOM_SPMI_RRADC is not set CONFIG_QCOM_VADC_COMMON=y +CONFIG_QCOM_WCNSS_CTRL=y +CONFIG_QCOM_WCNSS_PIL=y CONFIG_REGMAP_SPMI=y CONFIG_REGULATOR_CPR3=y # CONFIG_REGULATOR_CPR3_NPU is not set @@ -23,8 +111,16 @@ CONFIG_REGULATOR_CPR4_APSS=y # CONFIG_REGULATOR_QCOM_LABIBB is not set CONFIG_REGULATOR_QCOM_SPMI=y # CONFIG_REGULATOR_QCOM_USB_VBUS is not set +CONFIG_RESET_QCOM_AOSS=y +CONFIG_RESET_QCOM_PDC=y CONFIG_RTC_DRV_PM8XXX=y +# CONFIG_SCHED_CLUSTER is not set +CONFIG_SCHED_CORE=y CONFIG_SPMI=y # CONFIG_SPMI_HISI3670 is not set CONFIG_SPMI_MSM_PMIC_ARB=y # CONFIG_SPMI_PMIC_CLKDIV is not set +CONFIG_TLS=y +CONFIG_TLS_DEVICE=y +# CONFIG_TLS_TOE is not set +CONFIG_XOR_BLOCKS=y From d18ab410d0fb5a8c0201b46aa6679bc085f53cbb Mon Sep 17 00:00:00 2001 From: bitthief Date: Sat, 4 Feb 2023 01:30:08 +0200 Subject: [PATCH 185/225] nat46: patches for QCA NSS ECM Signed-off-by: bitthief package: kernel: nat46: add kernel 6.1 support Signed-off-by: bitthief Co-Developed-by: Sean Khan --- package/kernel/nat46/Makefile | 10 +- .../kernel/nat46/patches/101-skb-reset.patch | 30 + package/kernel/nat46/patches/102-mapt.patch | 209 ++++++ package/kernel/nat46/patches/103-tos.patch | 39 ++ package/kernel/nat46/patches/104-icmp.patch | 439 ++++++++++++ .../patches/105-longest-prefix-match.patch | 640 ++++++++++++++++++ .../nat46/patches/106-dummy_header.patch | 104 +++ package/kernel/nat46/patches/107-stats.patch | 136 ++++ .../kernel/nat46/patches/108-ce_port.patch | 134 ++++ ...agment_if_not_df_and_larger_than_mtu.patch | 30 + .../patches/110-icmp_error_not_handled.patch | 100 +++ .../111-fix_null_point_reference.patch | 40 ++ .../nat46/patches/112-fix_icmp_crash.patch | 40 ++ .../patches/116-rate-limit-the-print.patch | 34 + .../patches/117-fix-icmp-no-payload-bug.patch | 34 + .../nat46/patches/118-performance_fix.patch | 415 ++++++++++++ .../patches/120-sleeping_backtrace.patch | 57 ++ .../kernel/nat46/patches/121-tos-fix.patch | 27 + 18 files changed, 2517 insertions(+), 1 deletion(-) create mode 100644 package/kernel/nat46/patches/101-skb-reset.patch create mode 100644 package/kernel/nat46/patches/102-mapt.patch create mode 100644 package/kernel/nat46/patches/103-tos.patch create mode 100644 package/kernel/nat46/patches/104-icmp.patch create mode 100644 package/kernel/nat46/patches/105-longest-prefix-match.patch create mode 100644 package/kernel/nat46/patches/106-dummy_header.patch create mode 100644 package/kernel/nat46/patches/107-stats.patch create mode 100644 package/kernel/nat46/patches/108-ce_port.patch create mode 100644 package/kernel/nat46/patches/109-fragment_if_not_df_and_larger_than_mtu.patch create mode 100644 package/kernel/nat46/patches/110-icmp_error_not_handled.patch create mode 100644 package/kernel/nat46/patches/111-fix_null_point_reference.patch create mode 100644 package/kernel/nat46/patches/112-fix_icmp_crash.patch create mode 100644 package/kernel/nat46/patches/116-rate-limit-the-print.patch create mode 100644 package/kernel/nat46/patches/117-fix-icmp-no-payload-bug.patch create mode 100644 package/kernel/nat46/patches/118-performance_fix.patch create mode 100644 package/kernel/nat46/patches/120-sleeping_backtrace.patch create mode 100644 package/kernel/nat46/patches/121-tos-fix.patch diff --git a/package/kernel/nat46/Makefile b/package/kernel/nat46/Makefile index 296ef5a058e83e..32ea3a4516d4e0 100644 --- a/package/kernel/nat46/Makefile +++ b/package/kernel/nat46/Makefile @@ -12,6 +12,8 @@ PKG_SOURCE_VERSION:=4c5beee236841724219598fabb1edc93d4f08ce5 PKG_MAINTAINER:=Hans Dedecker PKG_LICENSE:=GPL-2.0 +PKG_BUILD_PARALLEL:=1 + include $(INCLUDE_DIR)/package.mk define KernelPackage/nat46 @@ -25,11 +27,17 @@ endef include $(INCLUDE_DIR)/kernel-defaults.mk +define Build/InstallDev + mkdir -p -m 0777 $(STAGING_DIR)/usr/include/nat46 + $(CP) $(PKG_BUILD_DIR)/nat46/modules/*.h $(STAGING_DIR)/usr/include/nat46/ +endef + define Build/Compile - $(KERNEL_MAKE) M="$(PKG_BUILD_DIR)/nat46/modules" \ + +$(KERNEL_MAKE) M="$(PKG_BUILD_DIR)/nat46/modules" \ MODFLAGS="-DMODULE -mlong-calls" \ EXTRA_CFLAGS="-DNAT46_VERSION=\\\"$(PKG_SOURCE_VERSION)\\\"" \ modules + cp $(PKG_BUILD_DIR)/nat46/modules/Module.symvers $(PKG_BUILD_DIR)/Module.symvers endef $(eval $(call KernelPackage,nat46)) diff --git a/package/kernel/nat46/patches/101-skb-reset.patch b/package/kernel/nat46/patches/101-skb-reset.patch new file mode 100644 index 00000000000000..14cf2d75a07d88 --- /dev/null +++ b/package/kernel/nat46/patches/101-skb-reset.patch @@ -0,0 +1,30 @@ +Author: Pavithra R +Date: Sun Sep 20 13:33:42 2020 +0530 + +nat46: Add skb_ext_reset to reset skb extensions + +This patch adds support to reset the skb extensions before +resetting the netfilter. Without the change, conntrack +is in invalid state and traffic gets dropped. + +Change-Id: I24ee6fe8a9a9dec09d61d8e716fff587f65e4e4f +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -1710,6 +1710,7 @@ int nat46_ipv6_input(struct sk_buff *old + #if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) + nf_reset(new_skb); + #else ++ skb_ext_reset(new_skb); + nf_reset_ct(new_skb); + #endif + +@@ -1936,6 +1937,7 @@ int nat46_ipv4_input(struct sk_buff *old + #if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) + nf_reset(new_skb); + #else ++ skb_ext_reset(new_skb); + nf_reset_ct(new_skb); + #endif + diff --git a/package/kernel/nat46/patches/102-mapt.patch b/package/kernel/nat46/patches/102-mapt.patch new file mode 100644 index 00000000000000..1e83481c967f8b --- /dev/null +++ b/package/kernel/nat46/patches/102-mapt.patch @@ -0,0 +1,209 @@ +Author: Pavithra R +Date: Sat Aug 1 13:27:20 2020 +0530 + +nat46: Export APIs for acceleration engine support in nat46 for kernel 5.4 + +This patch is propagated from kernel 4.4 commit +861e64a607fd22d5af089cf56539f42a2e31d581 + +The patch defines and exports APIs in nat46 to be used for accelaration. + +Change-Id: I7934b15544953f870d3595b8b359433b4fff7c30 +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -1497,7 +1497,6 @@ static uint16_t nat46_fixup_icmp_dest_un + return 0; + } + +- + /* Fixup ICMP->ICMP6 before IP header translation, according to http://tools.ietf.org/html/rfc6145 */ + + static uint16_t nat46_fixup_icmp(nat46_instance_t *nat46, struct iphdr *iph, struct sk_buff *old_skb) { +@@ -1579,6 +1578,10 @@ int pairs_xlate_v6_to_v4_outer(nat46_ins + return ( (xlate_src >= 0) && (xlate_dst >= 0) ); + } + ++int xlate_6_to_4(struct net_device *dev, struct ipv6hdr *ip6h, uint16_t proto, __u32 *pv4saddr, __u32 *pv4daddr) { ++ return pairs_xlate_v6_to_v4_outer(netdev_nat46_instance(dev), ip6h, proto, pv4saddr, pv4daddr); ++} ++EXPORT_SYMBOL(xlate_6_to_4); + + int nat46_ipv6_input(struct sk_buff *old_skb) { + struct ipv6hdr *ip6h = ipv6_hdr(old_skb); +@@ -1733,6 +1736,10 @@ int nat46_ipv6_input(struct sk_buff *old + + nat46debug(5, "about to send v4 packet, flags: %02x", IPCB(new_skb)->flags); + nat46_netdev_count_xmit(new_skb, old_skb->dev); ++ ++ /* set skb->iif */ ++ new_skb->skb_iif = old_skb->skb_iif; ++ + netif_rx(new_skb); + + /* TBD: should copy be released here? */ +@@ -1841,6 +1848,10 @@ int pairs_xlate_v4_to_v6_outer(nat46_ins + return 0; + } + ++int xlate_4_to_6(struct net_device *dev, struct iphdr *hdr4, uint16_t sport, uint16_t dport, void *v6saddr, void *v6daddr) { ++ return pairs_xlate_v4_to_v6_outer(netdev_nat46_instance(dev), hdr4, &sport, &dport, v6saddr, v6daddr); ++} ++EXPORT_SYMBOL(xlate_4_to_6); + + int nat46_ipv4_input(struct sk_buff *old_skb) { + nat46_instance_t *nat46 = get_nat46_instance(old_skb); +@@ -1981,6 +1992,10 @@ int nat46_ipv4_input(struct sk_buff *old + + nat46debug(5, "about to send v6 packet, flags: %02x", IP6CB(new_skb)->flags); + nat46_netdev_count_xmit(new_skb, old_skb->dev); ++ ++ /* set skb->iif */ ++ new_skb->skb_iif = old_skb->skb_iif; ++ + netif_rx(new_skb); + + done: +@@ -1988,4 +2003,22 @@ done: + return err; + } + ++int nat46_get_npairs(struct net_device *dev) { ++ nat46_instance_t *nat46 = netdev_nat46_instance(dev); ++ return nat46->npairs; ++} ++EXPORT_SYMBOL(nat46_get_npairs); + ++bool nat46_get_rule_config(struct net_device *dev, nat46_xlate_rulepair_t **nat46_rule_pair, int *count) { ++ nat46_instance_t *nat46 = netdev_nat46_instance(dev); ++ if (nat46->npairs < 1) { ++ /* ++ * no rules ? ++ */ ++ return false; ++ } ++ *count = nat46->npairs; ++ *nat46_rule_pair = nat46->pairs; ++ return true; ++} ++EXPORT_SYMBOL(nat46_get_rule_config); +--- a/nat46/modules/nat46-core.h ++++ b/nat46/modules/nat46-core.h +@@ -42,18 +42,18 @@ typedef enum { + #define NAT46_SIGNATURE 0x544e3634 + #define FREED_NAT46_SIGNATURE 0xdead544e + +-typedef struct { ++typedef struct nat46_xlate_rule { + nat46_xlate_style_t style; + struct in6_addr v6_pref; +- int v6_pref_len; +- u32 v4_pref; +- int v4_pref_len; +- int ea_len; +- int psid_offset; +- int fmr_flag; ++ int v6_pref_len; ++ u32 v4_pref; ++ int v4_pref_len; ++ int ea_len; ++ int psid_offset; ++ int fmr_flag; + } nat46_xlate_rule_t; + +-typedef struct { ++typedef struct nat46_xlate_rulepair { + nat46_xlate_rule_t local; + nat46_xlate_rule_t remote; + } nat46_xlate_rulepair_t; +@@ -82,4 +82,9 @@ nat46_instance_t *get_nat46_instance(str + nat46_instance_t *alloc_nat46_instance(int npairs, nat46_instance_t *old, int from_ipair, int to_ipair, int remove_ipair); + void release_nat46_instance(nat46_instance_t *nat46); + ++int xlate_6_to_4(struct net_device *dev, struct ipv6hdr *ip6h, uint16_t proto, __u32 *pv4saddr, __u32 *pv4daddr); ++int xlate_4_to_6(struct net_device *dev, struct iphdr *hdr4, uint16_t sport, uint16_t dport, void *v6saddr, void *v6daddr); ++bool nat46_get_rule_config(struct net_device *dev, nat46_xlate_rulepair_t **nat46_rule_pair, int *count); ++int nat46_get_npairs(struct net_device *dev); ++ + #endif +--- a/nat46/modules/nat46-netdev.c ++++ b/nat46/modules/nat46-netdev.c +@@ -24,10 +24,12 @@ + #include + #include + #include ++#include + #include "nat46-core.h" + #include "nat46-module.h" + + #define NETDEV_DEFAULT_NAME "nat46." ++static RADIX_TREE(netdev_tree, GFP_ATOMIC); + + typedef struct { + u32 sig; +@@ -83,6 +85,18 @@ void nat46_netdev_count_xmit(struct sk_b + dev->stats.tx_bytes += skb->len; + } + ++void nat46_update_stats(struct net_device *dev, uint32_t rx_packets, uint32_t rx_bytes, ++ uint32_t tx_packets, uint32_t tx_bytes, uint32_t rx_dropped, uint32_t tx_dropped) ++{ ++ dev->stats.rx_packets += rx_packets; ++ dev->stats.rx_bytes += rx_bytes; ++ dev->stats.tx_packets += tx_packets; ++ dev->stats.tx_bytes += tx_bytes; ++ dev->stats.rx_dropped += rx_dropped; ++ dev->stats.tx_dropped += tx_dropped; ++} ++EXPORT_SYMBOL(nat46_update_stats); ++ + void *netdev_nat46_instance(struct net_device *dev) { + nat46_netdev_priv_t *priv = netdev_priv(dev); + return priv->nat46; +@@ -159,6 +173,11 @@ int nat46_netdev_create(char *basename, + printk("nat46: netdevice nat46 '%s' created successfully.\n", devname); + kfree(devname); + ++ /* ++ * add this netdevice to list ++ */ ++ radix_tree_insert(&netdev_tree, (*dev)->ifindex, (void *)*dev); ++ + return 0; + + err_register_dev: +@@ -175,10 +194,24 @@ void nat46_netdev_destroy(struct net_dev + netif_stop_queue(dev); + netdev_nat46_set_instance(dev, NULL); + unregister_netdev(dev); ++ radix_tree_delete(&netdev_tree, dev->ifindex); + free_netdev(dev); + printk("nat46: Destroying nat46 device.\n"); + } + ++bool is_map_t_dev(struct net_device *dev) ++{ ++ if(!dev) { ++ return false; ++ } ++ ++ if(radix_tree_lookup(&netdev_tree, dev->ifindex)) { ++ return true; ++ } ++ return false; ++} ++EXPORT_SYMBOL(is_map_t_dev); ++ + static int is_nat46(struct net_device *dev) { + nat46_netdev_priv_t *priv = netdev_priv(dev); + return (priv && (NAT46_DEVICE_SIGNATURE == priv->sig)); +--- a/nat46/modules/nat46-netdev.h ++++ b/nat46/modules/nat46-netdev.h +@@ -26,3 +26,6 @@ void nat64_show_all_configs(struct seq_f + void nat46_netdev_count_xmit(struct sk_buff *skb, struct net_device *dev); + void *netdev_nat46_instance(struct net_device *dev); + ++void nat46_update_stats(struct net_device *dev, uint32_t rx_packets, uint32_t rx_bytes, uint32_t tx_packets, uint32_t tx_bytes, ++ uint32_t rx_dropped, uint32_t tx_dropped); ++bool is_map_t_dev(struct net_device *dev); diff --git a/package/kernel/nat46/patches/103-tos.patch b/package/kernel/nat46/patches/103-tos.patch new file mode 100644 index 00000000000000..60ffcb2fae802a --- /dev/null +++ b/package/kernel/nat46/patches/103-tos.patch @@ -0,0 +1,39 @@ +Author: Pavithra R +Date: Sat Aug 1 13:55:33 2020 +0530 + +nat46: Set IPv6 traffic class from IPv4 ToS value + +Set IPv6 traffic class from IPv4 ToS value during +IPv4 to IPv6 translation and vice-versa. + +This patch is propagated from kernel 4.4 commit +1cd3b55b059d4513649bb73bc69da931ed3beb7b + +Change-Id: Ia14e53447e829c8648c01656237ac902ad8674ec +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -886,11 +886,12 @@ void *get_next_header_ptr6(void *pv6, in + } + + void fill_v4hdr_from_v6hdr(struct iphdr * iph, struct ipv6hdr *ip6h, __u32 v4saddr, __u32 v4daddr, __u16 id, __u16 frag_off, __u16 proto, int l3_payload_len) { ++ uint32_t ver_class_flow = ntohl(*(__be32 *)ip6h); + iph->ttl = ip6h->hop_limit; + iph->saddr = v4saddr; + iph->daddr = v4daddr; + iph->protocol = proto; +- *((__be16 *)iph) = htons((4 << 12) | (5 << 8) | (0x00/*tos*/ & 0xff)); ++ *((__be16 *)iph) = htons((4 << 12) | (5 << 8) | ((ver_class_flow >> 20) & 0xff)); + iph->frag_off = frag_off; + iph->id = id; + iph->tot_len = htons( l3_payload_len + IPV4HDRSIZE ); +@@ -1859,7 +1860,7 @@ int nat46_ipv4_input(struct sk_buff *old + uint16_t sport = 0, dport = 0; + + int err = 0; +- int tclass = 0; ++ uint8_t tclass = 0; + int flowlabel = 0; + int check_for_l4 = 0; + int having_l4 = 0; diff --git a/package/kernel/nat46/patches/104-icmp.patch b/package/kernel/nat46/patches/104-icmp.patch new file mode 100644 index 00000000000000..7907a66726005b --- /dev/null +++ b/package/kernel/nat46/patches/104-icmp.patch @@ -0,0 +1,439 @@ +Author: Pavithra R +Date: Mon Aug 3 17:03:37 2020 +0530 + +nat46: Fix for icmp translation issues. + +This patch is propagated from kernel 4.4 commit +45fce10ba0105515289930b3e3f9df57bf3c22b6. + +Fixed icmpv4 to icmpv6 and vice-versa translation issues, in accordance with RFC6145. + +The change covers: +1. Translation of ICMP errors from IPv4 to IPv6 and vice-versa. +2. Translation of inner L3 packet header {Eth:IPv4:ICMP:IPv4:ICMP} in ICMP error messages. +3. Address translation for packets not having port numbers, hence CE/BR needs to fetch this + information from inner header (atleast 28 bytes (IP hdr + 8 bytes) of orignal packet received + that is transmitted back will be there in response). + +Change-Id: I677474728aeaee656376fdb1edcb9476783d5b40 +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -29,6 +29,9 @@ + #include "nat46-core.h" + #include "nat46-module.h" + ++static uint16_t xlate_pkt_in_err_v4_to_v6(nat46_instance_t *nat46, struct iphdr *iph, ++ struct sk_buff *old_skb, uint16_t *sport, uint16_t *dport); ++ + void + nat46debug_dump(nat46_instance_t *nat46, int level, void *addr, int len) + { +@@ -885,6 +888,14 @@ void *get_next_header_ptr6(void *pv6, in + return ret; + } + ++void fill_v6hdr_from_v4hdr(struct iphdr *iph, struct ipv6hdr *ip6h) { ++ *((__be16 *)ip6h) = htons((6 << 12) | (iph->tos << 4)); /* Version, Traffic Class */ ++ memset(&(ip6h->flow_lbl), 0, sizeof(ip6h->flow_lbl)); /* Flowlabel */ ++ ip6h->payload_len = htons(ntohs(iph->tot_len) - IPV4HDRSIZE); ++ ip6h->nexthdr = iph->protocol; ++ ip6h->hop_limit = iph->ttl; ++} ++ + void fill_v4hdr_from_v6hdr(struct iphdr * iph, struct ipv6hdr *ip6h, __u32 v4saddr, __u32 v4daddr, __u16 id, __u16 frag_off, __u16 proto, int l3_payload_len) { + uint32_t ver_class_flow = ntohl(*(__be32 *)ip6h); + iph->ttl = ip6h->hop_limit; +@@ -1212,10 +1223,14 @@ static void nat46_fixup_icmp6_paramprob( + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -1 }; + u32 *pptr6 = icmp6_parameter_ptr(icmp6h); + u8 *pptr4 = icmp_parameter_ptr((struct icmphdr *)icmp6h); +- int new_pptr = -1; ++ u8 new_pptr = -1; + int len = ntohs(ip6h->payload_len)-sizeof(*icmp6h); + + switch(icmp6h->icmp6_code) { ++ case 1: ++ update_icmp6_type_code(nat46, icmp6h, 3, 2); ++ break; ++ + case 0: + if(*pptr6 < sizeof(ptr6_4)/sizeof(ptr6_4[0])) { + new_pptr = ptr6_4[*pptr6]; +@@ -1224,27 +1239,21 @@ static void nat46_fixup_icmp6_paramprob( + *pptr4 = 0xff & new_pptr; + update_icmp6_type_code(nat46, icmp6h, 12, 0); + len = xlate_payload6_to4(nat46, (icmp6h + 1), get_next_header_ptr6((icmp6h + 1), len), len, &icmp6h->icmp6_cksum, ptailTruncSize); +- } else { +- ip6h->nexthdr = NEXTHDR_NONE; ++ update_icmp6_type_code(nat46, icmp6h, 12, 0); ++ break; + } +- } else { +- ip6h->nexthdr = NEXTHDR_NONE; + } +- break; +- case 1: +- icmp6h->icmp6_cksum = csum16_upd(icmp6h->icmp6_cksum, ((*pptr6 >> 16) & 0xffff), 0); +- icmp6h->icmp6_cksum = csum16_upd(icmp6h->icmp6_cksum, (*pptr6 & 0xffff), 0); +- *pptr6 = 0; +- update_icmp6_type_code(nat46, icmp6h, 3, 2); +- len = xlate_payload6_to4(nat46, (icmp6h + 1), get_next_header_ptr6((icmp6h + 1), len), len, &icmp6h->icmp6_cksum, ptailTruncSize); +- break; ++#if __has_attribute(__fallthrough__) ++ __attribute__((__fallthrough__)); ++#endif + case 2: /* fallthrough to default */ + default: + ip6h->nexthdr = NEXTHDR_NONE; ++ return; + } ++ len = xlate_payload6_to4(nat46, (icmp6h + 1), get_next_header_ptr6((icmp6h + 1), len), len, &icmp6h->icmp6_cksum, ptailTruncSize); + } + +- + /* Fixup ICMP6->ICMP before IP header translation, according to http://tools.ietf.org/html/rfc6145 */ + + static void nat46_fixup_icmp6(nat46_instance_t *nat46, struct ipv6hdr *ip6h, struct icmp6hdr *icmp6h, struct sk_buff *old_skb, int *ptailTruncSize) { +@@ -1299,17 +1308,19 @@ int ip6_input_not_interested(nat46_insta + return 0; + } + +-static uint16_t nat46_fixup_icmp_time_exceeded(nat46_instance_t *nat46, struct iphdr *iph, struct icmphdr *icmph, struct sk_buff *old_skb) { ++static uint16_t nat46_fixup_icmp_time_exceeded(nat46_instance_t *nat46, struct iphdr *iph, ++ struct icmphdr *icmph, struct sk_buff *old_skb, uint16_t *sport, uint16_t *dport) { + /* + * Set the Type to 3, and adjust the + * ICMP checksum both to take the type change into account and + * to include the ICMPv6 pseudo-header. The Code is unchanged. + */ + icmph->type = 3; +- return 0; ++ return xlate_pkt_in_err_v4_to_v6(nat46, iph, old_skb, sport, dport); + } + +-static uint16_t nat46_fixup_icmp_parameterprob(nat46_instance_t *nat46, struct iphdr *iph, struct icmphdr *icmph, struct sk_buff *old_skb) { ++static uint16_t nat46_fixup_icmp_parameterprob(nat46_instance_t *nat46, struct iphdr *iph, ++ struct icmphdr *icmph, struct sk_buff *old_skb, uint16_t *sport, uint16_t *dport) { + /* + * Set the Type to 4, and adjust the + * ICMP checksum both to take the type/code change into account +@@ -1352,27 +1363,33 @@ static uint16_t nat46_fixup_icmp_paramet + */ + static int ptr4_6[] = { 0, 1, 4, 4, -1, -1, -1, -1, 7, 6, -1, -1, 8, 8, 8, 8, 24, 24, 24, 24, -1 }; + u8 *icmp_pptr = icmp_parameter_ptr(icmph); +- int new_pptr = -1; ++ u32 *icmp6_pptr = icmp6_parameter_ptr((struct icmp6hdr *)icmph); ++ int8_t new_pptr = -1; ++ ++ icmph->type = 4; ++ + switch (icmph->code) { + case 0: + case 2: + if (*icmp_pptr < (sizeof(ptr4_6)/sizeof(ptr4_6[0]))) { + icmph->code = 0; + new_pptr = ptr4_6[*icmp_pptr]; +- if(new_pptr >= 0) { +- /* FIXME: update the parameter pointer in ICMPv6 with new_pptr value */ ++ if (new_pptr >= 0) { ++ *icmp6_pptr = new_pptr; ++ return xlate_pkt_in_err_v4_to_v6(nat46, iph, old_skb, sport, dport); + } +- } else { +- iph->protocol = NEXTHDR_NONE; + } +- break; ++#if __has_attribute(__fallthrough__) ++ __attribute__((__fallthrough__)); ++#endif + default: + iph->protocol = NEXTHDR_NONE; + } + return 0; + } + +-static uint16_t nat46_fixup_icmp_dest_unreach(nat46_instance_t *nat46, struct iphdr *iph, struct icmphdr *icmph, struct sk_buff *old_skb) { ++static uint16_t nat46_fixup_icmp_dest_unreach(nat46_instance_t *nat46, struct iphdr *iph, ++ struct icmphdr *icmph, struct sk_buff *old_skb, uint16_t *sport, uint16_t *dport) { + /* + * Translate the Code as + * described below, set the Type to 1, and adjust the ICMP +@@ -1435,16 +1452,21 @@ static uint16_t nat46_fixup_icmp_dest_un + + u16 *pmtu = ((u16 *)icmph) + 3; /* IPv4-compatible MTU value is 16 bit */ + ++ icmph->type = 1; ++ + switch (icmph->code) { + case 0: + case 1: + icmph->code = 0; + break; +- case 2: +- /* FIXME: set ICMPv6 parameter pointer to 6 */ ++ case 2: { ++ u32 *icmp6_pptr = icmp6_parameter_ptr((struct icmp6hdr *)icmph); ++ *icmp6_pptr = 6; /* Offset to Next Proto field in IPv6 header. */ + icmph->type = 4; + icmph->code = 1; ++ nat46debug(3, "ICMP Proto Unreachable translated into IPv6 Param Prob.\n"); + break; ++ } + case 3: + icmph->code = 4; + break; +@@ -1494,13 +1516,15 @@ static uint16_t nat46_fixup_icmp_dest_un + break; + default: + iph->protocol = NEXTHDR_NONE; ++ return 0; + } +- return 0; ++ return xlate_pkt_in_err_v4_to_v6(nat46, iph, old_skb, sport, dport); + } + + /* Fixup ICMP->ICMP6 before IP header translation, according to http://tools.ietf.org/html/rfc6145 */ +- +-static uint16_t nat46_fixup_icmp(nat46_instance_t *nat46, struct iphdr *iph, struct sk_buff *old_skb) { ++static uint16_t nat46_fixup_icmp(nat46_instance_t *nat46, struct iphdr *iph, ++ struct sk_buff *old_skb, uint16_t *sport, uint16_t *dport) ++{ + struct icmphdr *icmph = (struct icmphdr *)(iph+1); + uint16_t ret = 0; + +@@ -1509,22 +1533,22 @@ static uint16_t nat46_fixup_icmp(nat46_i + switch(icmph->type) { + case ICMP_ECHO: + icmph->type = ICMPV6_ECHO_REQUEST; +- ret = icmph->un.echo.id; ++ *sport = *dport = icmph->un.echo.id; + nat46debug(3, "ICMP echo request translated into IPv6, id: %d", ntohs(ret)); + break; + case ICMP_ECHOREPLY: + icmph->type = ICMPV6_ECHO_REPLY; +- ret = icmph->un.echo.id; ++ *sport = *dport = icmph->un.echo.id; + nat46debug(3, "ICMP echo reply translated into IPv6, id: %d", ntohs(ret)); + break; + case ICMP_TIME_EXCEEDED: +- ret = nat46_fixup_icmp_time_exceeded(nat46, iph, icmph, old_skb); ++ ret = nat46_fixup_icmp_time_exceeded(nat46, iph, icmph, old_skb, sport, dport); + break; + case ICMP_PARAMETERPROB: +- ret = nat46_fixup_icmp_parameterprob(nat46, iph, icmph, old_skb); ++ ret = nat46_fixup_icmp_parameterprob(nat46, iph, icmph, old_skb, sport, dport); + break; + case ICMP_DEST_UNREACH: +- ret = nat46_fixup_icmp_dest_unreach(nat46, iph, icmph, old_skb); ++ ret = nat46_fixup_icmp_dest_unreach(nat46, iph, icmph, old_skb, sport, dport); + break; + default: + /* Silently drop. */ +@@ -1544,11 +1568,13 @@ int pairs_xlate_v6_to_v4_outer(nat46_ins + + if(-1 == xlate_dst) { + if (xlate_v6_to_v4(nat46, &apair->local, &ip6h->daddr, pv4daddr)) { ++ nat46debug(5, "Dst addr %pI6 to %pI4 \n", &ip6h->daddr, pv4daddr); + xlate_dst = ipair; + } + } + if(-1 == xlate_src) { + if (xlate_v6_to_v4(nat46, &apair->remote, &ip6h->saddr, pv4saddr)) { ++ nat46debug(5, "Src addr %pI6 to %pI4 \n", &ip6h->saddr, pv4saddr); + xlate_src = ipair; + } + } +@@ -1659,6 +1685,7 @@ int nat46_ipv6_input(struct sk_buff *old + } + + if(!pairs_xlate_v6_to_v4_outer(nat46, ip6h, proto, &v4saddr, &v4daddr)) { ++ nat46debug(0, "[nat46] Could not translate v6->v4"); + goto done; + } + +@@ -1821,11 +1848,13 @@ int pairs_xlate_v4_to_v6_outer(nat46_ins + + if(-1 == xlate_src) { + if(xlate_v4_to_v6(nat46, &apair->local, &hdr4->saddr, v6saddr, sport)) { ++ nat46debug(5, "Src addr %pI4 to %pI6 \n", &hdr4->saddr, v6saddr); + xlate_src = ipair; + } + } + if(-1 == xlate_dst) { + if(xlate_v4_to_v6(nat46, &apair->remote, &hdr4->daddr, v6daddr, dport)) { ++ nat46debug(5, "Dst addr %pI4 to %pI6 \n", &hdr4->daddr, v6daddr); + xlate_dst = ipair; + } + } +@@ -1854,10 +1883,145 @@ int xlate_4_to_6(struct net_device *dev, + } + EXPORT_SYMBOL(xlate_4_to_6); + ++/* FIXME: This is a workaround, till the LPM is not added. The sport & dport in inner header will be dport & sport of the outer ++ * header, respectively. Hence, dest. and source ips of inner header will be found in local & remote rules, respectively. ++ * Will work only for a pair of local & remote rules. Once LPM is brought in, this method can be removed and ++ * pairs_xlate_v4_to_v6_outer be used instead. ++ */ ++int pairs_xlate_v4_to_v6_inner(nat46_instance_t *nat46, struct iphdr *iph, ++ uint16_t sport, uint16_t dport, void *v6saddr, void *v6daddr) { ++ int ipair = 0; ++ nat46_xlate_rulepair_t *apair = NULL; ++ int xlate_src = -1; ++ int xlate_dst = -1; ++ ++ for (ipair = 0; ipair < nat46->npairs; ipair++) { ++ apair = &nat46->pairs[ipair]; ++ ++ if (-1 == xlate_dst) { ++ if (xlate_v4_to_v6(nat46, &apair->local, &iph->daddr, v6daddr, &dport)) { ++ nat46debug(3, "Dst addr %pI4 to %pI6 \n", &iph->daddr, v6daddr); ++ xlate_dst = ipair; ++ } ++ } ++ if (-1 == xlate_src) { ++ if(xlate_v4_to_v6(nat46, &apair->remote, &iph->saddr, v6saddr, &sport)) { ++ nat46debug(3, "Src addr %pI4 to %pI6 \n", &iph->saddr, v6saddr); ++ xlate_src = ipair; ++ } ++ } ++ if ((xlate_src >= 0) && (xlate_dst >= 0)) { ++ /* we did manage to translate it */ ++ nat46debug(5, "[nat46] Inner header xlate results: src %d dst %d", xlate_src, xlate_dst); ++ return 1; ++ } else { ++ /* We did not match fully and there are more rules */ ++ if((ipair+1 < nat46->npairs) && is_last_pair_in_group(apair)) { ++ xlate_src = -1; ++ xlate_dst = -1; ++ } ++ } ++} ++ ++ nat46debug(1, "[nat46] Could not find a translation pair v4->v6"); ++ return 0; ++} ++ ++static uint16_t xlate_pkt_in_err_v4_to_v6(nat46_instance_t *nat46, struct iphdr *iph, ++ struct sk_buff *old_skb, uint16_t *sport, uint16_t *dport) { ++ struct ipv6hdr ip6h; ++ char v6saddr[16], v6daddr[16]; ++ uint16_t temp_port = 0; ++ int ret = 0; ++ struct icmphdr *icmph = (struct icmphdr *)(iph + 1); ++ struct iphdr *iiph = (struct iphdr *)(icmph + 1); ++ ++ switch (iiph->protocol) { ++ case IPPROTO_TCP: { ++ struct tcphdr *th = (struct tcphdr *)(iiph + 1); ++ *sport = th->source; ++ *dport = th->dest; ++ iiph->protocol = NEXTHDR_TCP; ++ break; ++ } ++ case IPPROTO_UDP: { ++ struct udphdr *udp = (struct udphdr *)(iiph + 1); ++ *sport = udp->source; ++ *dport = udp->dest; ++ iiph->protocol = NEXTHDR_UDP; ++ break; ++ } ++ case IPPROTO_ICMP: { ++ struct icmphdr *icmph = (struct icmphdr *)(iiph + 1); ++ iiph->protocol = NEXTHDR_ICMP; ++ switch (icmph->type) { ++ case ICMP_ECHO: ++ icmph->type = ICMPV6_ECHO_REQUEST; ++ *sport = *dport = icmph->un.echo.id; ++ break; ++ case ICMP_ECHOREPLY: ++ icmph->type = ICMPV6_ECHO_REPLY; ++ *sport = *dport = icmph->un.echo.id; ++ break; ++ default: ++ nat46debug(3, "ICMP Error message can't be inside another ICMP Error messgae."); ++ *sport = *dport = 0; ++ return 0; ++ } ++ break; ++ } ++ default: ++ nat46debug(3, "[ICMPv4] Next header: %u. Only TCP, UDP, and ICMP are supported.", iiph->protocol); ++ *sport = *dport = 0; ++ return 0; ++ } ++ ++ nat46debug(3, "Retrieved from pkt in error: dest port %d, and src port %d.", ntohs(*dport), ntohs(*sport)); ++ ++ if (!pairs_xlate_v4_to_v6_inner(nat46, iiph, *sport, *dport, v6saddr, v6daddr)) { ++ nat46debug(0, "[nat46] Could not translate inner header v4->v6"); ++ *sport = *dport = 0; ++ return 0; ++ } ++ ++ fill_v6hdr_from_v4hdr (iiph, &ip6h); ++ memcpy(&ip6h.saddr, v6saddr, sizeof(ip6h.saddr)); ++ memcpy(&ip6h.daddr, v6daddr, sizeof(ip6h.daddr)); ++ ++ if (skb_tailroom(old_skb) >= IPV6V4HDRDELTA){ ++ skb_put(old_skb, IPV6V4HDRDELTA); ++ memmove(((char *)iiph + IPV6HDRSIZE), (iiph + 1), ntohs(iiph->tot_len) - IPV4HDRSIZE); ++ memcpy(iiph, &ip6h, IPV6HDRSIZE); ++ } ++ else { ++ ret = pskb_expand_head(old_skb, 0, IPV6V4HDRDELTA, GFP_ATOMIC); ++ if (unlikely(ret)) { ++ nat46debug(0, "[nat46] Could not copy v4 skb"); ++ *sport = *dport = 0; ++ return 0; ++ } ++ ++ skb_put(old_skb, IPV6V4HDRDELTA); ++ iiph = (struct iphdr *)(icmp_hdr(old_skb) + 1); ++ memmove(((char *)iiph + IPV6HDRSIZE), (iiph + 1), ntohs(iiph->tot_len) - IPV4HDRSIZE); ++ memcpy(iiph, &ip6h, IPV6HDRSIZE); ++ nat46 = get_nat46_instance(old_skb); ++ iph = ip_hdr(old_skb); ++ } ++ ++ /* Swapping Ports for outer header */ ++ /* Another work-around till LPM is not present. */ ++ temp_port = *sport; ++ *sport = *dport; ++ *dport = temp_port; ++ ++ return 1; ++} ++ + int nat46_ipv4_input(struct sk_buff *old_skb) { + nat46_instance_t *nat46 = get_nat46_instance(old_skb); + struct sk_buff *new_skb; +- uint16_t sport = 0, dport = 0; ++ uint16_t sport = 0, dport = 0, ret = 0; + + int err = 0; + uint8_t tclass = 0; +@@ -1879,7 +2043,7 @@ int nat46_ipv4_input(struct sk_buff *old + } + nat46debug(1, "nat46_ipv4_input packet"); + nat46debug(5, "nat46_ipv4_input protocol: %d, len: %d, flags: %02x", hdr4->protocol, old_skb->len, IPCB(old_skb)->flags); +- if(0 == (ntohs(hdr4->frag_off) & 0x3FFF) ) { ++ if (0 == (ntohs(hdr4->frag_off) & 0x3FFF)) { + check_for_l4 = 1; + } else if (IPPROTO_ICMP == hdr4->protocol) { + /* +@@ -1916,9 +2080,10 @@ int nat46_ipv4_input(struct sk_buff *old + break; + } + case IPPROTO_ICMP: +- sport = dport = nat46_fixup_icmp(nat46, hdr4, old_skb); +- having_l4 = 1; +- break; ++ ret = nat46_fixup_icmp(nat46, hdr4, old_skb, &sport, &dport); ++ nat46debug(3, "ICMP translated to dest port %d, and src port %d.", ntohs(dport), ntohs(sport)); ++ having_l4 = 1; ++ break; + default: + break; + } diff --git a/package/kernel/nat46/patches/105-longest-prefix-match.patch b/package/kernel/nat46/patches/105-longest-prefix-match.patch new file mode 100644 index 00000000000000..95fe6af973f45b --- /dev/null +++ b/package/kernel/nat46/patches/105-longest-prefix-match.patch @@ -0,0 +1,640 @@ +Author: Pavithra R +Date: Tue Aug 4 10:33:59 2020 +0530 + +nat46: Adding support for multiple MAP-T rules. + +This patch is propagated from kernel 4.4 commit +05a122b0cb0d3a99f040c94b3f626e7350f1445b + +This change covers: +1. Support for adding maximum of 32 MAP-T rules (DMR + FMRs). +2. Support for rule lookup based on Longest Prefix Match method. +3. Support for validation of new rules being inserted. + +Change-Id: Id87448a8f544273b40c20aaab6e5c63b0dbd72e +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -128,6 +128,13 @@ int try_parse_ipv6_prefix(struct in6_add + *arg_plen++ = 0; + if (pref_len) { + *pref_len = simple_strtol(arg_plen, NULL, 10); ++ ++ /* ++ * ipv6 prefix should be <= 128 ++ */ ++ if (*pref_len > IPV6_BITS_MAX) { ++ return -1; ++ } + } + } + err = (1 != in6_pton(arg, -1, (u8 *)pref, '\0', NULL)); +@@ -141,6 +148,13 @@ int try_parse_ipv4_prefix(u32 *v4addr, i + *arg_plen++ = 0; + if (pref_len) { + *pref_len = simple_strtol(arg_plen, NULL, 10); ++ ++ /* ++ * ipv4 prefix len should be <= 32 ++ */ ++ if (*pref_len > IPV4_BITS_MAX) { ++ return -1; ++ } + } + } + err = (1 != in4_pton(arg, -1, (u8 *)v4addr, '/', NULL)); +@@ -183,11 +197,127 @@ int try_parse_rule_arg(nat46_xlate_rule_ + return err; + } + +-/* +- * Parse the config commands in the buffer, +- * destructive (puts zero between the args) ++static inline void nat46_swap(nat46_xlate_rulepair_t *var1, nat46_xlate_rulepair_t *var2) { ++ nat46_xlate_rulepair_t temp; ++ temp = *var1; ++ *var1 = *var2; ++ *var2 = temp; ++} ++ ++/* ++ * Sort rule pairs based on prefix length. + */ ++void nat46_sort_rule_array(nat46_instance_t *nat46) { ++ int i, j; ++ int nelem = nat46->npairs; ++ nat46_xlate_rulepair_t *array = NULL; ++ ++ memcpy(nat46->sorted_ipv4_local_pairs, nat46->pairs, nelem * sizeof(nat46_xlate_rulepair_t)); ++ memcpy(nat46->sorted_ipv4_remote_pairs, nat46->pairs, nelem * sizeof(nat46_xlate_rulepair_t)); ++ memcpy(nat46->sorted_ipv6_local_pairs, nat46->pairs, nelem * sizeof(nat46_xlate_rulepair_t)); ++ memcpy(nat46->sorted_ipv6_remote_pairs, nat46->pairs, nelem * sizeof(nat46_xlate_rulepair_t)); ++ ++ array = &nat46->sorted_ipv4_local_pairs[0]; ++ for (i = 0; i < nelem - 1; i++) { ++ for (j = 0; j < nelem - i - 1; j++) { ++ if (array[j].local.v4_pref_len < array[j+1].local.v4_pref_len) { ++ nat46_swap (&array[j], &array[j+1]); ++ } ++ } ++ } ++ ++ array = &nat46->sorted_ipv4_remote_pairs[0]; ++ for (i = 0; i < nelem - 1; i++) { ++ for (j = 0; j < nelem - i - 1; j++) { ++ if (array[j].remote.v4_pref_len < array[j+1].remote.v4_pref_len) { ++ nat46_swap (&array[j], &array[j+1]); ++ } ++ } ++ } + ++ array = &nat46->sorted_ipv6_local_pairs[0]; ++ for (i = 0; i < nelem - 1; i++) { ++ for (j = 0; j < nelem - i - 1; j++) { ++ if (array[j].local.v6_pref_len < array[j+1].local.v6_pref_len) { ++ nat46_swap (&array[j], &array[j+1]); ++ } ++ } ++ } ++ ++ array = &nat46->sorted_ipv6_remote_pairs[0]; ++ for (i = 0; i < nelem - 1; i++) { ++ for (j = 0; j < nelem - i - 1; j++) { ++ if (array[j].remote.v6_pref_len < array[j+1].remote.v6_pref_len) { ++ nat46_swap (&array[j], &array[j+1]); ++ } ++ } ++ } ++} ++ ++bool nat46_validate_RFC6052_style(nat46_instance_t *nat46, nat46_xlate_rule_t rule) ++{ ++ if (rule.style == NAT46_XLATE_RFC6052) { ++ if (!((rule.v6_pref_len == 32) || (rule.v6_pref_len == 40) || ++ (rule.v6_pref_len == 48) || (rule.v6_pref_len == 56) || ++ (rule.v6_pref_len == 64) || (rule.v6_pref_len == 96))) { ++ nat46debug(3, "IPv6 prefix len is invalid"); ++ return false; ++ } ++ } ++ return true; ++} ++ ++bool nat46_validate_MAP_style(nat46_instance_t *nat46, nat46_xlate_rule_t rule) ++{ ++ int psid_len; ++ if (rule.style == NAT46_XLATE_MAP) { ++ ++ /* ++ * max ea_len is 48 ++ */ ++ if (rule.ea_len > EA_LEN_MAX) { ++ nat46debug(3, "EA-length should not exceed 48"); ++ return false; ++ } ++ ++ if (rule.v4_pref_len + rule.ea_len > IPV4_BITS_MAX) { ++ psid_len = rule.ea_len - (IPV4_BITS_MAX - rule.v4_pref_len); ++ } else { ++ psid_len = 0; ++ } ++ ++ if (psid_len + rule.psid_offset > PSID_LEN_MAX) { ++ nat46debug(3, "psid_len + psid_offset should not exceed 16"); ++ return false; ++ } ++ } ++ return true; ++} ++ ++int nat46_validate_ipair_config(nat46_instance_t *nat46, nat46_xlate_rulepair_t *apair) ++{ ++ if (!nat46_validate_RFC6052_style(nat46, apair->local)) { ++ return -1; ++ } ++ ++ if (!nat46_validate_RFC6052_style(nat46, apair->remote)) { ++ return -1; ++ } ++ ++ if (!nat46_validate_MAP_style(nat46, apair->local)) { ++ return -1; ++ } ++ ++ if (!nat46_validate_MAP_style(nat46, apair->remote)) { ++ return -1; ++ } ++ return 0; ++} ++ ++/* ++ * Parse the config commands in the buffer, ++ * destructive (puts zero between the args) ++ */ + int nat46_set_ipair_config(nat46_instance_t *nat46, int ipair, char *buf, int count) { + char *tail = buf; + char *arg_name; +@@ -217,7 +347,18 @@ int nat46_set_ipair_config(nat46_instanc + err = try_parse_rule_arg(&apair->remote, arg_name, &tail); + } + } +- return err; ++ ++ err = nat46_validate_ipair_config(nat46, apair); ++ if (err) { ++ return err; ++ } ++ ++ /* ++ * sort nat46->pairs based on prefix length. ++ */ ++ nat46_sort_rule_array(nat46); ++ ++ return 0; + } + + int nat46_set_config(nat46_instance_t *nat46, char *buf, int count) { +@@ -933,37 +1074,120 @@ int is_last_pair_in_group(nat46_xlate_ru + return ( (apair->local.style != NAT46_XLATE_NONE) && (apair->remote.style != NAT46_XLATE_NONE) ); + } + ++nat46_xlate_rulepair_t *nat46_lpm(nat46_instance_t *nat46, nat46_rule_type_t type, void *paddr) { ++ int ipair = 0; ++ nat46_xlate_rulepair_t *apair = NULL; ++ uint32_t mask = 0; ++ uint8_t *pa1; ++ uint8_t *pa2; ++ ++ if(!nat46 || !paddr) { ++ return NULL; ++ } ++ ++ switch (type) { ++ case NAT46_IPV4_LOCAL: ++ for (ipair = 0; ipair < nat46->npairs; ipair++) { ++ apair = &nat46->sorted_ipv4_local_pairs[ipair]; ++ ++ /* ++ * For a 32-bit number, if the shift count is 32, then the ++ * result of the left shift operation is always 0. ++ */ ++ if (apair->local.v4_pref_len) { ++ mask = htonl(U32_MASK << (IPV4_BITS_MAX - apair->local.v4_pref_len)); ++ } ++ ++ if((*(uint32_t *)paddr & mask) == (apair->local.v4_pref & mask)) { ++ return apair; ++ } ++ } ++ break; ++ case NAT46_IPV4_REMOTE: ++ for (ipair = 0; ipair < nat46->npairs; ipair++) { ++ apair = &nat46->sorted_ipv4_remote_pairs[ipair]; ++ ++ /* ++ * For a 32-bit number, if the shift count is 32, then the ++ * result of the left shift operation is always 0. ++ */ ++ if (apair->remote.v4_pref_len) { ++ mask = htonl(U32_MASK << (IPV4_BITS_MAX - apair->remote.v4_pref_len)); ++ } ++ ++ if((*(uint32_t *)paddr & mask) == (apair->remote.v4_pref & mask)) { ++ return apair; ++ } ++ } ++ break; ++ case NAT46_IPV6_LOCAL: ++ for (ipair = 0; ipair < nat46->npairs; ipair++) { ++ apair = &nat46->sorted_ipv6_local_pairs[ipair]; ++ if(memcmp(paddr, &apair->local.v6_pref, apair->local.v6_pref_len / BITS_PER_BYTE)) { ++ continue; ++ } ++ if(apair->local.v6_pref_len % BITS_PER_BYTE) { ++ mask = U8_MASK << (BITS_PER_BYTE - (apair->local.v6_pref_len % BITS_PER_BYTE)); ++ pa1 = (uint8_t *)paddr + (apair->local.v6_pref_len / BITS_PER_BYTE); ++ pa2 = (uint8_t *)&apair->local.v6_pref + (apair->local.v6_pref_len / BITS_PER_BYTE); ++ ++ if ((*pa1 & mask) == (*pa2 & mask)) { ++ return apair; ++ } ++ } ++ else ++ return apair; ++ } ++ break; ++ case NAT46_IPV6_REMOTE: ++ for (ipair = 0; ipair < nat46->npairs; ipair++) { ++ apair = &nat46->sorted_ipv6_remote_pairs[ipair]; ++ if(memcmp(paddr, &apair->remote.v6_pref, apair->remote.v6_pref_len / BITS_PER_BYTE)) { ++ continue; ++ } ++ if(apair->remote.v6_pref_len % BITS_PER_BYTE) { ++ mask = U8_MASK << (BITS_PER_BYTE - (apair->remote.v6_pref_len % BITS_PER_BYTE)); ++ pa1 = (uint8_t *)paddr + (apair->remote.v6_pref_len / BITS_PER_BYTE); ++ pa2 = (uint8_t *)&apair->remote.v6_pref + (apair->remote.v6_pref_len / BITS_PER_BYTE); ++ ++ if((*pa1 & mask) == (*pa2 & mask)) { ++ return apair; ++ } ++ } ++ else ++ return apair; ++ } ++ break; ++ default: ++ nat46debug(0, "%s : Invalid prefix type.\n", __func__); ++ } ++ return NULL; ++} ++ + void pairs_xlate_v6_to_v4_inner(nat46_instance_t *nat46, struct ipv6hdr *ip6h, __u32 *pv4saddr, __u32 *pv4daddr) { + int ipair = 0; + nat46_xlate_rulepair_t *apair = NULL; + int xlate_src = -1; + int xlate_dst = -1; + +- for(ipair = 0; ipair < nat46->npairs; ipair++) { +- apair = &nat46->pairs[ipair]; ++ apair = nat46_lpm(nat46, NAT46_IPV6_REMOTE, &ip6h->daddr); ++ if (!apair) { ++ return; ++ } + +- if(-1 == xlate_dst) { +- if(xlate_v6_to_v4(nat46, &apair->remote, &ip6h->daddr, pv4daddr)) { +- xlate_dst = ipair; +- } +- } +- if(-1 == xlate_src) { +- if(xlate_v6_to_v4(nat46, &apair->local, &ip6h->saddr, pv4saddr)) { +- xlate_src = ipair; +- } +- } +- if((xlate_src >= 0) && (xlate_dst >= 0)) { +- /* we did manage to translate it */ +- break; +- } else { +- /* We did not match fully and there are more rules */ +- if((ipair+1 < nat46->npairs) && is_last_pair_in_group(apair)) { +- xlate_src = -1; +- xlate_dst = -1; +- } +- } ++ if (xlate_v6_to_v4(nat46, &apair->remote, &ip6h->daddr, pv4daddr)) { ++ xlate_dst = ipair; ++ } ++ if (xlate_v6_to_v4(nat46, &apair->local, &ip6h->saddr, pv4saddr)) { ++ xlate_src = ipair; ++ } ++ ++ if ((xlate_src >= 0) && (xlate_dst >= 0)) { ++ /* we did manage to translate it */ ++ nat46debug(5, "[nat46payload] xlate results: src %d dst %d", xlate_src, xlate_dst); ++ } else { ++ nat46debug(1, "[nat46] Could not find a translation pair v6->v4 src %pI6c dst %pI6c", &ip6h->saddr, &ip6h->daddr); + } +- nat46debug(5, "[nat46payload] xlate results: src %d dst %d", xlate_src, xlate_dst); + } + + /* +@@ -1557,40 +1781,31 @@ static uint16_t nat46_fixup_icmp(nat46_i + return ret; + } + +-int pairs_xlate_v6_to_v4_outer(nat46_instance_t *nat46, struct ipv6hdr *ip6h, uint16_t proto, __u32 *pv4saddr, __u32 *pv4daddr) { ++int pairs_xlate_v6_to_v4_outer(nat46_instance_t *nat46, nat46_xlate_rulepair_t *apair, ++ struct ipv6hdr *ip6h, uint16_t proto, __u32 *pv4saddr, __u32 *pv4daddr) { + int ipair = 0; +- nat46_xlate_rulepair_t *apair = NULL; + int xlate_src = -1; + int xlate_dst = -1; + + for(ipair = 0; ipair < nat46->npairs; ipair++) { +- apair = &nat46->pairs[ipair]; +- +- if(-1 == xlate_dst) { +- if (xlate_v6_to_v4(nat46, &apair->local, &ip6h->daddr, pv4daddr)) { +- nat46debug(5, "Dst addr %pI6 to %pI4 \n", &ip6h->daddr, pv4daddr); +- xlate_dst = ipair; +- } ++ apair = nat46_lpm(nat46, NAT46_IPV6_REMOTE, &ip6h->saddr); ++ if (!apair) { ++ return 0; + } +- if(-1 == xlate_src) { +- if (xlate_v6_to_v4(nat46, &apair->remote, &ip6h->saddr, pv4saddr)) { +- nat46debug(5, "Src addr %pI6 to %pI4 \n", &ip6h->saddr, pv4saddr); +- xlate_src = ipair; +- } ++ ++ if (xlate_v6_to_v4(nat46, &apair->local, &ip6h->daddr, pv4daddr)) { ++ nat46debug(5, "Dst addr %pI6 to %pI4 \n", &ip6h->daddr, pv4daddr); ++ xlate_dst = ipair; + } +- if( (xlate_src >= 0) && (xlate_dst >= 0) ) { +- break; +- } else { +- /* We did not match fully and there are more rules */ +- if((ipair+1 < nat46->npairs) && is_last_pair_in_group(apair)) { +- xlate_src = -1; +- xlate_dst = -1; +- } ++ ++ if (xlate_v6_to_v4(nat46, &apair->remote, &ip6h->saddr, pv4saddr)) { ++ nat46debug(5, "Src addr %pI6 to %pI4 \n", &ip6h->saddr, pv4saddr); ++ xlate_src = ipair; + } + } + if (xlate_dst >= 0) { + if (xlate_src < 0) { +- if(proto == NEXTHDR_ICMP) { ++ if (proto == NEXTHDR_ICMP) { + nat46debug(1, "[nat46] Could not translate remote address v6->v4, ipair %d, for ICMP6 use dest addr", ipair); + *pv4saddr = *pv4daddr; + xlate_src = xlate_dst; +@@ -1606,12 +1821,14 @@ int pairs_xlate_v6_to_v4_outer(nat46_ins + } + + int xlate_6_to_4(struct net_device *dev, struct ipv6hdr *ip6h, uint16_t proto, __u32 *pv4saddr, __u32 *pv4daddr) { +- return pairs_xlate_v6_to_v4_outer(netdev_nat46_instance(dev), ip6h, proto, pv4saddr, pv4daddr); ++ nat46_xlate_rulepair_t apair; ++ return pairs_xlate_v6_to_v4_outer(netdev_nat46_instance(dev), &apair, ip6h, proto, pv4saddr, pv4daddr); + } + EXPORT_SYMBOL(xlate_6_to_4); + + int nat46_ipv6_input(struct sk_buff *old_skb) { + struct ipv6hdr *ip6h = ipv6_hdr(old_skb); ++ nat46_xlate_rulepair_t apair; + nat46_instance_t *nat46 = get_nat46_instance(old_skb); + uint16_t proto; + uint16_t frag_off; +@@ -1684,7 +1901,7 @@ int nat46_ipv6_input(struct sk_buff *old + check_for_l4 = 1; + } + +- if(!pairs_xlate_v6_to_v4_outer(nat46, ip6h, proto, &v4saddr, &v4daddr)) { ++ if (!pairs_xlate_v6_to_v4_outer(nat46, &apair, ip6h, proto, &v4saddr, &v4daddr)) { + nat46debug(0, "[nat46] Could not translate v6->v4"); + goto done; + } +@@ -1837,56 +2054,44 @@ int ip4_input_not_interested(nat46_insta + return 0; + } + +-int pairs_xlate_v4_to_v6_outer(nat46_instance_t *nat46, struct iphdr *hdr4, uint16_t *sport, uint16_t *dport, void *v6saddr, void *v6daddr) { ++int pairs_xlate_v4_to_v6_outer(nat46_instance_t *nat46, nat46_xlate_rulepair_t *apair, ++ struct iphdr *hdr4, uint16_t *sport, uint16_t *dport, void *v6saddr, void *v6daddr) { + int ipair = 0; +- nat46_xlate_rulepair_t *apair = NULL; + int xlate_src = -1; + int xlate_dst = -1; ++ int ret = 0; + +- for(ipair = 0; ipair < nat46->npairs; ipair++) { +- apair = &nat46->pairs[ipair]; ++ apair = nat46_lpm(nat46, NAT46_IPV4_REMOTE, &hdr4->daddr); ++ if (!apair) { ++ return 0; ++ } + +- if(-1 == xlate_src) { +- if(xlate_v4_to_v6(nat46, &apair->local, &hdr4->saddr, v6saddr, sport)) { +- nat46debug(5, "Src addr %pI4 to %pI6 \n", &hdr4->saddr, v6saddr); +- xlate_src = ipair; +- } +- } +- if(-1 == xlate_dst) { +- if(xlate_v4_to_v6(nat46, &apair->remote, &hdr4->daddr, v6daddr, dport)) { +- nat46debug(5, "Dst addr %pI4 to %pI6 \n", &hdr4->daddr, v6daddr); +- xlate_dst = ipair; +- } +- } +- if( (xlate_src >= 0) && (xlate_dst >= 0) ) { +- break; +- } else { +- /* We did not match fully and there are more rules */ +- if((ipair+1 < nat46->npairs) && is_last_pair_in_group(apair)) { +- xlate_src = -1; +- xlate_dst = -1; +- } +- } ++ if (xlate_v4_to_v6(nat46, &apair->local, &hdr4->saddr, v6saddr, sport)) { ++ nat46debug(5, "Src addr %pI4 to %pI6 \n", &hdr4->saddr, v6saddr); ++ xlate_src = ipair; ++ } ++ if (xlate_v4_to_v6(nat46, &apair->remote, &hdr4->daddr, v6daddr, dport)) { ++ nat46debug(5, "Dst addr %pI4 to %pI6 \n", &hdr4->daddr, v6daddr); ++ xlate_dst = ipair; + } + nat46debug(5, "[nat46] pairs_xlate_v4_to_v6_outer result: src %d dst %d", xlate_src, xlate_dst); + if ( (xlate_src >= 0) && (xlate_dst >= 0) ) { +- return 1; ++ ret = 1; ++ } else { ++ nat46debug(1, "[nat46] Could not find a translation pair v4->v6"); + } +- +- nat46debug(1, "[nat46] Could not find a translation pair v4->v6"); +- +- return 0; ++ return ret; + } + + int xlate_4_to_6(struct net_device *dev, struct iphdr *hdr4, uint16_t sport, uint16_t dport, void *v6saddr, void *v6daddr) { +- return pairs_xlate_v4_to_v6_outer(netdev_nat46_instance(dev), hdr4, &sport, &dport, v6saddr, v6daddr); ++ nat46_xlate_rulepair_t apair; ++ return pairs_xlate_v4_to_v6_outer(netdev_nat46_instance(dev), &apair, hdr4, &sport, &dport, v6saddr, v6daddr); + } + EXPORT_SYMBOL(xlate_4_to_6); + +-/* FIXME: This is a workaround, till the LPM is not added. The sport & dport in inner header will be dport & sport of the outer +- * header, respectively. Hence, dest. and source ips of inner header will be found in local & remote rules, respectively. +- * Will work only for a pair of local & remote rules. Once LPM is brought in, this method can be removed and +- * pairs_xlate_v4_to_v6_outer be used instead. ++/* ++ * The sport & dport in inner header will be dport & sport of the outer header, respectively. ++ * Hence, dest. and source ips of inner header will be found in local & remote rules, respectively. + */ + int pairs_xlate_v4_to_v6_inner(nat46_instance_t *nat46, struct iphdr *iph, + uint16_t sport, uint16_t dport, void *v6saddr, void *v6daddr) { +@@ -1895,35 +2100,27 @@ int pairs_xlate_v4_to_v6_inner(nat46_ins + int xlate_src = -1; + int xlate_dst = -1; + +- for (ipair = 0; ipair < nat46->npairs; ipair++) { +- apair = &nat46->pairs[ipair]; ++ apair = nat46_lpm(nat46, NAT46_IPV4_REMOTE, &iph->saddr); ++ if (!apair) { ++ return 0; ++ } + +- if (-1 == xlate_dst) { +- if (xlate_v4_to_v6(nat46, &apair->local, &iph->daddr, v6daddr, &dport)) { +- nat46debug(3, "Dst addr %pI4 to %pI6 \n", &iph->daddr, v6daddr); +- xlate_dst = ipair; +- } +- } +- if (-1 == xlate_src) { +- if(xlate_v4_to_v6(nat46, &apair->remote, &iph->saddr, v6saddr, &sport)) { +- nat46debug(3, "Src addr %pI4 to %pI6 \n", &iph->saddr, v6saddr); +- xlate_src = ipair; +- } +- } +- if ((xlate_src >= 0) && (xlate_dst >= 0)) { +- /* we did manage to translate it */ +- nat46debug(5, "[nat46] Inner header xlate results: src %d dst %d", xlate_src, xlate_dst); +- return 1; +- } else { +- /* We did not match fully and there are more rules */ +- if((ipair+1 < nat46->npairs) && is_last_pair_in_group(apair)) { +- xlate_src = -1; +- xlate_dst = -1; +- } +- } +-} ++ if (xlate_v4_to_v6(nat46, &apair->local, &iph->daddr, v6daddr, &dport)) { ++ nat46debug(3, "Dst addr %pI4 to %pI6 \n", &iph->daddr, v6daddr); ++ xlate_dst = ipair; ++ } ++ if (xlate_v4_to_v6(nat46, &apair->remote, &iph->saddr, v6saddr, &sport)) { ++ nat46debug(3, "Src addr %pI4 to %pI6 \n", &iph->saddr, v6saddr); ++ xlate_src = ipair; ++ } ++ if ((xlate_src >= 0) && (xlate_dst >= 0)) { ++ /* we did manage to translate it */ ++ nat46debug(5, "[nat46] Inner header xlate results: src %d dst %d", xlate_src, xlate_dst); ++ return 1; ++ } else { ++ nat46debug(1, "[nat46] Could not find a translation pair v4->v6"); ++ } + +- nat46debug(1, "[nat46] Could not find a translation pair v4->v6"); + return 0; + } + +@@ -2020,6 +2217,7 @@ static uint16_t xlate_pkt_in_err_v4_to_v + + int nat46_ipv4_input(struct sk_buff *old_skb) { + nat46_instance_t *nat46 = get_nat46_instance(old_skb); ++ nat46_xlate_rulepair_t apair; + struct sk_buff *new_skb; + uint16_t sport = 0, dport = 0, ret = 0; + +@@ -2097,7 +2295,7 @@ int nat46_ipv4_input(struct sk_buff *old + having_l4 = 1; + } + +- if(!pairs_xlate_v4_to_v6_outer(nat46, hdr4, having_l4 ? &sport : NULL, having_l4 ? &dport : NULL, v6saddr, v6daddr)) { ++ if(!pairs_xlate_v4_to_v6_outer(nat46, &apair, hdr4, having_l4 ? &sport : NULL, having_l4 ? &dport : NULL, v6saddr, v6daddr)) { + nat46debug(0, "[nat46] Could not translate v4->v6"); + goto done; + } +--- a/nat46/modules/nat46-core.h ++++ b/nat46/modules/nat46-core.h +@@ -23,6 +23,15 @@ + // #define nat46debug(level, format, ...) + #define nat46debug(level, format, ...) do { if(nat46->debug >= level) { printk(format "\n", ##__VA_ARGS__); } } while (0) + ++#define U8_MASK (uint8_t)(0xFF) ++#define U32_MASK (uint32_t)(~0U) ++#define BITS_PER_BYTE 8 ++#define PSID_LEN_MAX 16 ++#define NUM_RULE_PAIRS_MAX 32 ++#define IPV4_BITS_MAX 32 ++#define EA_LEN_MAX 48 ++#define IPV6_BITS_MAX 128 ++ + #define IPV6HDRSIZE 40 + #define IPV4HDRSIZE 20 + #define IPV6V4HDRDELTA (IPV6HDRSIZE - IPV4HDRSIZE) +@@ -39,6 +48,17 @@ typedef enum { + NAT46_XLATE_RFC6052 + } nat46_xlate_style_t; + ++/* ++ * Enumeration for sorting pairs based on ++ * type of prefix length. ++ */ ++typedef enum { ++ NAT46_IPV4_LOCAL = 0, ++ NAT46_IPV4_REMOTE, ++ NAT46_IPV6_LOCAL, ++ NAT46_IPV6_REMOTE ++} nat46_rule_type_t; ++ + #define NAT46_SIGNATURE 0x544e3634 + #define FREED_NAT46_SIGNATURE 0xdead544e + +@@ -64,7 +84,11 @@ typedef struct { + int debug; + + int npairs; +- nat46_xlate_rulepair_t pairs[0]; /* npairs */ ++ nat46_xlate_rulepair_t pairs[NUM_RULE_PAIRS_MAX]; /* npairs */ ++ nat46_xlate_rulepair_t sorted_ipv4_local_pairs[NUM_RULE_PAIRS_MAX]; /* npairs */ ++ nat46_xlate_rulepair_t sorted_ipv4_remote_pairs[NUM_RULE_PAIRS_MAX]; /* npairs */ ++ nat46_xlate_rulepair_t sorted_ipv6_local_pairs[NUM_RULE_PAIRS_MAX]; /* npairs */ ++ nat46_xlate_rulepair_t sorted_ipv6_remote_pairs[NUM_RULE_PAIRS_MAX]; /* npairs */ + } nat46_instance_t; + + int nat46_ipv6_input(struct sk_buff *old_skb); +--- a/nat46/modules/nat46-netdev.c ++++ b/nat46/modules/nat46-netdev.c +@@ -270,7 +270,14 @@ int nat46_insert(char *devname, char *bu + int ret = -1; + if(dev) { + nat46_instance_t *nat46 = netdev_nat46_instance(dev); +- nat46_instance_t *nat46_new = alloc_nat46_instance(nat46->npairs+1, nat46, 0, 1, -1); ++ nat46_instance_t *nat46_new; ++ ++ if(nat46->npairs == NUM_RULE_PAIRS_MAX) { ++ printk("Could not insert a new rule on device %s\n", devname); ++ return ret; ++ } ++ ++ nat46_new = alloc_nat46_instance(nat46->npairs+1, nat46, 0, 1, -1); + if(nat46_new) { + netdev_nat46_set_instance(dev, nat46_new); + ret = nat46_set_ipair_config(nat46_new, 0, buf, strlen(buf)); diff --git a/package/kernel/nat46/patches/106-dummy_header.patch b/package/kernel/nat46/patches/106-dummy_header.patch new file mode 100644 index 00000000000000..1d4351166fb963 --- /dev/null +++ b/package/kernel/nat46/patches/106-dummy_header.patch @@ -0,0 +1,104 @@ +Author: Pavithra R +Date: Wed Aug 5 10:09:45 2020 +0530 + +nat46: Add dummy fragment header for DF=0 IPv4 packet. + +This patch is propagated from 4.4 kernel commit +b45f19e86ebcc19ea26d5e014bfdcb837148f99e. + +Add dummy fragment header to IPv6 translated packet for +every DF=0 IPv4 packet. + +Change-Id: Id72945eefac030e95e4fd18305e48c46e525def3 +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -1996,6 +1996,27 @@ done: + + + ++/* ++ * Function to get MAP-T rules and flags. ++ */ ++bool nat46_get_info(struct net_device *dev, nat46_xlate_rulepair_t **nat46_rule_pair, ++ int *count, u8 *flag) { ++ if ((!dev) || (!nat46_rule_pair) || (!count) || (!flag)) { ++ return false; ++ } ++ ++ if (!nat46_get_rule_config(dev, nat46_rule_pair, count)) { ++ return false; ++ } ++ ++ /* Check add dummy header flag */ ++ if (add_dummy_header) { ++ *flag = ADD_DUMMY_HEADER; ++ } ++ return true; ++} ++EXPORT_SYMBOL(nat46_get_info); ++ + void ip6_update_csum(struct sk_buff * skb, struct ipv6hdr * ip6hdr, int do_atomic_frag) + { + u32 sum1=0; +@@ -2254,6 +2275,11 @@ int nat46_ipv4_input(struct sk_buff *old + } + hdr4 = ip_hdr(old_skb); + check_for_l4 = 1; ++ if (add_dummy_header) { ++ if (0 == (ntohs(hdr4->frag_off) & IP_DF)) { ++ add_frag_header = 1; ++ } ++ } + } else { + add_frag_header = 1; + if (0 == (ntohs(hdr4->frag_off) & 0x1FFF)) { +--- a/nat46/modules/nat46-core.h ++++ b/nat46/modules/nat46-core.h +@@ -32,6 +32,9 @@ + #define EA_LEN_MAX 48 + #define IPV6_BITS_MAX 128 + ++/* Flag definations for MAP-T */ ++#define ADD_DUMMY_HEADER 0x01 ++ + #define IPV6HDRSIZE 40 + #define IPV4HDRSIZE 20 + #define IPV6V4HDRDELTA (IPV6HDRSIZE - IPV4HDRSIZE) +@@ -110,5 +113,6 @@ int xlate_6_to_4(struct net_device *dev, + int xlate_4_to_6(struct net_device *dev, struct iphdr *hdr4, uint16_t sport, uint16_t dport, void *v6saddr, void *v6daddr); + bool nat46_get_rule_config(struct net_device *dev, nat46_xlate_rulepair_t **nat46_rule_pair, int *count); + int nat46_get_npairs(struct net_device *dev); +- ++bool nat46_get_info(struct net_device *dev, nat46_xlate_rulepair_t **nat46_rule_pair, ++ int *count, u8 *flag); + #endif +--- a/nat46/modules/nat46-module.c ++++ b/nat46/modules/nat46-module.c +@@ -56,12 +56,16 @@ MODULE_AUTHOR("Andrew Yourtchenko +Date: Wed Aug 5 10:57:25 2020 +0530 + +nat46: Add support for 64-bits stats. + +This patch is propagated from 4.4 kernel commit +4a2d1dd9bc9331392c7a4947126c361217c82e0c + +Add 64-bits stats functionality for MAP-T interface. + +Change-Id: I4a6f9c7ed3554ac0ec672aa5fa283be2e95cfdc0 +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-netdev.c ++++ b/nat46/modules/nat46-netdev.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include + #include "nat46-core.h" + #include "nat46-module.h" +@@ -40,16 +41,40 @@ static u8 netdev_count = 0; + + static int nat46_netdev_up(struct net_device *dev); + static int nat46_netdev_down(struct net_device *dev); +- ++static int nat46_netdev_init(struct net_device *dev); ++static void nat46_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *tot); + static netdev_tx_t nat46_netdev_xmit(struct sk_buff *skb, struct net_device *dev); + + + static const struct net_device_ops nat46_netdev_ops = { ++ .ndo_init = nat46_netdev_init, /* device specific initialization */ + .ndo_open = nat46_netdev_up, /* Called at ifconfig nat46 up */ + .ndo_stop = nat46_netdev_down, /* Called at ifconfig nat46 down */ + .ndo_start_xmit = nat46_netdev_xmit, /* REQUIRED, must return NETDEV_TX_OK */ ++ .ndo_get_stats64 = nat46_get_stats64, /* 64 bit device stats */ + }; + ++static int nat46_netdev_init(struct net_device *dev) ++{ ++ int i; ++ dev->tstats = alloc_percpu(struct pcpu_sw_netstats); ++ if (!dev->tstats) { ++ return -ENOMEM; ++ } ++ ++ for_each_possible_cpu(i) { ++ struct pcpu_sw_netstats *ipt_stats; ++ ipt_stats = per_cpu_ptr(dev->tstats, i); ++ u64_stats_init(&ipt_stats->syncp); ++ } ++ return 0; ++} ++ ++static void nat46_netdev_resource_free(struct net_device *dev) ++{ ++ free_percpu(dev->tstats); ++} ++ + static int nat46_netdev_up(struct net_device *dev) + { + netif_start_queue(dev); +@@ -65,9 +90,14 @@ static int nat46_netdev_down(struct net_ + static netdev_tx_t nat46_netdev_xmit(struct sk_buff *skb, struct net_device *dev) + { + int ret = 0; ++ struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats); ++ ++ u64_stats_update_begin(&tstats->syncp); ++ u64_stats_inc(&tstats->rx_packets); ++ u64_stats_add(&tstats->rx_bytes, skb->len); ++ u64_stats_update_end(&tstats->syncp); ++ put_cpu_ptr(tstats); + +- dev->stats.rx_packets++; +- dev->stats.rx_bytes += skb->len; + if(ETH_P_IP == ntohs(skb->protocol)) { + ret = nat46_ipv4_input(skb); + } +@@ -81,22 +111,39 @@ static netdev_tx_t nat46_netdev_xmit(str + } + + void nat46_netdev_count_xmit(struct sk_buff *skb, struct net_device *dev) { +- dev->stats.tx_packets++; +- dev->stats.tx_bytes += skb->len; ++ struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats); ++ ++ u64_stats_update_begin(&tstats->syncp); ++ u64_stats_inc(&tstats->tx_packets); ++ u64_stats_add(&tstats->tx_bytes, skb->len); ++ u64_stats_update_end(&tstats->syncp); ++ put_cpu_ptr(tstats); + } + + void nat46_update_stats(struct net_device *dev, uint32_t rx_packets, uint32_t rx_bytes, + uint32_t tx_packets, uint32_t tx_bytes, uint32_t rx_dropped, uint32_t tx_dropped) + { +- dev->stats.rx_packets += rx_packets; +- dev->stats.rx_bytes += rx_bytes; +- dev->stats.tx_packets += tx_packets; +- dev->stats.tx_bytes += tx_bytes; ++ struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats); ++ ++ u64_stats_update_begin(&tstats->syncp); ++ u64_stats_add(&tstats->rx_packets, rx_packets); ++ u64_stats_add(&tstats->rx_bytes, rx_bytes); ++ u64_stats_add(&tstats->tx_packets, tx_packets); ++ u64_stats_add(&tstats->tx_bytes, tx_bytes); + dev->stats.rx_dropped += rx_dropped; + dev->stats.tx_dropped += tx_dropped; ++ u64_stats_update_end(&tstats->syncp); ++ put_cpu_ptr(tstats); + } + EXPORT_SYMBOL(nat46_update_stats); + ++static void nat46_get_stats64(struct net_device *dev, ++ struct rtnl_link_stats64 *tot) ++{ ++ netdev_stats_to_stats64(tot, &dev->stats); ++ dev_fetch_sw_netstats(tot, dev->tstats); ++} ++ + void *netdev_nat46_instance(struct net_device *dev) { + nat46_netdev_priv_t *priv = netdev_priv(dev); + return priv->nat46; +@@ -120,6 +167,7 @@ static void nat46_netdev_setup(struct ne + priv->nat46 = nat46; + + dev->netdev_ops = &nat46_netdev_ops; ++ dev->priv_destructor = nat46_netdev_resource_free; + dev->type = ARPHRD_NONE; + dev->hard_header_len = 0; + dev->addr_len = 0; diff --git a/package/kernel/nat46/patches/108-ce_port.patch b/package/kernel/nat46/patches/108-ce_port.patch new file mode 100644 index 00000000000000..ab6ab37b986e07 --- /dev/null +++ b/package/kernel/nat46/patches/108-ce_port.patch @@ -0,0 +1,134 @@ +Author: Pavithra R +Date: Wed Aug 5 18:59:20 2020 +0530 + +nat46: Copy CE's port number to IPv6 fragment header. + +This patch is propagated from kernel 4.4 commit +7886fd3eb081c7767b02685593bc1d19deaecba8 + +Copy CE's port number to the lower 16-bits of IPv6 identification +number. + +Change-Id: I6946e93bf8bed4c1378d19e75db0729097e0d9eb +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -31,6 +31,7 @@ + + static uint16_t xlate_pkt_in_err_v4_to_v6(nat46_instance_t *nat46, struct iphdr *iph, + struct sk_buff *old_skb, uint16_t *sport, uint16_t *dport); ++static DEFINE_SPINLOCK(port_id_lock); + + void + nat46debug_dump(nat46_instance_t *nat46, int level, void *addr, int len) +@@ -2236,6 +2237,73 @@ static uint16_t xlate_pkt_in_err_v4_to_v + return 1; + } + ++/* Return the port number from CE's port set */ ++static uint16_t nat46_get_ce_port(nat46_xlate_rulepair_t *pair, uint16_t sport) ++{ ++ /* ++ * 'psid_bits_len' represents number of bits in PSID. ++ * 'offset' represents offset of PSID in a port number. ++ */ ++ uint8_t psid_bits_len, offset, port_set_bitmask; ++ ++ /* ++ * 'psid16' represent PSID value. ++ * 'm' represents number of bits in excluded port set. ++ * 'a' represents number of bits in a 16-bit port number after PSID. ++ * It is used to control number of port in one contiguous port set. ++ * ++ * Name of a variable 'a' and 'm' is as per Appendix B of [RFC7597]. ++ */ ++ uint16_t psid16, value, m, a; ++ nat46_xlate_rule_t *rule; ++ ++ /* stores to last port number from CE's port set */ ++ static uint16_t port_num; ++ ++ rule = &pair->local; ++ offset = rule->psid_offset; ++ ++ if (rule->ea_len + rule->v4_pref_len > IPV4_BITS_MAX) { ++ psid_bits_len = rule->ea_len - (IPV4_BITS_MAX - rule->v4_pref_len); ++ } else { ++ return 0; ++ } ++ a = PSID_LEN_MAX - offset - psid_bits_len; ++ psid16 = (ntohs(sport) >> a) & (0xffff >> (PSID_LEN_MAX - psid_bits_len)); ++ ++ spin_lock(&port_id_lock); ++ ++ /* Start case */ ++ if (0 == port_num) { ++ m = (offset) ? 1 : 0; ++ port_num = (m << (PSID_LEN_MAX - offset)) | (psid16 << a); ++ value = port_num; ++ spin_unlock(&port_id_lock); ++ return value; ++ } ++ ++ /* End of one port set */ ++ port_set_bitmask = (1 << a) - 1; ++ value = port_num & port_set_bitmask; ++ if (0 == (value ^ port_set_bitmask)) { ++ m = port_num >> (PSID_LEN_MAX - offset); ++ m++; ++ /* End case */ ++ if (m >= (1 << offset)) { ++ m = (offset) ? 1 : 0; ++ } ++ port_num = (m << (PSID_LEN_MAX - offset)) | (psid16 << a); ++ value = port_num; ++ spin_unlock(&port_id_lock); ++ return value; ++ } ++ ++ port_num++; ++ value = port_num; ++ spin_unlock(&port_id_lock); ++ return value; ++} ++ + int nat46_ipv4_input(struct sk_buff *old_skb) { + nat46_instance_t *nat46 = get_nat46_instance(old_skb); + nat46_xlate_rulepair_t apair; +@@ -2368,9 +2436,34 @@ int nat46_ipv4_input(struct sk_buff *old + + if (add_frag_header) { + struct frag_hdr *fh = (struct frag_hdr*)(hdr6 + 1); ++ uint16_t ce_port_num = 0; ++ ++ /* Flag to represent whether PSID is assigned to MAP-T node or not */ ++ bool is_psid = false; ++ + fh->frag_off = htons(((ntohs(hdr4->frag_off) >> 13) & 7) + ((ntohs(hdr4->frag_off) & 0x1FFF) << 3)); + fh->nexthdr = hdr4->protocol; +- fh->identification = htonl(ntohs(hdr4->id)); ++ ++ /* ++ * PSID assigned MAP-T node will have non-zero ea_len and we are currently ++ * only supporting NAT46_XLATE_MAP as the CE's rule style. ++ */ ++ is_psid = (apair.local.style == NAT46_XLATE_MAP) && apair.local.ea_len; ++ if (is_psid) { ++ ce_port_num = nat46_get_ce_port(nat46->pairs, sport); ++ nat46debug(10, "\n ce port number is %02x\n", ce_port_num); ++ ++ /* Assign CE's port number as the fragment identifier */ ++ if (ce_port_num) { ++ fh->identification = htonl(ce_port_num); ++ } else { ++ fh->identification = htonl(ntohs(hdr4->id)); ++ } ++ } else { ++ fh->identification = htonl(ntohs(hdr4->id)); ++ } ++ ++ + } + ip6_update_csum(new_skb, hdr6, add_frag_header); + diff --git a/package/kernel/nat46/patches/109-fragment_if_not_df_and_larger_than_mtu.patch b/package/kernel/nat46/patches/109-fragment_if_not_df_and_larger_than_mtu.patch new file mode 100644 index 00000000000000..333228a97496c3 --- /dev/null +++ b/package/kernel/nat46/patches/109-fragment_if_not_df_and_larger_than_mtu.patch @@ -0,0 +1,30 @@ +Author: Pavithra R +Date: Wed Aug 5 19:26:48 2020 +0530 + +nat46: Fix the issue of packets not fragmented + +This patch is propagated from the kernel 4.4 commit +e598f9c249092abd7c7978fe99b6690884f225c9 + +when packets size is larger than the MTU of dst, if DF flag is not set, +fragment it instead of dropping it with PktTooBig ICMPv6 message. + +Change-Id: I380d42f59bb4f46a45e542f251f5710f2cca8b62 +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -2343,10 +2343,11 @@ int nat46_ipv4_input(struct sk_buff *old + } + hdr4 = ip_hdr(old_skb); + check_for_l4 = 1; +- if (add_dummy_header) { +- if (0 == (ntohs(hdr4->frag_off) & IP_DF)) { ++ if (0 == (ntohs(hdr4->frag_off) & IP_DF)) { ++ if (add_dummy_header) { + add_frag_header = 1; + } ++ old_skb->ignore_df = 1; + } + } else { + add_frag_header = 1; diff --git a/package/kernel/nat46/patches/110-icmp_error_not_handled.patch b/package/kernel/nat46/patches/110-icmp_error_not_handled.patch new file mode 100644 index 00000000000000..5697c609732ccf --- /dev/null +++ b/package/kernel/nat46/patches/110-icmp_error_not_handled.patch @@ -0,0 +1,100 @@ +Author: Pavithra R +Date: Wed Aug 5 20:16:27 2020 +0530 + +nat46: fix ICMPv6 error message dropped locally + +This patch is propagated from the kernel 4.4 commit +1b96bd0e9ee9182566b119741854c03bf4b94a99 + +While routing IPv6 packets from a customer-side translated device (CLAT) +to a provider-side translated device (PLAT), it is possible that the IPv6 +destination is unknown. In such a scenario, the IPv6 stack must send back +an ICMP error. However, the source IPv6 address of this error message does +not have a MAP-T translation. According to RFC2473, the translation layer +should use the tunnel's own IPv4 address for the IPv6 ICMP packet's source +address. + +Change-Id: I784473cddf9214843c466d10763cb66852139ef6 +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -1782,11 +1782,12 @@ static uint16_t nat46_fixup_icmp(nat46_i + return ret; + } + +-int pairs_xlate_v6_to_v4_outer(nat46_instance_t *nat46, nat46_xlate_rulepair_t *apair, ++int pairs_xlate_v6_to_v4_outer(nat46_instance_t *nat46, nat46_xlate_rulepair_t **papair, + struct ipv6hdr *ip6h, uint16_t proto, __u32 *pv4saddr, __u32 *pv4daddr) { + int ipair = 0; + int xlate_src = -1; + int xlate_dst = -1; ++ nat46_xlate_rulepair_t *apair; + + for(ipair = 0; ipair < nat46->npairs; ipair++) { + apair = nat46_lpm(nat46, NAT46_IPV6_REMOTE, &ip6h->saddr); +@@ -1794,6 +1795,7 @@ int pairs_xlate_v6_to_v4_outer(nat46_ins + return 0; + } + ++ *papair = apair; + if (xlate_v6_to_v4(nat46, &apair->local, &ip6h->daddr, pv4daddr)) { + nat46debug(5, "Dst addr %pI6 to %pI4 \n", &ip6h->daddr, pv4daddr); + xlate_dst = ipair; +@@ -1822,14 +1824,14 @@ int pairs_xlate_v6_to_v4_outer(nat46_ins + } + + int xlate_6_to_4(struct net_device *dev, struct ipv6hdr *ip6h, uint16_t proto, __u32 *pv4saddr, __u32 *pv4daddr) { +- nat46_xlate_rulepair_t apair; ++ nat46_xlate_rulepair_t *apair; + return pairs_xlate_v6_to_v4_outer(netdev_nat46_instance(dev), &apair, ip6h, proto, pv4saddr, pv4daddr); + } + EXPORT_SYMBOL(xlate_6_to_4); + + int nat46_ipv6_input(struct sk_buff *old_skb) { + struct ipv6hdr *ip6h = ipv6_hdr(old_skb); +- nat46_xlate_rulepair_t apair; ++ nat46_xlate_rulepair_t *apair; + nat46_instance_t *nat46 = get_nat46_instance(old_skb); + uint16_t proto; + uint16_t frag_off; +@@ -1903,8 +1905,37 @@ int nat46_ipv6_input(struct sk_buff *old + } + + if (!pairs_xlate_v6_to_v4_outer(nat46, &apair, ip6h, proto, &v4saddr, &v4daddr)) { +- nat46debug(0, "[nat46] Could not translate v6->v4"); +- goto done; ++ if (proto == NEXTHDR_ICMP) { ++ struct icmp6hdr *icmp6h = add_offset(ip6h, v6packet_l3size); ++ struct ipv6hdr *ip6h_inner = (struct ipv6hdr *) (icmp6h + 1); ++ struct ipv6hdr hdr6; ++ switch(icmp6h->icmp6_type) { ++ case ICMPV6_DEST_UNREACH: ++ case ICMPV6_PKT_TOOBIG: ++ case ICMPV6_TIME_EXCEED: ++ case ICMPV6_PARAMPROB: ++ /* ++ * For icmpv6 error message, using the original message ++ * address to locate the apair one more time according ++ * to the RFC 2473, and use the ipv4 address of the ++ * tunnel as SRC ipv4 address ++ */ ++ memcpy(&hdr6.saddr, &ip6h_inner->daddr, 16); ++ memcpy(&hdr6.daddr, &ip6h_inner->saddr, 16); ++ if (!pairs_xlate_v6_to_v4_outer(nat46, &apair, &hdr6, proto, &v4saddr, &v4daddr)) { ++ nat46debug(0, "[nat46] Could not translate v6->v4"); ++ goto done; ++ } ++ v4saddr = apair->local.v4_pref; ++ break; ++ default: ++ nat46debug(0, "[nat46] Could not translate v6->v4"); ++ goto done; ++ } ++ } else { ++ nat46debug(0, "[nat46] Could not translate v6->v4"); ++ goto done; ++ } + } + + if (check_for_l4) { diff --git a/package/kernel/nat46/patches/111-fix_null_point_reference.patch b/package/kernel/nat46/patches/111-fix_null_point_reference.patch new file mode 100644 index 00000000000000..4cef9db199d639 --- /dev/null +++ b/package/kernel/nat46/patches/111-fix_null_point_reference.patch @@ -0,0 +1,40 @@ +Author: Pavithra R +Date: Wed Aug 5 20:35:00 2020 +0530 + +nat46: Fix null pointer dereference issue + +This patch is propagated from the kernel 4.4 commit +5bdf9bd5500c45ab5a3fd43e60c40a09d5e5a13d + +get_nat46_instance possibly returns null point, before using the returning +point, caller needs to check if it is null. + +Change-Id: Id407a71ca8eccd60a713c34429e7e3f16e2cdd12 +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -1847,6 +1847,11 @@ int nat46_ipv6_input(struct sk_buff *old + int l3_infrag_payload_len = ntohs(ip6h->payload_len); + int check_for_l4 = 0; + ++ if (nat46 == NULL) { ++ printk("nat46:%p skb is dropped for no valid instance found\n", old_skb); ++ return err; ++ } ++ + nat46debug(4, "nat46_ipv6_input packet"); + + if(ip6_input_not_interested(nat46, ip6h, old_skb)) { +@@ -2353,6 +2358,11 @@ int nat46_ipv4_input(struct sk_buff *old + + char v6saddr[16], v6daddr[16]; + ++ if (nat46 == NULL) { ++ printk("nat46:%p skb is dropped for no valid instance found\n", old_skb); ++ return err; ++ } ++ + memset(v6saddr, 1, 16); + memset(v6daddr, 2, 16); + diff --git a/package/kernel/nat46/patches/112-fix_icmp_crash.patch b/package/kernel/nat46/patches/112-fix_icmp_crash.patch new file mode 100644 index 00000000000000..5d34697a45b84d --- /dev/null +++ b/package/kernel/nat46/patches/112-fix_icmp_crash.patch @@ -0,0 +1,40 @@ +Author: Pavithra R +Date: Wed Aug 5 20:57:33 2020 +0530 + +Fix crash of free skb + +This patch is propagated from the 4.4 kernel commit +b959b0d45c66ae004a5bfc1687980093fa5b8cc3. + +This is caused by the translation of the inner ipv6 header, it +move memory by the inner head's tot_len which is not exact that +inner packet will be trimmed for icmp error packets size no more +than 576. + +Change-Id: Id5d41fa0721acdf6ea76721c45415fe3be432207 +Signed-off-by: Pavithra R + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -2245,7 +2245,9 @@ static uint16_t xlate_pkt_in_err_v4_to_v + + if (skb_tailroom(old_skb) >= IPV6V4HDRDELTA){ + skb_put(old_skb, IPV6V4HDRDELTA); +- memmove(((char *)iiph + IPV6HDRSIZE), (iiph + 1), ntohs(iiph->tot_len) - IPV4HDRSIZE); ++ /* ErrorICMP size is less than 576, the inner ipv4 packet will be trimmed */ ++ memmove(((char *)iiph + IPV6HDRSIZE), (iiph + 1), ++ ntohs(iph->tot_len) - 2 * IPV4HDRSIZE - sizeof(struct icmphdr)); + memcpy(iiph, &ip6h, IPV6HDRSIZE); + } + else { +@@ -2258,7 +2260,9 @@ static uint16_t xlate_pkt_in_err_v4_to_v + + skb_put(old_skb, IPV6V4HDRDELTA); + iiph = (struct iphdr *)(icmp_hdr(old_skb) + 1); +- memmove(((char *)iiph + IPV6HDRSIZE), (iiph + 1), ntohs(iiph->tot_len) - IPV4HDRSIZE); ++ /* ErrorICMP size is less than 576, the inner ipv4 packet will be trimmed */ ++ memmove(((char *)iiph + IPV6HDRSIZE), (iiph + 1), ++ ntohs(iph->tot_len) - 2 * IPV4HDRSIZE - sizeof(struct icmphdr)); + memcpy(iiph, &ip6h, IPV6HDRSIZE); + nat46 = get_nat46_instance(old_skb); + iph = ip_hdr(old_skb); diff --git a/package/kernel/nat46/patches/116-rate-limit-the-print.patch b/package/kernel/nat46/patches/116-rate-limit-the-print.patch new file mode 100644 index 00000000000000..d857d0e6cb0a05 --- /dev/null +++ b/package/kernel/nat46/patches/116-rate-limit-the-print.patch @@ -0,0 +1,34 @@ +Author: Pavithra R +Date: Wed Sep 30 14:05:50 2020 +0530 + +nat46: Add rate limit to a print. + +This patch is propagated from the kernel 4.4 commit +d47f62508d2c105f236470e56bedbe279db0e6f1 + +Change-Id: I2119fbe54d630c3ed39535f1cb1b8a0d9d3199b4 +Signed-off-by: Pavithra R +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -1928,7 +1928,9 @@ int nat46_ipv6_input(struct sk_buff *old + memcpy(&hdr6.saddr, &ip6h_inner->daddr, 16); + memcpy(&hdr6.daddr, &ip6h_inner->saddr, 16); + if (!pairs_xlate_v6_to_v4_outer(nat46, &apair, &hdr6, proto, &v4saddr, &v4daddr)) { +- nat46debug(0, "[nat46] Could not translate v6->v4"); ++ if (net_ratelimit()) { ++ nat46debug(0, "[nat46] Could not translate v6->v4"); ++ } + goto done; + } + v4saddr = apair->local.v4_pref; +@@ -2436,7 +2438,9 @@ int nat46_ipv4_input(struct sk_buff *old + } + + if(!pairs_xlate_v4_to_v6_outer(nat46, &apair, hdr4, having_l4 ? &sport : NULL, having_l4 ? &dport : NULL, v6saddr, v6daddr)) { +- nat46debug(0, "[nat46] Could not translate v4->v6"); ++ if (net_ratelimit()) { ++ nat46debug(0, "[nat46] Could not translate v4->v6"); ++ } + goto done; + } + diff --git a/package/kernel/nat46/patches/117-fix-icmp-no-payload-bug.patch b/package/kernel/nat46/patches/117-fix-icmp-no-payload-bug.patch new file mode 100644 index 00000000000000..a8bff4a945457c --- /dev/null +++ b/package/kernel/nat46/patches/117-fix-icmp-no-payload-bug.patch @@ -0,0 +1,34 @@ +Author: Pavithra R +Date: Wed Sep 30 14:27:37 2020 +0530 + +nat46: Fix for ICMP error packets with no payload. + +This patch is propagated from the kernel 4.4 commit +d8b29a8e31f948a5d7338aa69c36e0f654fcb9e4 + +When no payload is attached to the original packet, any +ICMP error message generated in response to such packets +gets dropped due to malformed packet at CE. + +During the translation of packet-in-error in ICMP, +the IPv6 header in ICMPv6 payload gets corrupted. +Hence, the translated packet gets dropped at CE. + +This fix updates the outer IPv4 header's total length +before translating to IPv6 header. + +Change-Id: Ifd9802afb50771de39b4c6fb734d36b0801613ec +Signed-off-by: Pavithra R +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -2266,9 +2266,8 @@ static uint16_t xlate_pkt_in_err_v4_to_v + memmove(((char *)iiph + IPV6HDRSIZE), (iiph + 1), + ntohs(iph->tot_len) - 2 * IPV4HDRSIZE - sizeof(struct icmphdr)); + memcpy(iiph, &ip6h, IPV6HDRSIZE); +- nat46 = get_nat46_instance(old_skb); +- iph = ip_hdr(old_skb); + } ++ iph->tot_len = htons(ntohs(iph->tot_len) + IPV6V4HDRDELTA); + + /* Swapping Ports for outer header */ + /* Another work-around till LPM is not present. */ diff --git a/package/kernel/nat46/patches/118-performance_fix.patch b/package/kernel/nat46/patches/118-performance_fix.patch new file mode 100644 index 00000000000000..5de4906ef99f7f --- /dev/null +++ b/package/kernel/nat46/patches/118-performance_fix.patch @@ -0,0 +1,415 @@ +Author: Suruchi Agarwal +Date: Fri Dec 17 13:37:15 2021 -0800 + + nat46: Performance fix + + Avoid allocating new skb and copy for map-t translation + + Change-Id: I621b90609b4642d64b6e4cfb98b105b3fcbb0365 + Signed-off-by: Suruchi Agarwal + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -118,7 +118,7 @@ char *get_next_arg(char **ptail) { + return pc; + } + +-/* ++/* + * Parse an IPv6 address (if pref_len is NULL), or prefix (if it isn't). + * parses destructively (places \0 between address and prefix len) + */ +@@ -163,7 +163,7 @@ int try_parse_ipv4_prefix(u32 *v4addr, i + } + + +-/* ++/* + * parse a rule argument and put config into a rule. + * advance the tail to prepare for the next arg parsing. + * destructive. +@@ -384,7 +384,7 @@ char *xlate_style_to_string(nat46_xlate_ + return "unknown"; + } + +-/* ++/* + * Get the nat46 configuration into a supplied buffer (if non-null). + */ + int nat46_get_ipair_config(nat46_instance_t *nat46, int ipair, char *buf, int count) { +@@ -985,6 +985,28 @@ __sum16 csum_ipv6_unmagic(nat46_instance + return csum; + } + ++/* Update UDP with incremental checksum */ ++__sum16 csum_ipv6_udp_remagic(struct ipv6hdr *ip6hdr, u32 csum) { ++ uint32_t sum; ++ sum = csum_partial(ip6hdr->saddr.s6_addr16, 2 * sizeof(ip6hdr->saddr), ~csum); ++ sum = ((sum >> 16) & 0xffff) + (sum & 0xffff); ++ sum += ((sum >> 16) & 0xffff); ++ return (u16)(~sum); ++} ++ ++/* Undo the IPv4 pseudoheader inclusion into the checksum */ ++__sum16 csum_ipv4_unmagic(__be32 saddr, __be32 daddr, ++ u32 csum) { ++ u32 s; ++ uint32_t addr_csum; ++ csum = ntohs(~csum); ++ addr_csum = (saddr & 0xffff) + (saddr >> 16) + (daddr & 0xffff) + (daddr >> 16); ++ s= csum + ntohs(~addr_csum); ++ s = ((s >> 16) & 0xffff) + (s & 0xffff); ++ s += ((s >> 16) & 0xffff); ++ return htons((u16)(~s)); ++} ++ + /* Update ICMPv6 type/code with incremental checksum adjustment */ + void update_icmp6_type_code(nat46_instance_t *nat46, struct icmp6hdr *icmp6h, u8 type, u8 code) { + u16 old_tc = *((u16 *)icmp6h); +@@ -1038,9 +1060,8 @@ void fill_v6hdr_from_v4hdr(struct iphdr + ip6h->hop_limit = iph->ttl; + } + +-void fill_v4hdr_from_v6hdr(struct iphdr * iph, struct ipv6hdr *ip6h, __u32 v4saddr, __u32 v4daddr, __u16 id, __u16 frag_off, __u16 proto, int l3_payload_len) { +- uint32_t ver_class_flow = ntohl(*(__be32 *)ip6h); +- iph->ttl = ip6h->hop_limit; ++void fill_v4hdr_from_v6hdr(struct iphdr * iph, uint32_t ver_class_flow, uint8_t hop_limit, __u32 v4saddr, __u32 v4daddr, __u16 id, __u16 frag_off, __u16 proto, int l3_payload_len) { ++ iph->ttl = hop_limit; + iph->saddr = v4saddr; + iph->daddr = v4daddr; + iph->protocol = proto; +@@ -1198,6 +1219,8 @@ void pairs_xlate_v6_to_v4_inner(nat46_in + */ + int xlate_payload6_to4(nat46_instance_t *nat46, void *pv6, void *ptrans_hdr, int v6_len, u16 *ul_sum, int *ptailTruncSize) { + struct ipv6hdr *ip6h = pv6; ++ uint32_t ver_class_flow; ++ uint8_t hop_limit; + __u32 v4saddr, v4daddr; + struct iphdr new_ipv4; + struct iphdr *iph = &new_ipv4; +@@ -1274,7 +1297,10 @@ int xlate_payload6_to4(nat46_instance_t + } + } + +- fill_v4hdr_from_v6hdr(iph, ip6h, v4saddr, v4daddr, ipid, ipflags, proto, infrag_payload_len); ++ ver_class_flow = ntohl(*(__be32 *)ip6h); ++ hop_limit = ip6h->hop_limit; ++ ++ fill_v4hdr_from_v6hdr(iph, ver_class_flow, hop_limit, v4saddr, v4daddr, ipid, ipflags, proto, infrag_payload_len); + if(ul_sum) { + *ul_sum = unchecksum16(pv6, (((u8 *)ptrans_hdr)-((u8 *)pv6))/2, *ul_sum); + *ul_sum = rechecksum16(iph, 10, *ul_sum); +@@ -1831,6 +1857,8 @@ EXPORT_SYMBOL(xlate_6_to_4); + + int nat46_ipv6_input(struct sk_buff *old_skb) { + struct ipv6hdr *ip6h = ipv6_hdr(old_skb); ++ uint32_t ver_class_flow; ++ uint8_t hop_limit; + nat46_xlate_rulepair_t *apair; + nat46_instance_t *nat46 = get_nat46_instance(old_skb); + uint16_t proto; +@@ -1839,22 +1867,20 @@ int nat46_ipv6_input(struct sk_buff *old + + struct iphdr * iph; + __u32 v4saddr, v4daddr; +- struct sk_buff * new_skb = 0; + int err = 0; +- int truncSize = 0; + int tailTruncSize = 0; + int v6packet_l3size = sizeof(*ip6h); + int l3_infrag_payload_len = ntohs(ip6h->payload_len); + int check_for_l4 = 0; + +- if (nat46 == NULL) { ++ if (unlikely(nat46 == NULL)) { + printk("nat46:%p skb is dropped for no valid instance found\n", old_skb); + return err; + } + + nat46debug(4, "nat46_ipv6_input packet"); + +- if(ip6_input_not_interested(nat46, ip6h, old_skb)) { ++ if(unlikely(ip6_input_not_interested(nat46, ip6h, old_skb))) { + nat46debug(1, "nat46_ipv6_input not interested"); + goto done; + } +@@ -1985,47 +2011,45 @@ int nat46_ipv6_input(struct sk_buff *old + } + } + +- new_skb = skb_copy(old_skb, GFP_ATOMIC); // other possible option: GFP_ATOMIC +- if (!new_skb) { +- nat46debug(0, "[nat46] Could not copy v6 skb"); +- goto done; +- } ++ ver_class_flow = ntohl(*(__be32 *)ip6h); ++ hop_limit = ip6h->hop_limit; + + /* Remove any debris in the socket control block */ +- memset(IPCB(new_skb), 0, sizeof(struct inet_skb_parm)); ++ memset(IPCB(old_skb), 0, sizeof(struct inet_skb_parm)); ++ + /* Remove netfilter references to IPv6 packet, new netfilter references will be created based on IPv4 packet */ + #if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) +- nf_reset(new_skb); ++ nf_reset(old_skb); + #else +- skb_ext_reset(new_skb); +- nf_reset_ct(new_skb); ++ skb_ext_reset(old_skb); ++ nf_reset_ct(old_skb); + #endif + + /* modify packet: actual IPv6->IPv4 transformation */ +- truncSize = v6packet_l3size - sizeof(struct iphdr); /* chop first 20 bytes */ +- skb_pull(new_skb, truncSize); +- skb_put(new_skb, -tailTruncSize); ++ skb_pull(old_skb, sizeof(struct iphdr)); + l3_infrag_payload_len -= tailTruncSize; +- skb_reset_network_header(new_skb); +- skb_set_transport_header(new_skb,IPV4HDRSIZE); /* transport (TCP/UDP/ICMP/...) header starts after 20 bytes */ ++ skb_reset_mac_header(old_skb); ++ skb_reset_network_header(old_skb); ++ skb_set_transport_header(old_skb,IPV4HDRSIZE); /* transport (TCP/UDP/ICMP/...) header starts after 20 bytes */ + + /* build IPv4 header */ +- iph = ip_hdr(new_skb); +- fill_v4hdr_from_v6hdr(iph, ip6h, v4saddr, v4daddr, frag_id, frag_off, proto, l3_infrag_payload_len); +- new_skb->protocol = htons(ETH_P_IP); ++ iph = ip_hdr(old_skb); ++ fill_v4hdr_from_v6hdr(iph, ver_class_flow, hop_limit, v4saddr, v4daddr, frag_id, frag_off, proto, l3_infrag_payload_len); ++ old_skb->protocol = htons(ETH_P_IP); + + if (ntohs(iph->tot_len) >= 2000) { + nat46debug(0, "Too big IP len: %d", ntohs(iph->tot_len)); + } + +- nat46debug(5, "about to send v4 packet, flags: %02x", IPCB(new_skb)->flags); +- nat46_netdev_count_xmit(new_skb, old_skb->dev); ++ nat46debug(5, "about to send v4 packet, flags: %02x", IPCB(old_skb)->flags); ++ nat46_netdev_count_xmit(old_skb, old_skb->dev); + +- /* set skb->iif */ +- new_skb->skb_iif = old_skb->skb_iif; +- +- netif_rx(new_skb); ++ netif_rx(old_skb); + ++ /* ++ * skb was consumed in the ipv4 format, don't release later. ++ */ ++ err = 1; + /* TBD: should copy be released here? */ + + done: +@@ -2056,7 +2080,7 @@ bool nat46_get_info(struct net_device *d + } + EXPORT_SYMBOL(nat46_get_info); + +-void ip6_update_csum(struct sk_buff * skb, struct ipv6hdr * ip6hdr, int do_atomic_frag) ++void ip6_update_csum(struct sk_buff * skb, struct ipv6hdr * ip6hdr, uint32_t v4saddr, uint32_t v4daddr, int do_atomic_frag) + { + u32 sum1=0; + u16 sum2=0; +@@ -2079,12 +2103,13 @@ void ip6_update_csum(struct sk_buff * sk + struct udphdr *udp = udp_hdr(skb); + unsigned udplen = ntohs(ip6hdr->payload_len) - (do_atomic_frag?8:0); /* UDP hdr + payload */ + +- oldsum = udp->check; +- udp->check = 0; +- +- sum1 = csum_partial((char*)udp, udplen, 0); /* calculate checksum for UDP hdr+payload */ +- sum2 = csum_ipv6_magic(&ip6hdr->saddr, &ip6hdr->daddr, udplen, ip6hdr->nexthdr, sum1); /* add pseudoheader */ +- ++ if (!udp->check) { ++ sum1 = csum_partial((char*)udp, udplen, 0); /* calculate checksum for UDP hdr+payload */ ++ sum2 = csum_ipv6_magic(&ip6hdr->saddr, &ip6hdr->daddr, udplen, ip6hdr->nexthdr, sum1); /* add pseudoheader */ ++ } else { ++ sum1 = csum_ipv4_unmagic(v4saddr, v4daddr, udp->check); ++ sum2 = csum_ipv6_udp_remagic(ip6hdr, sum1); ++ } + udp->check = sum2; + + break; +@@ -2348,7 +2373,6 @@ static uint16_t nat46_get_ce_port(nat46_ + int nat46_ipv4_input(struct sk_buff *old_skb) { + nat46_instance_t *nat46 = get_nat46_instance(old_skb); + nat46_xlate_rulepair_t apair; +- struct sk_buff *new_skb; + uint16_t sport = 0, dport = 0, ret = 0; + + int err = 0; +@@ -2360,10 +2384,15 @@ int nat46_ipv4_input(struct sk_buff *old + + struct ipv6hdr * hdr6; + struct iphdr * hdr4 = ip_hdr(old_skb); ++ uint32_t v4saddr, v4daddr; ++ uint8_t ttl; ++ uint16_t tot_len; ++ uint8_t protocol; ++ uint16_t frag_off, id; + + char v6saddr[16], v6daddr[16]; + +- if (nat46 == NULL) { ++ if (unlikely(nat46 == NULL)) { + printk("nat46:%p skb is dropped for no valid instance found\n", old_skb); + return err; + } +@@ -2443,31 +2472,39 @@ int nat46_ipv4_input(struct sk_buff *old + goto done; + } + +- new_skb = skb_copy(old_skb, GFP_ATOMIC); +- if (!new_skb) { +- nat46debug(0, "[nat46] Could not copy v4 skb"); +- goto done; +- } ++ v4saddr = hdr4->saddr; ++ v4daddr = hdr4->daddr; ++ protocol = hdr4->protocol; ++ tot_len = hdr4->tot_len; ++ ttl = hdr4->ttl; ++ frag_off = hdr4->frag_off; ++ id = hdr4->id; + + /* Remove any debris in the socket control block */ +- memset(IP6CB(new_skb), 0, sizeof(struct inet6_skb_parm)); ++ memset(IP6CB(old_skb), 0, sizeof(struct inet6_skb_parm)); + /* Remove netfilter references to IPv4 packet, new netfilter references will be created based on IPv6 packet */ + #if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) +- nf_reset(new_skb); ++ nf_reset(old_skb); + #else +- skb_ext_reset(new_skb); +- nf_reset_ct(new_skb); ++ skb_ext_reset(old_skb); ++ nf_reset_ct(old_skb); + #endif + + /* expand header (add 20 extra bytes at the beginning of sk_buff) */ +- pskb_expand_head(new_skb, IPV6HDRSIZE - (hdr4->ihl << 2) + (add_frag_header?8:0), 0, GFP_ATOMIC); ++ if (skb_headroom(old_skb) < IPV6V4HDRDELTA) { ++ ret = pskb_expand_head(old_skb, IPV6V4HDRDELTA + (add_frag_header?8:0), 0, GFP_ATOMIC); ++ if (unlikely(ret)) { ++ nat46debug(0, "[nat46] Could not expand skb header"); ++ goto done; ++ } ++ } + +- skb_push(new_skb, IPV6HDRSIZE - (hdr4->ihl << 2) + (add_frag_header?8:0)); /* push boundary by extra 20 bytes */ ++ skb_push(old_skb, IPV6HDRSIZE - (hdr4->ihl << 2) + (add_frag_header?8:0)); /* push boundary by extra 20 bytes */ + +- skb_reset_network_header(new_skb); +- skb_set_transport_header(new_skb, IPV6HDRSIZE + (add_frag_header?8:0) ); /* transport (TCP/UDP/ICMP/...) header starts after 40 bytes */ ++ skb_reset_network_header(old_skb); ++ skb_set_transport_header(old_skb, IPV6HDRSIZE + (add_frag_header?8:0) ); /* transport (TCP/UDP/ICMP/...) header starts after 40 bytes */ + +- hdr6 = ipv6_hdr(new_skb); ++ hdr6 = ipv6_hdr(old_skb); + memset(hdr6, 0, sizeof(*hdr6) + (add_frag_header?8:0)); + + /* build IPv6 header */ +@@ -2475,13 +2512,14 @@ int nat46_ipv4_input(struct sk_buff *old + *(__be32 *)hdr6 = htonl(0x60000000 | (tclass << 20)) | flowlabel; /* version, priority, flowlabel */ + + /* IPv6 length is a payload length, IPv4 is hdr+payload */ +- hdr6->payload_len = htons(ntohs(hdr4->tot_len) - (hdr4->ihl << 2) + (add_frag_header?8:0)); +- hdr6->nexthdr = hdr4->protocol; +- hdr6->hop_limit = hdr4->ttl; ++ hdr6->payload_len = htons(ntohs(tot_len) - sizeof(struct iphdr) + (add_frag_header?8:0)); ++ hdr6->nexthdr = protocol; ++ hdr6->hop_limit = ttl; ++ + memcpy(&hdr6->saddr, v6saddr, 16); + memcpy(&hdr6->daddr, v6daddr, 16); + +- new_skb->protocol = htons(ETH_P_IPV6); ++ old_skb->protocol = htons(ETH_P_IPV6); + + if (add_frag_header) { + struct frag_hdr *fh = (struct frag_hdr*)(hdr6 + 1); +@@ -2490,8 +2528,8 @@ int nat46_ipv4_input(struct sk_buff *old + /* Flag to represent whether PSID is assigned to MAP-T node or not */ + bool is_psid = false; + +- fh->frag_off = htons(((ntohs(hdr4->frag_off) >> 13) & 7) + ((ntohs(hdr4->frag_off) & 0x1FFF) << 3)); +- fh->nexthdr = hdr4->protocol; ++ fh->frag_off = htons(((ntohs(frag_off) >> 13) & 7) + ((ntohs(frag_off) & 0x1FFF) << 3)); ++ fh->nexthdr = protocol; + + /* + * PSID assigned MAP-T node will have non-zero ea_len and we are currently +@@ -2506,29 +2544,30 @@ int nat46_ipv4_input(struct sk_buff *old + if (ce_port_num) { + fh->identification = htonl(ce_port_num); + } else { +- fh->identification = htonl(ntohs(hdr4->id)); ++ fh->identification = htonl(ntohs(id)); + } + } else { +- fh->identification = htonl(ntohs(hdr4->id)); ++ fh->identification = htonl(ntohs(id)); + } + + + } +- ip6_update_csum(new_skb, hdr6, add_frag_header); ++ ip6_update_csum(old_skb, hdr6, v4saddr, v4daddr, add_frag_header); + +- hdr6->nexthdr = add_frag_header ? NEXTHDR_FRAGMENT : hdr4->protocol; ++ hdr6->nexthdr = add_frag_header ? NEXTHDR_FRAGMENT : protocol; + + + // FIXME: check if you can not fit the packet into the cached MTU +- // if (dst_mtu(skb_dst(new_skb))==0) { } +- +- nat46debug(5, "about to send v6 packet, flags: %02x", IP6CB(new_skb)->flags); +- nat46_netdev_count_xmit(new_skb, old_skb->dev); ++ // if (dst_mtu(skb_dst(old_skb))==0) { } + +- /* set skb->iif */ +- new_skb->skb_iif = old_skb->skb_iif; ++ nat46debug(5, "about to send v6 packet, flags: %02x", IPCB(old_skb)->flags); ++ nat46_netdev_count_xmit(old_skb, old_skb->dev); ++ netif_rx(old_skb); + +- netif_rx(new_skb); ++ /* ++ * skb was reused, needn't free it later. ++ */ ++ err = 1; + + done: + release_nat46_instance(nat46); +--- a/nat46/modules/nat46-core.h ++++ b/nat46/modules/nat46-core.h +@@ -39,7 +39,7 @@ + #define IPV4HDRSIZE 20 + #define IPV6V4HDRDELTA (IPV6HDRSIZE - IPV4HDRSIZE) + +-/* ++/* + * A generic v4<->v6 translation structure. + * The currently supported translation styles: + */ +--- a/nat46/modules/nat46-netdev.c ++++ b/nat46/modules/nat46-netdev.c +@@ -100,8 +100,7 @@ static netdev_tx_t nat46_netdev_xmit(str + + if(ETH_P_IP == ntohs(skb->protocol)) { + ret = nat46_ipv4_input(skb); +- } +- if(ETH_P_IPV6 == ntohs(skb->protocol)) { ++ }else if(ETH_P_IPV6 == ntohs(skb->protocol)) { + ret = nat46_ipv6_input(skb); + } + if(0 == ret) { +@@ -174,6 +173,7 @@ static void nat46_netdev_setup(struct ne + dev->mtu = 16384; /* iptables does reassembly. Rather than using ETH_DATA_LEN, let's try to get as much mileage as we can with the Linux stack */ + dev->features = NETIF_F_NETNS_LOCAL; + dev->flags = IFF_NOARP | IFF_POINTOPOINT; ++ dev->priv_flags_ext = IFF_EXT_MAPT; + } + + int nat46_netdev_create(char *basename, struct net_device **dev) diff --git a/package/kernel/nat46/patches/120-sleeping_backtrace.patch b/package/kernel/nat46/patches/120-sleeping_backtrace.patch new file mode 100644 index 00000000000000..5963af2b0365d7 --- /dev/null +++ b/package/kernel/nat46/patches/120-sleeping_backtrace.patch @@ -0,0 +1,57 @@ +commit 9457a8be6e700f39e6b545f8db0edd30c0693700 +Author: Ken Zhu +Date: Tue Sep 6 11:11:20 2022 -0700 + + nat46: fix sleeping warning back trace + + use spin_lock instead of mutex_lock since + mutex_lock could sleep in the kernel packet process. + + Change-Id: I65c15a9f618ef296159884a0d6d742e66aaf6623 + Signed-off-by: Ken Zhu + +--- a/nat46/modules/nat46-glue.c ++++ b/nat46/modules/nat46-glue.c +@@ -18,7 +18,7 @@ + #include "nat46-glue.h" + #include "nat46-core.h" + +-static DEFINE_MUTEX(ref_lock); ++static DEFINE_SPINLOCK(ref_lock); + int is_valid_nat46(nat46_instance_t *nat46) { + return (nat46 && (nat46->sig == NAT46_SIGNATURE)); + } +@@ -47,28 +47,27 @@ nat46_instance_t *alloc_nat46_instance(i + return nat46; + } + +- + nat46_instance_t *get_nat46_instance(struct sk_buff *sk) { + nat46_instance_t *nat46 = netdev_nat46_instance(sk->dev); +- mutex_lock(&ref_lock); ++ spin_lock_bh(&ref_lock); + if (is_valid_nat46(nat46)) { + nat46->refcount++; +- mutex_unlock(&ref_lock); ++ spin_unlock_bh(&ref_lock); + return nat46; + } else { + printk("[nat46] get_nat46_instance: Could not find a valid NAT46 instance!"); +- mutex_unlock(&ref_lock); ++ spin_unlock_bh(&ref_lock); + return NULL; + } + } + + void release_nat46_instance(nat46_instance_t *nat46) { +- mutex_lock(&ref_lock); ++ spin_lock_bh(&ref_lock); + nat46->refcount--; + if(0 == nat46->refcount) { + printk("[nat46] release_nat46_instance: freeing nat46 instance with %d pairs\n", nat46->npairs); + nat46->sig = FREED_NAT46_SIGNATURE; + kfree(nat46); + } +- mutex_unlock(&ref_lock); ++ spin_unlock_bh(&ref_lock); + } diff --git a/package/kernel/nat46/patches/121-tos-fix.patch b/package/kernel/nat46/patches/121-tos-fix.patch new file mode 100644 index 00000000000000..6b265886f5b70b --- /dev/null +++ b/package/kernel/nat46/patches/121-tos-fix.patch @@ -0,0 +1,27 @@ +Author: Ramkishan Gurjar +Date: Thu Nov 16 15:30:04 2023 +0530 + + nat46: Fix traffic class is not set in ipv6 Header from ipv4 tos value. + + Change-Id: I781d7af8bc9751dd23f6c3f4195644b3f9025fcb + Signed-off-by: Ramkishan Gurjar + +--- a/nat46/modules/nat46-core.c ++++ b/nat46/modules/nat46-core.c +@@ -2397,6 +2397,8 @@ int nat46_ipv4_input(struct sk_buff *old + return err; + } + ++ tclass = ip_tos_ignore ? 0 : hdr4->tos; /* traffic class */ ++ + memset(v6saddr, 1, 16); + memset(v6daddr, 2, 16); + +@@ -2508,7 +2510,6 @@ int nat46_ipv4_input(struct sk_buff *old + memset(hdr6, 0, sizeof(*hdr6) + (add_frag_header?8:0)); + + /* build IPv6 header */ +- tclass = ip_tos_ignore ? 0 : hdr4->tos; /* traffic class */ + *(__be32 *)hdr6 = htonl(0x60000000 | (tclass << 20)) | flowlabel; /* version, priority, flowlabel */ + + /* IPv6 length is a payload length, IPv4 is hdr+payload */ From 0e420fa1db9cae5c6f55929d5463b96aee87b33c Mon Sep 17 00:00:00 2001 From: Sean Khan Date: Mon, 6 May 2024 00:33:46 -0400 Subject: [PATCH 186/225] package: kernel: nat46: use standard build functions Instead of 'install', 'cp', use standard build functions Signed-off-by: Sean Khan --- package/kernel/nat46/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/kernel/nat46/Makefile b/package/kernel/nat46/Makefile index 32ea3a4516d4e0..dd1d55b84eef02 100644 --- a/package/kernel/nat46/Makefile +++ b/package/kernel/nat46/Makefile @@ -28,8 +28,8 @@ endef include $(INCLUDE_DIR)/kernel-defaults.mk define Build/InstallDev - mkdir -p -m 0777 $(STAGING_DIR)/usr/include/nat46 - $(CP) $(PKG_BUILD_DIR)/nat46/modules/*.h $(STAGING_DIR)/usr/include/nat46/ + $(INSTALL_DIR) $(STAGING_DIR)/usr/include/nat46 + $(INSTALL_DATA) $(PKG_BUILD_DIR)/nat46/modules/*.h $(STAGING_DIR)/usr/include/nat46/ endef define Build/Compile @@ -37,7 +37,7 @@ define Build/Compile MODFLAGS="-DMODULE -mlong-calls" \ EXTRA_CFLAGS="-DNAT46_VERSION=\\\"$(PKG_SOURCE_VERSION)\\\"" \ modules - cp $(PKG_BUILD_DIR)/nat46/modules/Module.symvers $(PKG_BUILD_DIR)/Module.symvers + $(INSTALL_DATA) $(PKG_BUILD_DIR)/nat46/modules/Module.symvers $(PKG_BUILD_DIR)/Module.symvers endef $(eval $(call KernelPackage,nat46)) From 9979ea4efbba1a71e1aa43f6d58012e4160b046f Mon Sep 17 00:00:00 2001 From: bitthief Date: Sat, 4 Feb 2023 01:28:51 +0200 Subject: [PATCH 187/225] iproute2: add NSS QDISC support Signed-off-by: bitthief Co-Developed-by: Sean Khan --- .../iproute2/patches/400-add-nss-qdisc.patch | 2093 +++++++++++++++++ .../iproute2/patches/500-add-nssmirred.patch | 243 ++ 2 files changed, 2336 insertions(+) create mode 100644 package/network/utils/iproute2/patches/400-add-nss-qdisc.patch create mode 100644 package/network/utils/iproute2/patches/500-add-nssmirred.patch diff --git a/package/network/utils/iproute2/patches/400-add-nss-qdisc.patch b/package/network/utils/iproute2/patches/400-add-nss-qdisc.patch new file mode 100644 index 00000000000000..299710f79169d0 --- /dev/null +++ b/package/network/utils/iproute2/patches/400-add-nss-qdisc.patch @@ -0,0 +1,2093 @@ +--- a/include/uapi/linux/pkt_sched.h ++++ b/include/uapi/linux/pkt_sched.h +@@ -119,6 +119,251 @@ enum { + + #define TCA_STAB_MAX (__TCA_STAB_MAX - 1) + ++enum { ++ TCA_NSS_ACCEL_MODE_NSS_FW, ++ TCA_NSS_ACCEL_MODE_PPE, ++ TCA_NSS_ACCEL_MODE_MAX ++}; ++ ++/* NSSFIFO section */ ++ ++enum { ++ TCA_NSSFIFO_UNSPEC, ++ TCA_NSSFIFO_PARMS, ++ __TCA_NSSFIFO_MAX ++}; ++ ++#define TCA_NSSFIFO_MAX (__TCA_NSSFIFO_MAX - 1) ++ ++struct tc_nssfifo_qopt { ++ __u32 limit; /* Queue length: bytes for bfifo, packets for pfifo */ ++ __u8 set_default; /* Sets qdisc to be the default qdisc for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSWRED section */ ++ ++enum { ++ TCA_NSSWRED_UNSPEC, ++ TCA_NSSWRED_PARMS, ++ __TCA_NSSWRED_MAX ++}; ++ ++#define TCA_NSSWRED_MAX (__TCA_NSSWRED_MAX - 1) ++#define NSSWRED_CLASS_MAX 6 ++struct tc_red_alg_parameter { ++ __u32 min; /* qlen_avg < min: pkts are all enqueued */ ++ __u32 max; /* qlen_avg > max: pkts are all dropped */ ++ __u32 probability;/* Drop probability at qlen_avg = max */ ++ __u32 exp_weight_factor;/* exp_weight_factor for calculate qlen_avg */ ++}; ++ ++struct tc_nsswred_traffic_class { ++ __u32 limit; /* Queue length */ ++ __u32 weight_mode_value; /* Weight mode value */ ++ struct tc_red_alg_parameter rap;/* Parameters for RED alg */ ++}; ++ ++/* ++ * Weight modes for WRED ++ */ ++enum tc_nsswred_weight_modes { ++ TC_NSSWRED_WEIGHT_MODE_DSCP = 0,/* Weight mode is DSCP */ ++ TC_NSSWRED_WEIGHT_MODES, /* Must be last */ ++}; ++typedef enum tc_nsswred_weight_modes tc_nsswred_weight_mode_t; ++ ++struct tc_nsswred_qopt { ++ __u32 limit; /* Queue length */ ++ enum tc_nsswred_weight_modes weight_mode; ++ /* Weight mode */ ++ __u32 traffic_classes; /* How many traffic classes: DPs */ ++ __u32 def_traffic_class; /* Default traffic if no match: def_DP */ ++ __u32 traffic_id; /* The traffic id to be configured: DP */ ++ __u32 weight_mode_value; /* Weight mode value */ ++ struct tc_red_alg_parameter rap;/* RED algorithm parameters */ ++ struct tc_nsswred_traffic_class tntc[NSSWRED_CLASS_MAX]; ++ /* Traffic settings for dumpping */ ++ __u8 ecn; /* Setting ECN bit or dropping */ ++ __u8 set_default; /* Sets qdisc to be the default for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSCODEL section */ ++ ++enum { ++ TCA_NSSCODEL_UNSPEC, ++ TCA_NSSCODEL_PARMS, ++ __TCA_NSSCODEL_MAX ++}; ++ ++#define TCA_NSSCODEL_MAX (__TCA_NSSCODEL_MAX - 1) ++ ++struct tc_nsscodel_qopt { ++ __u32 target; /* Acceptable queueing delay */ ++ __u32 limit; /* Max number of packets that can be held in the queue */ ++ __u32 interval; /* Monitoring interval */ ++ __u32 flows; /* Number of flow buckets */ ++ __u32 quantum; /* Weight (in bytes) used for DRR of flow buckets */ ++ __u8 ecn; /* 0 - disable ECN, 1 - enable ECN */ ++ __u8 set_default; /* Sets qdisc to be the default qdisc for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++struct tc_nsscodel_xstats { ++ __u32 peak_queue_delay; /* Peak delay experienced by a dequeued packet */ ++ __u32 peak_drop_delay; /* Peak delay experienced by a dropped packet */ ++}; ++ ++/* NSSFQ_CODEL section */ ++ ++struct tc_nssfq_codel_xstats { ++ __u32 new_flow_count; /* Total number of new flows seen */ ++ __u32 new_flows_len; /* Current number of new flows */ ++ __u32 old_flows_len; /* Current number of old flows */ ++ __u32 ecn_mark; /* Number of packets marked with ECN */ ++ __u32 drop_overlimit; /* Number of packets dropped due to overlimit */ ++ __u32 maxpacket; /* The largest packet seen so far in the queue */ ++}; ++ ++/* NSSTBL section */ ++ ++enum { ++ TCA_NSSTBL_UNSPEC, ++ TCA_NSSTBL_PARMS, ++ __TCA_NSSTBL_MAX ++}; ++ ++#define TCA_NSSTBL_MAX (__TCA_NSSTBL_MAX - 1) ++ ++struct tc_nsstbl_qopt { ++ __u32 burst; /* Maximum burst size */ ++ __u32 rate; /* Limiting rate of TBF */ ++ __u32 peakrate; /* Maximum rate at which TBF is allowed to send */ ++ __u32 mtu; /* Max size of packet, or minumim burst size */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSPRIO section */ ++ ++#define TCA_NSSPRIO_MAX_BANDS 256 ++ ++enum { ++ TCA_NSSPRIO_UNSPEC, ++ TCA_NSSPRIO_PARMS, ++ __TCA_NSSPRIO_MAX ++}; ++ ++#define TCA_NSSPRIO_MAX (__TCA_NSSPRIO_MAX - 1) ++ ++struct tc_nssprio_qopt { ++ __u32 bands; /* Number of bands */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSBF section */ ++ ++enum { ++ TCA_NSSBF_UNSPEC, ++ TCA_NSSBF_CLASS_PARMS, ++ TCA_NSSBF_QDISC_PARMS, ++ __TCA_NSSBF_MAX ++}; ++ ++#define TCA_NSSBF_MAX (__TCA_NSSBF_MAX - 1) ++ ++struct tc_nssbf_class_qopt { ++ __u32 burst; /* Maximum burst size */ ++ __u32 rate; /* Allowed bandwidth for this class */ ++ __u32 mtu; /* MTU of the associated interface */ ++ __u32 quantum; /* Quantum allocation for DRR */ ++}; ++ ++struct tc_nssbf_qopt { ++ __u16 defcls; /* Default class value */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSWRR section */ ++ ++enum { ++ TCA_NSSWRR_UNSPEC, ++ TCA_NSSWRR_CLASS_PARMS, ++ TCA_NSSWRR_QDISC_PARMS, ++ __TCA_NSSWRR_MAX ++}; ++ ++#define TCA_NSSWRR_MAX (__TCA_NSSWRR_MAX - 1) ++ ++struct tc_nsswrr_class_qopt { ++ __u32 quantum; /* Weight associated to this class */ ++}; ++ ++struct tc_nsswrr_qopt { ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSWFQ section */ ++ ++enum { ++ TCA_NSSWFQ_UNSPEC, ++ TCA_NSSWFQ_CLASS_PARMS, ++ TCA_NSSWFQ_QDISC_PARMS, ++ __TCA_NSSWFQ_MAX ++}; ++ ++#define TCA_NSSWFQ_MAX (__TCA_NSSWFQ_MAX - 1) ++ ++struct tc_nsswfq_class_qopt { ++ __u32 quantum; /* Weight associated to this class */ ++}; ++ ++struct tc_nsswfq_qopt { ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSHTB section */ ++ ++enum { ++ TCA_NSSHTB_UNSPEC, ++ TCA_NSSHTB_CLASS_PARMS, ++ TCA_NSSHTB_QDISC_PARMS, ++ __TCA_NSSHTB_MAX ++}; ++ ++#define TCA_NSSHTB_MAX (__TCA_NSSHTB_MAX - 1) ++ ++struct tc_nsshtb_class_qopt { ++ __u32 burst; /* Allowed burst size */ ++ __u32 rate; /* Allowed bandwidth for this class */ ++ __u32 cburst; /* Maximum burst size */ ++ __u32 crate; /* Maximum bandwidth for this class */ ++ __u32 quantum; /* Quantum allocation for DRR */ ++ __u32 priority; /* Priority value associated with this class */ ++ __u32 overhead; /* Overhead in bytes per packet */ ++}; ++ ++struct tc_nsshtb_qopt { ++ __u32 r2q; /* Rate to quantum ratio */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSBLACKHOLE section */ ++ ++enum { ++ TCA_NSSBLACKHOLE_UNSPEC, ++ TCA_NSSBLACKHOLE_PARMS, ++ __TCA_NSSBLACKHOLE_MAX ++}; ++ ++#define TCA_NSSBLACKHOLE_MAX (__TCA_NSSBLACKHOLE_MAX - 1) ++ ++struct tc_nssblackhole_qopt { ++ __u8 set_default; /* Sets qdisc to be the default qdisc for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++ + /* FIFO section */ + + struct tc_fifo_qopt { +--- a/tc/Makefile ++++ b/tc/Makefile +@@ -77,6 +77,7 @@ TCMODULES += q_etf.o + TCMODULES += q_taprio.o + TCMODULES += q_plug.o + TCMODULES += q_ets.o ++TCMODULES += q_nss.o + + TCSO := + +--- /dev/null ++++ b/tc/q_nss.c +@@ -0,0 +1,1826 @@ ++/* ++ ************************************************************************** ++ * Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved. ++ * Permission to use, copy, modify, and/or distribute this software for ++ * any purpose with or without fee is hereby granted, provided that the ++ * above copyright notice and this permission notice appear in all copies. ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT ++ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ ************************************************************************** ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "utils.h" ++#include "tc_util.h" ++#include "tc_red.h" ++ ++/* ======================== NSSWRED =======================*/ ++ ++static void nssred_explain(void) ++{ ++ fprintf(stderr, "Usage: ... nssred limit BYTES avpkt BYTES [ min BYTES ] [ max BYTES ] [ probability VALUE ]\n"); ++ fprintf(stderr, " [ burst PACKETS ] [ecn] [ set_default ] [ accel_mode ]\n"); ++} ++ ++static void nsswred_explain(void) ++{ ++ fprintf(stderr, "Usage: ... nsswred setup DPs NUMBER dp_default NUMBER [ weight_mode dscp ] [ecn] [ set_default ] [ accel_mode ]\n"); ++ fprintf(stderr, " nsswred limit BYTES DP NUMBER min BYTES max BYTES avpkt BYTES dscp NUMBER [ probability VALUE ] [ burst PACKETS ]\n"); ++} ++ ++static int nsswred_setup(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ struct rtattr *tail; ++ struct tc_nsswred_qopt opt; ++ ++ memset(&opt, 0, sizeof(opt)); ++ unsigned int dps = 0; ++ unsigned int def_dp = 0; ++ bool accel_mode = false; ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "DPs") == 0) { ++ NEXT_ARG(); ++ if (get_unsigned(&dps, *argv, 0) || dps > NSSWRED_CLASS_MAX) { ++ ++ fprintf(stderr, "DPs should be between 1 - %d\n", NSSWRED_CLASS_MAX); ++ return -1; ++ } ++ } else if (strcmp(*argv, "weight_mode") == 0) { ++ NEXT_ARG(); ++ if (strcmp(*argv, "dscp") == 0) { ++ opt.weight_mode = TC_NSSWRED_WEIGHT_MODE_DSCP; ++ } else { ++ fprintf(stderr, "Illegal \"weight_mode\", we only support dscp at this moment\n"); ++ } ++ } else if (strcmp(*argv, "ecn") == 0) { ++ opt.ecn = 1; ++ } else if (strcmp(*argv, "dp_default") == 0) { ++ NEXT_ARG(); ++ if (get_unsigned(&def_dp, *argv, 0) || def_dp > dps) { ++ fprintf(stderr, "Illegal dp_default value\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "help") == 0) { ++ nsswred_explain(); ++ return -1; ++ } else if (strcmp(*argv, "set_default") == 0) { ++ opt.set_default = 1; ++ } else if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ nsswred_explain(); ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_NSS_FW; ++ } else if (opt.accel_mode != TCA_NSS_ACCEL_MODE_NSS_FW) { ++ fprintf(stderr, "accel_mode should be %d\n", TCA_NSS_ACCEL_MODE_NSS_FW); ++ return -1; ++ } ++ ++ if (!dps || !def_dp) { ++ fprintf(stderr, "Illegal nsswred setup parameters\n"); ++ return -1; ++ } ++ opt.traffic_classes = dps; ++ opt.def_traffic_class = def_dp; ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSWRED_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nsswred_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ struct rtattr *tail; ++ struct tc_nsswred_qopt opt; ++ ++ int total_args = argc; ++ unsigned burst = 0; ++ unsigned avpkt = 0; ++ double probability = 0.0; ++ unsigned char weighted = (strcmp(qu->id, "nsswred") == 0); ++ bool accel_mode = false; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "limit") == 0) { ++ NEXT_ARG(); ++ if (get_size(&opt.limit, *argv)) { ++ fprintf(stderr, "Illegal \"limit\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "set_default") == 0) { ++ opt.set_default = 1; ++ } else if (strcmp(*argv, "min") == 0) { ++ NEXT_ARG(); ++ if (get_size(&opt.rap.min, *argv)) { ++ fprintf(stderr, "Illegal \"min\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "max") == 0) { ++ NEXT_ARG(); ++ if (get_size(&opt.rap.max, *argv)) { ++ fprintf(stderr, "Illegal \"max\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "burst") == 0) { ++ NEXT_ARG(); ++ if (get_unsigned(&burst, *argv, 0)) { ++ fprintf(stderr, "Illegal \"burst\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "avpkt") == 0) { ++ NEXT_ARG(); ++ if (get_size(&avpkt, *argv)) { ++ fprintf(stderr, "Illegal \"avpkt\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "probability") == 0) { ++ NEXT_ARG(); ++ if (sscanf(*argv, "%lg", &probability) != 1) { ++ fprintf(stderr, "Illegal \"probability\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "ecn") == 0) { ++ opt.ecn = 1; ++ } else if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else if (strcmp(*argv, "help") == 0) { ++ if (weighted) { ++ nsswred_explain(); ++ } else { ++ nssred_explain(); ++ } ++ return -1; ++ } else if (weighted) { ++ if (strcmp(*argv, "setup") == 0) { ++ if (argc != total_args) { ++ fprintf(stderr, "Setup command must be the first parameter\n"); ++ return -1; ++ } ++ return nsswred_setup(qu, argc-1, argv+1, n); ++ } else if (strcmp(*argv, "DP") == 0) { ++ NEXT_ARG(); ++ if (get_unsigned(&opt.traffic_id, *argv, 0)) { ++ fprintf(stderr, "Illegal \"DP\""); ++ return -1; ++ } ++ } else if (strcmp(*argv, "dscp") == 0) { ++ NEXT_ARG(); ++ if (get_unsigned(&opt.weight_mode_value, *argv, 0)) { ++ fprintf(stderr, "Illegal \"dscp\" value\n"); ++ return -1; ++ } ++ } ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ if (weighted) { ++ nsswred_explain(); ++ } else { ++ nssred_explain(); ++ } ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_PPE; ++ } else if (opt.accel_mode >= TCA_NSS_ACCEL_MODE_MAX) { ++ fprintf(stderr, "Accel_mode should be < %d\n", TCA_NSS_ACCEL_MODE_MAX); ++ return -1; ++ } ++ ++ if (weighted) { ++ if (!opt.limit || !opt.rap.min || !opt.rap.max || !opt.traffic_id || !avpkt || !opt.weight_mode_value) { ++ fprintf(stderr, "Require limit, min, max, avpkt, DP, weight_mode_value\n"); ++ return -1; ++ } ++ } else { ++ if (!opt.limit || !avpkt) { ++ fprintf(stderr, "Require limit, avpkt"); ++ return -1; ++ } ++ } ++ ++ /* ++ * Compute default min/max thresholds based on ++ * Sally Floyd's recommendations: ++ * http://www.icir.org/floyd/REDparameters.txt ++ */ ++ if (!opt.rap.max) ++ opt.rap.max = opt.rap.min ? opt.rap.min * 3 : opt.limit / 4; ++ if (!opt.rap.min) ++ opt.rap.min = opt.rap.max / 3; ++ if (!burst) ++ burst = (2 * opt.rap.min + opt.rap.max) / (3 * avpkt); ++ if ((opt.rap.exp_weight_factor = tc_red_eval_ewma(opt.rap.min, burst, avpkt)) < 0) { ++ fprintf(stderr, "Failed to calculate EWMA constant.\n"); ++ return -1; ++ } ++ ++ /* ++ * project [0.0-1.0] to [0-255] to avoid floating point calculation ++ */ ++ opt.rap.probability = probability * (pow(2, 8)-1); ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSWRED_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nsswred_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSWRED_MAX + 1]; ++ struct tc_nsswred_qopt *qopt; ++ int i; ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSWRED_MAX, opt); ++ ++ if (tb[TCA_NSSWRED_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSWRED_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSWRED_PARMS]); ++ ++ if (strcmp(qu->id, "nsswred") == 0) { ++ fprintf(f, "DPs %d def_DP %d weight mode: " , qopt->traffic_classes, qopt->def_traffic_class); ++ if (qopt->weight_mode == TC_NSSWRED_WEIGHT_MODE_DSCP) ++ fprintf(f, "DSCP\n"); ++ else ++ fprintf(f, "Unknown\n"); ++ for (i = 0;i < qopt->traffic_classes; i ++) { ++ if (qopt->tntc[i].rap.exp_weight_factor) { ++ double prob = (double)qopt->tntc[i].rap.probability; ++ fprintf(f, "DP %d: limit %d, weight mode value: %d min: %d max: %d exp_weight_factor: %d probability %.2f\n", ++ i + 1, qopt->tntc[i].limit, qopt->tntc[i].weight_mode_value ++ , qopt->tntc[i].rap.min,qopt->tntc[i].rap.max,qopt->tntc[i].rap.exp_weight_factor,prob/255); ++ } ++ } ++ } else { ++ double prob = (double)qopt->rap.probability; ++ fprintf(f, "limit %d, min: %d max: %d exp_weight_factor: %d probability %.2f\n", ++ qopt->limit, qopt->rap.min,qopt->rap.max,qopt->rap.exp_weight_factor,prob/255); ++ } ++ ++ if (qopt->ecn) ++ fprintf(f, "ECN enabled "); ++ if (qopt->set_default) ++ fprintf(f, "set_default "); ++ ++ fprintf(f, "accel_mode: %d ", qopt->accel_mode); ++ ++ return 0; ++} ++ ++struct qdisc_util nssred_qdisc_util = { ++ .id = "nssred", ++ .parse_qopt = nsswred_parse_opt, ++ .print_qopt = nsswred_print_opt, ++}; ++ ++struct qdisc_util nsswred_qdisc_util = { ++ .id = "nsswred", ++ .parse_qopt = nsswred_parse_opt, ++ .print_qopt = nsswred_print_opt, ++}; ++ ++/* ======================== NSSFIFO =======================*/ ++ ++static void nssfifo_explain(void) ++{ ++ fprintf(stderr, "Usage: ... nsspfifo [ limit PACKETS ] [ set_default ] [ accel_mode ]\n"); ++} ++ ++static int nssfifo_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ struct rtattr *tail; ++ struct tc_nssfifo_qopt opt; ++ bool accel_mode = false; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "limit") == 0) { ++ NEXT_ARG(); ++ if (get_size(&opt.limit, *argv) || opt.limit == 0) { ++ fprintf(stderr, "Illegal \"limit\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "set_default") == 0) { ++ opt.set_default = 1; ++ } else if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else if (strcmp(*argv, "help") == 0) { ++ nssfifo_explain(); ++ return -1; ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ nssfifo_explain(); ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_PPE; ++ } else if (opt.accel_mode >= TCA_NSS_ACCEL_MODE_MAX) { ++ fprintf(stderr, "accel_mode should be < %d\n", TCA_NSS_ACCEL_MODE_MAX); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSFIFO_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nssfifo_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSFIFO_MAX + 1]; ++ struct tc_nssfifo_qopt *qopt; ++ SPRINT_BUF(b1); ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSFIFO_MAX, opt); ++ ++ if (tb[TCA_NSSFIFO_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSFIFO_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSFIFO_PARMS]); ++ ++ if (strcmp(qu->id, "nssbfifo") == 0) ++ fprintf(f, "limit %s ", sprint_size(qopt->limit, b1)); ++ else ++ fprintf(f, "limit %up ", qopt->limit); ++ ++ if (qopt->set_default) ++ fprintf(f, "set_default "); ++ ++ fprintf(f, "accel_mode %d ", qopt->accel_mode); ++ ++ return 0; ++} ++ ++struct qdisc_util nsspfifo_qdisc_util = { ++ .id = "nsspfifo", ++ .parse_qopt = nssfifo_parse_opt, ++ .print_qopt = nssfifo_print_opt, ++}; ++ ++struct qdisc_util nssbfifo_qdisc_util = { ++ .id = "nssbfifo", ++ .parse_qopt = nssfifo_parse_opt, ++ .print_qopt = nssfifo_print_opt, ++}; ++ ++/* ======================== NSSFQ_CODEL =======================*/ ++ ++static void nssfq_codel_explain(void) ++{ ++ fprintf(stderr, "Usage: ... nssfq_codel target TIME interval TIME [ flows NUMBER ] [ quantum BYTES ]" ++ "[ limit PACKETS ] [ set_default ] [ accel_mode ]\n"); ++} ++ ++static void nssfq_codel_explain_err1(void) ++{ ++ fprintf(stderr, "Value of target and interval should be greater than 1ms\n"); ++} ++ ++static int nssfq_codel_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ struct rtattr *tail; ++ struct tc_nsscodel_qopt opt; ++ bool accel_mode = false; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "target") == 0) { ++ NEXT_ARG(); ++ if (get_time(&opt.target, *argv)) { ++ fprintf(stderr, "Illegal \"target\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "limit") == 0) { ++ NEXT_ARG(); ++ if (get_size(&opt.limit, *argv) || opt.limit == 0) { ++ fprintf(stderr, "Illegal \"limit\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "flows") == 0) { ++ NEXT_ARG(); ++ if (get_size(&opt.flows, *argv) || opt.flows == 0) { ++ fprintf(stderr, "Illegal \"flows\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "quantum") == 0) { ++ NEXT_ARG(); ++ if (get_size(&opt.quantum, *argv) || opt.quantum == 0) { ++ fprintf(stderr, "Illegal \"quantum\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "interval") == 0) { ++ NEXT_ARG(); ++ if (get_time(&opt.interval, *argv)) { ++ fprintf(stderr, "Illegal \"interval\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "ecn") == 0) { ++ fprintf(stderr, "Illegal, ECN not supported\n"); ++ nssfq_codel_explain(); ++ return -1; ++ } else if (strcmp(*argv, "set_default") == 0) { ++ opt.set_default = 1; ++ } else if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else if (strcmp(*argv, "help") == 0) { ++ nssfq_codel_explain(); ++ return -1; ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ nssfq_codel_explain(); ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_NSS_FW; ++ } else if (opt.accel_mode != TCA_NSS_ACCEL_MODE_NSS_FW) { ++ fprintf(stderr, "accel_mode should be %d\n", TCA_NSS_ACCEL_MODE_NSS_FW); ++ return -1; ++ } ++ ++ if (!opt.target || !opt.interval) { ++ nssfq_codel_explain(); ++ return -1; ++ } ++ ++ if (opt.target < 1000 || opt.interval < 1000) { ++ nssfq_codel_explain_err1(); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSCODEL_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nssfq_codel_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSCODEL_MAX + 1]; ++ struct tc_nsscodel_qopt *qopt; ++ SPRINT_BUF(b1); ++ SPRINT_BUF(b2); ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSCODEL_MAX, opt); ++ ++ if (tb[TCA_NSSCODEL_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSCODEL_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSCODEL_PARMS]); ++ ++ fprintf(f, "target %s limit %up interval %s flows %u quantum %u ", ++ sprint_time(qopt->target, b1), ++ qopt->limit, ++ sprint_time(qopt->interval, b2), ++ qopt->flows, ++ qopt->quantum); ++ ++ if (qopt->ecn) ++ fprintf(f, "ecn "); ++ ++ if (qopt->set_default) ++ fprintf(f, "set_default "); ++ ++ fprintf(f, "accel_mode %d ", qopt->accel_mode); ++ ++ return 0; ++} ++ ++static int nssfq_codel_print_xstats(struct qdisc_util *qu, FILE *f, struct rtattr *xstats) ++{ ++ struct tc_nssfq_codel_xstats *st; ++ ++ if (xstats == NULL) ++ return 0; ++ ++ if (RTA_PAYLOAD(xstats) < sizeof(*st)) ++ return -1; ++ ++ st = RTA_DATA(xstats); ++ fprintf(f, " maxpacket %u drop_overlimit %u new_flow_count %u ecn_mark %u\n", ++ st->maxpacket, st->drop_overlimit, st->new_flow_count, st->ecn_mark); ++ fprintf(f, " new_flows_len %u old_flows_len %u", st->new_flows_len, st->old_flows_len); ++ ++ return 0; ++} ++ ++struct qdisc_util nssfq_codel_qdisc_util = { ++ .id = "nssfq_codel", ++ .parse_qopt = nssfq_codel_parse_opt, ++ .print_qopt = nssfq_codel_print_opt, ++ .print_xstats = nssfq_codel_print_xstats, ++}; ++ ++/* ======================== NSSCODEL =======================*/ ++ ++static void nsscodel_explain(void) ++{ ++ fprintf(stderr, "Usage: ... nsscodel target TIME interval TIME [ limit PACKETS ] [ set_default ] [ accel_mode ]\n"); ++} ++ ++static void nsscodel_explain_err1(void) ++{ ++ fprintf(stderr, "Value of target and interval should be greater than 1ms\n"); ++} ++ ++static int nsscodel_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ struct rtattr *tail; ++ struct tc_nsscodel_qopt opt; ++ bool accel_mode = false; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "target") == 0) { ++ NEXT_ARG(); ++ if (get_time(&opt.target, *argv)) { ++ fprintf(stderr, "Illegal \"target\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "limit") == 0) { ++ NEXT_ARG(); ++ if (get_size(&opt.limit, *argv) || opt.limit == 0) { ++ fprintf(stderr, "Illegal \"limit\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "interval") == 0) { ++ NEXT_ARG(); ++ if (get_time(&opt.interval, *argv)) { ++ fprintf(stderr, "Illegal \"interval\"\n"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "set_default") == 0) { ++ opt.set_default = 1; ++ } else if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else if (strcmp(*argv, "help") == 0) { ++ nsscodel_explain(); ++ return -1; ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ nsscodel_explain(); ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_NSS_FW; ++ } else if (opt.accel_mode != TCA_NSS_ACCEL_MODE_NSS_FW) { ++ fprintf(stderr, "accel_mode should be %d\n", TCA_NSS_ACCEL_MODE_NSS_FW); ++ return -1; ++ } ++ ++ if (!opt.target || !opt.interval) { ++ nsscodel_explain(); ++ return -1; ++ } ++ ++ if (opt.target < 1000 || opt.interval < 1000) { ++ nsscodel_explain_err1(); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSCODEL_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nsscodel_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSCODEL_MAX + 1]; ++ struct tc_nsscodel_qopt *qopt; ++ SPRINT_BUF(b1); ++ SPRINT_BUF(b2); ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSCODEL_MAX, opt); ++ ++ if (tb[TCA_NSSCODEL_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSCODEL_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSCODEL_PARMS]); ++ ++ fprintf(f, "target %s limit %up interval %s ", ++ sprint_time(qopt->target, b1), ++ qopt->limit, ++ sprint_time(qopt->interval, b2)); ++ ++ if (qopt->set_default) ++ fprintf(f, "set_default "); ++ ++ fprintf(f, "accel_mode %d ", qopt->accel_mode); ++ ++ return 0; ++} ++ ++static int nsscodel_print_xstats(struct qdisc_util *qu, FILE *f, struct rtattr *xstats) ++{ ++ struct tc_nsscodel_xstats *st; ++ ++ if (xstats == NULL) ++ return 0; ++ ++ if (RTA_PAYLOAD(xstats) < sizeof(*st)) ++ return -1; ++ ++ st = RTA_DATA(xstats); ++ fprintf(f, " peak queue delay %ums peak drop delay %ums", ++ st->peak_queue_delay, st->peak_drop_delay); ++ ++ return 0; ++} ++ ++struct qdisc_util nsscodel_qdisc_util = { ++ .id = "nsscodel", ++ .parse_qopt = nsscodel_parse_opt, ++ .print_qopt = nsscodel_print_opt, ++ .print_xstats = nsscodel_print_xstats, ++}; ++ ++/* ======================== NSSTBL =======================*/ ++ ++static void nsstbl_explain(void) ++{ ++ fprintf(stderr, "Usage: ... nsstbl burst BYTES rate BPS [ mtu BYTES ] [ accel_mode ]\n"); ++} ++ ++static int nsstbl_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ int ok = 0; ++ struct rtattr *tail; ++ struct tc_nsstbl_qopt opt; ++ bool accel_mode = false; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "burst") == 0 || ++ strcmp(*argv, "buffer") == 0 || ++ strcmp(*argv, "maxburst") == 0) { ++ NEXT_ARG(); ++ if (opt.burst) { ++ fprintf(stderr, "Double \"buffer/burst\" spec\n"); ++ return -1; ++ } ++ if (get_size(&opt.burst, *argv)) { ++ fprintf(stderr, "Illegal \"burst\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "mtu") == 0 || ++ strcmp(*argv, "minburst") == 0) { ++ NEXT_ARG(); ++ if (opt.mtu) { ++ fprintf(stderr, "Double \"mtu/minburst\" spec\n"); ++ return -1; ++ } ++ if (get_size(&opt.mtu, *argv)) { ++ fprintf(stderr, "Illegal \"mtu\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "rate") == 0) { ++ NEXT_ARG(); ++ if (opt.rate) { ++ fprintf(stderr, "Double \"rate\" spec\n"); ++ return -1; ++ } ++ if (get_rate(&opt.rate, *argv)) { ++ fprintf(stderr, "Illegal \"rate\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else if (strcmp(*argv, "help") == 0) { ++ nsstbl_explain(); ++ return -1; ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ nsstbl_explain(); ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!ok) { ++ nsstbl_explain(); ++ return -1; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_PPE; ++ } else if (opt.accel_mode >= TCA_NSS_ACCEL_MODE_MAX) { ++ fprintf(stderr, "accel_mode should be < %d\n", TCA_NSS_ACCEL_MODE_MAX); ++ return -1; ++ } ++ ++ if (!opt.rate || !opt.burst) { ++ fprintf(stderr, "Both \"rate\" and \"burst\" are required.\n"); ++ return -1; ++ } ++ ++ /* ++ * Peakrate is currently not supported, but we keep the infrastructure ++ * for future use. However, we have disabled taking input for this. ++ */ ++ if (opt.peakrate) { ++ if (!opt.mtu) { ++ fprintf(stderr, "\"mtu\" is required, if \"peakrate\" is requested.\n"); ++ return -1; ++ } ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSTBL_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nsstbl_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSTBL_MAX + 1]; ++ struct tc_nsstbl_qopt *qopt; ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSTBL_MAX, opt); ++ ++ if (tb[TCA_NSSTBL_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSTBL_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSTBL_PARMS]); ++ ++ print_size(PRINT_FP, NULL, "buffer/maxburst %s ", qopt->burst); ++ tc_print_rate(PRINT_FP, NULL, "rate %s ", qopt->rate); ++ print_size(PRINT_FP, NULL, "mtu %s ", qopt->mtu); ++ fprintf(f, "accel_mode %d ", qopt->accel_mode); ++ ++ return 0; ++} ++ ++struct qdisc_util nsstbl_qdisc_util = { ++ .id = "nsstbl", ++ .parse_qopt = nsstbl_parse_opt, ++ .print_qopt = nsstbl_print_opt, ++}; ++ ++/* ======================== NSSPRIO =======================*/ ++ ++static void nssprio_explain(void) ++{ ++ fprintf(stderr, "Usage: ... nssprio [ bands NUMBER (default 256) ] [ accel_mode ]\n"); ++} ++ ++static int nssprio_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ int ok = 0; ++ struct rtattr *tail; ++ struct tc_nssprio_qopt opt; ++ bool accel_mode = false; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "bands") == 0) { ++ NEXT_ARG(); ++ if (get_unsigned(&opt.bands, *argv, 0)) { ++ fprintf(stderr, "Illegal \"limit\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else if (strcmp(*argv, "help") == 0) { ++ nssprio_explain(); ++ return -1; ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ nssprio_explain(); ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!ok) { ++ opt.bands = TCA_NSSPRIO_MAX_BANDS; ++ } else if (opt.bands > TCA_NSSPRIO_MAX_BANDS) { ++ nssprio_explain(); ++ return -1; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_PPE; ++ } else if (opt.accel_mode >= TCA_NSS_ACCEL_MODE_MAX) { ++ fprintf(stderr, "accel_mode should be < %d\n", TCA_NSS_ACCEL_MODE_MAX); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSPRIO_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nssprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSPRIO_MAX + 1]; ++ struct tc_nssprio_qopt *qopt; ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSPRIO_MAX, opt); ++ ++ if (tb[TCA_NSSPRIO_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSPRIO_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSPRIO_PARMS]); ++ ++ fprintf(f, "bands %u ", qopt->bands); ++ fprintf(f, "accel_mode %d ", qopt->accel_mode); ++ ++ return 0; ++} ++ ++struct qdisc_util nssprio_qdisc_util = { ++ .id = "nssprio", ++ .parse_qopt = nssprio_parse_opt, ++ .print_qopt = nssprio_print_opt, ++}; ++ ++/* ======================== NSSBF =======================*/ ++ ++static void nssbf_explain_qdisc(void) ++{ ++ fprintf(stderr, ++ "Usage: ... nssbf [ accel_mode ]\n" ++ ); ++} ++ ++static void nssbf_explain_class(void) ++{ ++ fprintf(stderr, "Usage: ... nssbf rate BPS burst BYTES [ mtu BYTES ]\n"); ++ fprintf(stderr, " [ quantum BYTES ]\n"); ++} ++ ++static void nssbf_explain1(char *arg) ++{ ++ fprintf(stderr, "NSSBF: Illegal \"%s\"\n", arg); ++} ++ ++static int nssbf_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ struct tc_nssbf_qopt opt; ++ struct rtattr *tail; ++ bool accel_mode = false; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (matches(*argv, "default") == 0) { ++ NEXT_ARG(); ++ if (opt.defcls != 0) { ++ fprintf(stderr, "NSSBF: Double \"default\"\n"); ++ return -1; ++ } ++ if (get_u16(&opt.defcls, *argv, 16) < 0) { ++ nssbf_explain1("default"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else if (matches(*argv, "help") == 0) { ++ nssbf_explain_qdisc(); ++ return -1; ++ } else { ++ fprintf(stderr, "NSSBF: What is \"%s\" ?\n", *argv); ++ nssbf_explain_qdisc(); ++ return -1; ++ } ++ argc--, argv++; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_NSS_FW; ++ } else if (opt.accel_mode != TCA_NSS_ACCEL_MODE_NSS_FW) { ++ fprintf(stderr, "accel_mode should be %d\n", TCA_NSS_ACCEL_MODE_NSS_FW); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSBF_QDISC_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nssbf_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSBF_MAX + 1]; ++ struct tc_nssbf_qopt *qopt; ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSBF_MAX, opt); ++ ++ if (tb[TCA_NSSBF_QDISC_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSBF_QDISC_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSBF_QDISC_PARMS]); ++ ++ fprintf(f, "accel_mode %d ", qopt->accel_mode); ++ ++ return 0; ++} ++ ++static int nssbf_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ int ok = 0; ++ struct rtattr *tail; ++ struct tc_nssbf_class_qopt opt; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "burst") == 0 || ++ strcmp(*argv, "buffer") == 0 || ++ strcmp(*argv, "maxburst") == 0) { ++ NEXT_ARG(); ++ if (opt.burst) { ++ fprintf(stderr, "Double \"buffer/burst\" spec\n"); ++ return -1; ++ } ++ if (get_size(&opt.burst, *argv)) { ++ fprintf(stderr, "Illegal \"burst\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "mtu") == 0) { ++ NEXT_ARG(); ++ if (opt.mtu) { ++ fprintf(stderr, "Double \"mtu\" spec\n"); ++ return -1; ++ } ++ if (get_size(&opt.mtu, *argv)) { ++ fprintf(stderr, "Illegal \"mtu\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "quantum") == 0) { ++ NEXT_ARG(); ++ if (opt.quantum) { ++ fprintf(stderr, "Double \"quantum\" spec\n"); ++ return -1; ++ } ++ if (get_size(&opt.quantum, *argv)) { ++ fprintf(stderr, "Illegal \"quantum\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "rate") == 0) { ++ NEXT_ARG(); ++ if (opt.rate) { ++ fprintf(stderr, "Double \"rate\" spec\n"); ++ return -1; ++ } ++ if (get_rate(&opt.rate, *argv)) { ++ fprintf(stderr, "Illegal \"rate\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "help") == 0) { ++ nssbf_explain_class(); ++ return -1; ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ nssbf_explain_class(); ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!ok) { ++ nssbf_explain_class(); ++ return -1; ++ } ++ ++ if (!opt.rate || !opt.burst) { ++ fprintf(stderr, "Both \"rate\" and \"burst\" are required.\n"); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSBF_CLASS_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nssbf_print_class_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSBF_MAX + 1]; ++ struct tc_nssbf_class_qopt *qopt; ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSBF_MAX, opt); ++ ++ if (tb[TCA_NSSBF_CLASS_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSBF_CLASS_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSBF_CLASS_PARMS]); ++ ++ print_size(PRINT_FP, NULL, "burst %s ", qopt->burst); ++ tc_print_rate(PRINT_FP, NULL, "rate %s ", qopt->rate); ++ print_size(PRINT_FP, NULL, "quantum %s ", qopt->quantum); ++ print_size(PRINT_FP, NULL, "mtu %s ", qopt->mtu); ++ ++ return 0; ++} ++ ++struct qdisc_util nssbf_qdisc_util = { ++ .id = "nssbf", ++ .parse_qopt = nssbf_parse_opt, ++ .print_qopt = nssbf_print_opt, ++ .parse_copt = nssbf_parse_class_opt, ++ .print_copt = nssbf_print_class_opt, ++}; ++ ++/* ======================== NSSWRR =======================*/ ++ ++static void nsswrr_explain_qdisc(void) ++{ ++ fprintf(stderr, "Usage (qdisc): ... nsswrr [ accel_mode ]\n"); ++} ++ ++static void nsswrr_explain_class(void) ++{ ++ fprintf(stderr, "Usage (class): ... nsswrr quantum PACKETS ]\n"); ++} ++ ++static int nsswrr_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ struct tc_nsswrr_qopt opt; ++ bool accel_mode = false; ++ struct rtattr *tail; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else if (matches(*argv, "help") == 0) { ++ nsswrr_explain_qdisc(); ++ return -1; ++ } else { ++ fprintf(stderr, "What is \"%s\" ?\n", *argv); ++ nsswrr_explain_qdisc(); ++ return -1; ++ } ++ argc--, argv++; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_PPE; ++ } else if (opt.accel_mode >= TCA_NSS_ACCEL_MODE_MAX) { ++ fprintf(stderr, "accel_mode should be < %d\n", TCA_NSS_ACCEL_MODE_MAX); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSWRR_QDISC_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nsswrr_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSWRR_MAX + 1]; ++ struct tc_nsswrr_qopt *qopt; ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSWRR_MAX, opt); ++ ++ if (tb[TCA_NSSWRR_QDISC_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSWRR_QDISC_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSWRR_QDISC_PARMS]); ++ fprintf(f, "accel_mode %d ", qopt->accel_mode); ++ ++ return 0; ++} ++ ++static int nsswrr_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ int ok = 0; ++ struct rtattr *tail; ++ struct tc_nsswrr_class_qopt opt; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "quantum") == 0) { ++ NEXT_ARG(); ++ if (get_u32(&opt.quantum, *argv, 10)) { ++ fprintf(stderr, "Illegal \"quantum\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "help") == 0) { ++ nsswrr_explain_class(); ++ return -1; ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ nsswrr_explain_class(); ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!ok) { ++ nsswrr_explain_class(); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSWRR_CLASS_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nsswrr_print_class_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSWRR_MAX + 1]; ++ struct tc_nsswrr_class_qopt *qopt; ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSWRR_MAX, opt); ++ ++ if (tb[TCA_NSSWRR_CLASS_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSWRR_CLASS_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSWRR_CLASS_PARMS]); ++ ++ fprintf(f, "quantum %up ", qopt->quantum); ++ return 0; ++} ++ ++struct qdisc_util nsswrr_qdisc_util = { ++ .id = "nsswrr", ++ .parse_qopt = nsswrr_parse_opt, ++ .print_qopt = nsswrr_print_opt, ++ .parse_copt = nsswrr_parse_class_opt, ++ .print_copt = nsswrr_print_class_opt, ++}; ++ ++/* ======================== NSSWFQ =======================*/ ++ ++static void nsswfq_explain_qdisc(void) ++{ ++ fprintf(stderr, "Usage (qdisc): ... nsswfq [ accel_mode ]\n"); ++} ++ ++static void nsswfq_explain_class(void) ++{ ++ fprintf(stderr, "Usage (class): ... nsswfq quantum BYTES ]\n"); ++} ++ ++static int nsswfq_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ struct tc_nsswfq_qopt opt; ++ bool accel_mode = false; ++ struct rtattr *tail; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else if (matches(*argv, "help") == 0) { ++ nsswfq_explain_qdisc(); ++ return -1; ++ } else { ++ fprintf(stderr, "NSSWFQ: What is \"%s\" ?\n", *argv); ++ nsswfq_explain_qdisc(); ++ return -1; ++ } ++ argc--, argv++; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_PPE; ++ } else if (opt.accel_mode >= TCA_NSS_ACCEL_MODE_MAX) { ++ fprintf(stderr, "accel_mode should be < %d\n", TCA_NSS_ACCEL_MODE_MAX); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSWFQ_QDISC_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nsswfq_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSWFQ_MAX + 1]; ++ struct tc_nsswfq_qopt *qopt; ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSWFQ_MAX, opt); ++ ++ if (tb[TCA_NSSWFQ_QDISC_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSWFQ_QDISC_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSWFQ_QDISC_PARMS]); ++ fprintf(f, "accel_mode %d ", qopt->accel_mode); ++ ++ return 0; ++} ++ ++static int nsswfq_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ int ok = 0; ++ struct rtattr *tail; ++ struct tc_nsswfq_class_qopt opt; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "quantum") == 0) { ++ NEXT_ARG(); ++ if (get_size(&opt.quantum, *argv)) { ++ fprintf(stderr, "Illegal \"quantum\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "help") == 0) { ++ nsswfq_explain_class(); ++ return -1; ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ nsswfq_explain_class(); ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!ok) { ++ nsswfq_explain_class(); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSWFQ_CLASS_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nsswfq_print_class_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSWFQ_MAX + 1]; ++ struct tc_nsswfq_class_qopt *qopt; ++ SPRINT_BUF(b1); ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSWFQ_MAX, opt); ++ ++ if (tb[TCA_NSSWFQ_CLASS_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSWFQ_CLASS_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSWFQ_CLASS_PARMS]); ++ ++ fprintf(f, "quantum %s ", sprint_size(qopt->quantum, b1)); ++ ++ return 0; ++} ++ ++struct qdisc_util nsswfq_qdisc_util = { ++ .id = "nsswfq", ++ .parse_qopt = nsswfq_parse_opt, ++ .print_qopt = nsswfq_print_opt, ++ .parse_copt = nsswfq_parse_class_opt, ++ .print_copt = nsswfq_print_class_opt, ++}; ++ ++/* ======================== NSSHTB =======================*/ ++ ++static void nsshtb_explain_qdisc(void) ++{ ++ fprintf(stderr, ++ "Usage: ... nsshtb [ r2q ] [ accel_mode ]\n" ++ ); ++} ++ ++static void nsshtb_explain_class(void) ++{ ++ fprintf(stderr, "Usage: ... nsshtb priority 0-3 [ quantum BYTES ] [ rate BPS ] [ burst BYTES ] [crate BPS ] [ cburst BYTES ]\n"); ++ fprintf(stderr, " [ overhead BYTES ] \n"); ++} ++ ++static void nsshtb_explain1(char *arg) ++{ ++ fprintf(stderr, "NSSHTB: Illegal \"%s\"\n", arg); ++} ++ ++static int nsshtb_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ struct tc_nsshtb_qopt opt; ++ struct rtattr *tail; ++ bool accel_mode = false; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "r2q") == 0) { ++ NEXT_ARG(); ++ if (opt.r2q != 0) { ++ fprintf(stderr, "NSSHTB: Double \"r2q\"\n"); ++ return -1; ++ } ++ if (get_u32(&opt.r2q, *argv, 10) < 0) { ++ nsshtb_explain1("r2q"); ++ return -1; ++ } ++ } else if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else if (strcmp(*argv, "help") == 0) { ++ nsshtb_explain_qdisc(); ++ return -1; ++ } else { ++ fprintf(stderr, "NSSHTB: What is \"%s\" ?\n", *argv); ++ nsshtb_explain_qdisc(); ++ return -1; ++ } ++ argc--, argv++; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_PPE; ++ } else if (opt.accel_mode >= TCA_NSS_ACCEL_MODE_MAX) { ++ fprintf(stderr, "accel_mode should be < %d\n", TCA_NSS_ACCEL_MODE_MAX); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSHTB_QDISC_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nsshtb_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSHTB_MAX + 1]; ++ struct tc_nsshtb_qopt *qopt; ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSHTB_MAX, opt); ++ ++ if (tb[TCA_NSSHTB_QDISC_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSHTB_QDISC_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSHTB_QDISC_PARMS]); ++ ++ if (qopt->r2q != 0) ++ fprintf(f, "r2q %u ", qopt->r2q); ++ ++ fprintf(f, "accel_mode %d ", qopt->accel_mode); ++ ++ return 0; ++} ++ ++static int nsshtb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ int ok = 0; ++ struct rtattr *tail; ++ struct tc_nsshtb_class_qopt opt; ++ int crate = 0; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "burst") == 0) { ++ NEXT_ARG(); ++ if (opt.burst) { ++ fprintf(stderr, "Double \"burst\" spec\n"); ++ return -1; ++ } ++ if (get_size(&opt.burst, *argv)) { ++ fprintf(stderr, "Illegal \"burst\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "rate") == 0) { ++ NEXT_ARG(); ++ if (opt.rate) { ++ fprintf(stderr, "Double \"rate\" spec\n"); ++ return -1; ++ } ++ if (get_rate(&opt.rate, *argv)) { ++ fprintf(stderr, "Illegal \"rate\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "cburst") == 0) { ++ NEXT_ARG(); ++ if (opt.cburst) { ++ fprintf(stderr, "Double \"cburst\" spec\n"); ++ return -1; ++ } ++ if (get_size(&opt.cburst, *argv)) { ++ fprintf(stderr, "Illegal \"cburst\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "crate") == 0) { ++ NEXT_ARG(); ++ if (opt.crate) { ++ fprintf(stderr, "Double \"crate\" spec\n"); ++ return -1; ++ } ++ if (get_rate(&opt.crate, *argv)) { ++ fprintf(stderr, "Illegal \"crate\"\n"); ++ return -1; ++ } ++ crate++; ++ ok++; ++ } else if (strcmp(*argv, "priority") == 0) { ++ NEXT_ARG(); ++ if (opt.priority) { ++ fprintf(stderr, "Double \"priority\" spec\n"); ++ return -1; ++ } ++ if (get_u32(&opt.priority, *argv, 10) < 0) { ++ fprintf(stderr, "Illegal \"priority\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "quantum") == 0) { ++ NEXT_ARG(); ++ if (opt.quantum) { ++ fprintf(stderr, "Double \"quantum\" spec\n"); ++ return -1; ++ } ++ if (get_size(&opt.quantum, *argv)) { ++ fprintf(stderr, "Illegal \"quantum\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "overhead") == 0) { ++ NEXT_ARG(); ++ if (opt.overhead) { ++ fprintf(stderr, "Double \"overhead\" spec\n"); ++ return -1; ++ } ++ if (get_size(&opt.overhead, *argv)) { ++ fprintf(stderr, "Illegal \"overhead\"\n"); ++ return -1; ++ } ++ ok++; ++ } else if (strcmp(*argv, "help") == 0) { ++ nsshtb_explain_class(); ++ return -1; ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ nsshtb_explain_class(); ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!ok) { ++ nsshtb_explain_class(); ++ return -1; ++ } ++ ++ if (opt.rate && !opt.burst) { ++ fprintf(stderr, "\"burst\" required if \"rate\" is specified.\n"); ++ return -1; ++ } ++ ++ if (!crate) { ++ fprintf(stderr, "\"crate\" is required.\n"); ++ return -1; ++ } ++ ++ if (opt.crate && !opt.cburst) { ++ fprintf(stderr, "\"cburst\" required if \"crate\" is non-zero.\n"); ++ return -1; ++ } ++ ++ if (opt.priority > 3) { ++ fprintf(stderr, "\"priority\" should be an integer between 0 and 3.\n"); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSHTB_CLASS_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nsshtb_print_class_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSHTB_MAX + 1]; ++ struct tc_nsshtb_class_qopt *qopt; ++ SPRINT_BUF(b1); ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSHTB_MAX, opt); ++ ++ if (tb[TCA_NSSHTB_CLASS_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSHTB_CLASS_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSHTB_CLASS_PARMS]); ++ ++ print_size(PRINT_FP, NULL, "burst %s ", qopt->burst); ++ tc_print_rate(PRINT_FP, NULL, "rate %s ", qopt->rate); ++ print_size(PRINT_FP, NULL, "cburst %s ", qopt->cburst); ++ tc_print_rate(PRINT_FP, NULL, "crate %s ", qopt->crate); ++ fprintf(f, "priority %u ", qopt->priority); ++ print_size(PRINT_FP, NULL, "quantum %s ", qopt->quantum); ++ print_size(PRINT_FP, NULL, "overhead %s ", qopt->overhead); ++ ++ return 0; ++} ++ ++struct qdisc_util nsshtb_qdisc_util = { ++ .id = "nsshtb", ++ .parse_qopt = nsshtb_parse_opt, ++ .print_qopt = nsshtb_print_opt, ++ .parse_copt = nsshtb_parse_class_opt, ++ .print_copt = nsshtb_print_class_opt, ++}; ++ ++/* ======================== NSSBLACKHOLE ======================= */ ++ ++static void nssblackhole_explain(void) ++{ ++ fprintf(stderr, "Usage: ... nssblackhole [ set_default ] [ accel_mode ]\n"); ++} ++ ++static int nssblackhole_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ struct rtattr *tail; ++ struct tc_nssblackhole_qopt opt; ++ bool accel_mode = false; ++ ++ memset(&opt, 0, sizeof(opt)); ++ ++ while (argc > 0) { ++ if (strcmp(*argv, "set_default") == 0) { ++ opt.set_default = 1; ++ } else if (strcmp(*argv, "accel_mode") == 0) { ++ NEXT_ARG(); ++ if (get_u8(&opt.accel_mode, *argv, 0)) { ++ fprintf(stderr, "Illegal accel_mode value\n"); ++ return -1; ++ } ++ accel_mode = true; ++ } else if (strcmp(*argv, "help") == 0) { ++ nssblackhole_explain(); ++ return -1; ++ } else { ++ fprintf(stderr, "What is \"%s\"?\n", *argv); ++ nssblackhole_explain(); ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ if (!accel_mode) { ++ opt.accel_mode = TCA_NSS_ACCEL_MODE_PPE; ++ } else if (opt.accel_mode >= TCA_NSS_ACCEL_MODE_MAX) { ++ fprintf(stderr, "accel_mode should be < %d\n", TCA_NSS_ACCEL_MODE_MAX); ++ return -1; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 1024, TCA_NSSBLACKHOLE_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ ++ return 0; ++} ++ ++static int nssblackhole_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_NSSBLACKHOLE_MAX + 1]; ++ struct tc_nssblackhole_qopt *qopt; ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_NSSBLACKHOLE_MAX, opt); ++ ++ if (tb[TCA_NSSBLACKHOLE_PARMS] == NULL) ++ return -1; ++ ++ if (RTA_PAYLOAD(tb[TCA_NSSBLACKHOLE_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_NSSBLACKHOLE_PARMS]); ++ ++ if (qopt->set_default) ++ fprintf(f, "set_default "); ++ ++ fprintf(f, "accel_mode %d ", qopt->accel_mode); ++ ++ return 0; ++} ++ ++struct qdisc_util nssblackhole_qdisc_util = { ++ .id = "nssblackhole", ++ .parse_qopt = nssblackhole_parse_opt, ++ .print_qopt = nssblackhole_print_opt, ++}; diff --git a/package/network/utils/iproute2/patches/500-add-nssmirred.patch b/package/network/utils/iproute2/patches/500-add-nssmirred.patch new file mode 100644 index 00000000000000..f4c3bc587d124c --- /dev/null +++ b/package/network/utils/iproute2/patches/500-add-nssmirred.patch @@ -0,0 +1,243 @@ +--- a/tc/Makefile ++++ b/tc/Makefile +@@ -50,6 +50,7 @@ TCMODULES += m_tunnel_key.o + TCMODULES += m_sample.o + TCMODULES += m_ct.o + TCMODULES += m_gate.o ++TCMODULES += m_nssmirred.o + TCMODULES += p_ip.o + TCMODULES += p_ip6.o + TCMODULES += p_icmp.o +--- /dev/null ++++ b/tc/m_nssmirred.c +@@ -0,0 +1,183 @@ ++/* ++ ************************************************************************** ++ * Copyright (c) 2019 The Linux Foundation. All rights reserved. ++ * Permission to use, copy, modify, and/or distribute this software for ++ * any purpose with or without fee is hereby granted, provided that the ++ * above copyright notice and this permission notice appear in all copies. ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT ++ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ ************************************************************************** ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "utils.h" ++#include "tc_util.h" ++#include "tc_common.h" ++#include ++ ++/* ++ * explain() ++ * API to print the explaination of nssmirred action statement's ++ * elements. ++ */ ++static void explain(void) ++{ ++ fprintf(stderr, "Usage: nssmirred redirect \n"); ++ fprintf(stderr, "where: \n"); ++ fprintf(stderr, "\tTO_DEVICENAME is the devicename to redirect to\n"); ++ fprintf(stderr, "\tFROM_DEVICENAME is the devicename to redirect from\n"); ++} ++ ++/* ++ * usage() ++ * API to show the usage of the nssmirred action. ++ */ ++static void usage(void) ++{ ++ explain(); ++ exit(-1); ++} ++ ++/* ++ * parse_nss_mirred() ++ * Parse and validate the nssmirred action statement. ++ */ ++static int parse_nss_mirred(struct action_util *a, int *argc_p, char ***argv_p, ++ int tca_id, struct nlmsghdr *n) ++{ ++ int idx, argc = *argc_p; ++ char **argv = *argv_p; ++ struct tc_nss_mirred p; ++ struct rtattr *tail; ++ ++ if (argc < 0) { ++ fprintf(stderr, "nssmirred bad argument count %d. Try option \"help\"\n", argc); ++ goto error; ++ } ++ ++ if (matches(*argv, "nssmirred")) { ++ fprintf(stderr, "nssmirred bad argument %s. Try option \"help\"\n", *argv); ++ goto error; ++ } ++ ++ NEXT_ARG(); ++ if (!matches(*argv, "help")) { ++ usage(); ++ } ++ ++ if (matches(*argv, "redirect")) { ++ fprintf(stderr, "nssmirred bad argument %s. Try option \"help\"\n", *argv); ++ goto error; ++ } ++ ++ NEXT_ARG(); ++ if (matches(*argv, "dev")) { ++ fprintf(stderr, "nssmirred: bad value %s. Try option \"help\"\n", *argv); ++ goto error; ++ } ++ ++ NEXT_ARG(); ++ memset(&p, 0, sizeof(struct tc_nss_mirred)); ++ if ((idx = ll_name_to_index(*argv)) == 0) { ++ fprintf(stderr, "Cannot find to device \"%s\"\n", *argv); ++ goto error; ++ } ++ ++ p.to_ifindex = idx; ++ NEXT_ARG(); ++ if (matches(*argv, "fromdev")) { ++ fprintf(stderr, "nssmirred: bad value %s. Try option \"help\"\n", *argv); ++ goto error; ++ } ++ ++ NEXT_ARG(); ++ if ((idx = ll_name_to_index(*argv)) == 0) { ++ fprintf(stderr, "Cannot find from device \"%s\"\n", *argv); ++ goto error; ++ } ++ ++ p.from_ifindex = idx; ++ p.action = TC_ACT_STOLEN; ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, MAX_MSG, tca_id, NULL, 0); ++ addattr_l(n, MAX_MSG, TCA_NSS_MIRRED_PARMS, &p, sizeof (p)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ argc--; ++ argv++; ++ *argc_p = argc; ++ *argv_p = argv; ++ return 0; ++ ++error: ++ return -1; ++} ++ ++/* ++ * print_nss_mirred() ++ * Print information related to nssmirred action. ++ */ ++static int print_nss_mirred(struct action_util *au, FILE * f, struct rtattr *arg) ++{ ++ struct tc_nss_mirred *p; ++ struct rtattr *tb[TCA_NSS_MIRRED_MAX + 1]; ++ const char *from_dev, *to_dev; ++ ++ if (arg == NULL) { ++ return -1; ++ } ++ ++ parse_rtattr_nested(tb, TCA_NSS_MIRRED_MAX, arg); ++ ++ if (tb[TCA_NSS_MIRRED_PARMS] == NULL) { ++ fprintf(f, "[NULL nssmirred parameters]"); ++ goto error; ++ } ++ ++ p = RTA_DATA(tb[TCA_NSS_MIRRED_PARMS]); ++ if ((from_dev = ll_index_to_name(p->from_ifindex)) == 0) { ++ fprintf(stderr, "Invalid interface (index: %d)\n", p->from_ifindex); ++ goto error; ++ } ++ ++ if ((to_dev = ll_index_to_name(p->to_ifindex)) == 0) { ++ fprintf(stderr, "Invalid interface (index: %d)\n", p->to_ifindex); ++ goto error; ++ } ++ ++ fprintf(f, "nssmirred (%s to device %s) stolen\n", from_dev, to_dev); ++ fprintf(f, "\tindex %d ref %d bind %d\n",p->index,p->refcnt,p->bindcnt); ++ ++ if (show_stats) { ++ if (tb[TCA_NSS_MIRRED_TM]) { ++ struct tcf_t *tm = RTA_DATA(tb[TCA_NSS_MIRRED_TM]); ++ print_tm(f,tm); ++ } ++ } ++ return 0; ++ ++error: ++ return -1; ++} ++ ++/* ++ * nssmirred_action_util ++ * nssmirred action utility structure. ++ */ ++struct action_util nssmirred_action_util = { ++ .id = "nssmirred", ++ .parse_aopt = parse_nss_mirred, ++ .print_aopt = print_nss_mirred, ++}; +--- /dev/null ++++ b/include/linux/tc_act/tc_nssmirred.h +@@ -0,0 +1,44 @@ ++/* ++ ************************************************************************** ++ * Copyright (c) 2019 The Linux Foundation. All rights reserved. ++ * Permission to use, copy, modify, and/or distribute this software for ++ * any purpose with or without fee is hereby granted, provided that the ++ * above copyright notice and this permission notice appear in all copies. ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT ++ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ ************************************************************************** ++ */ ++ ++#ifndef __LINUX_TC_NSS_MIR_H ++#define __LINUX_TC_NSS_MIR_H ++ ++#include ++#include ++ ++/* ++ * tc_nss_mirred ++ * Structure for nssmirred action. ++ */ ++struct tc_nss_mirred { ++ tc_gen; ++ __u32 from_ifindex; /* ifindex of the port to be redirected from */ ++ __u32 to_ifindex; /* ifindex of the port to be redirected to */ ++}; ++ ++/* ++ * Types of nssmirred action parameters. ++ */ ++enum { ++ TCA_NSS_MIRRED_UNSPEC, ++ TCA_NSS_MIRRED_TM, ++ TCA_NSS_MIRRED_PARMS, ++ __TCA_NSS_MIRRED_MAX ++}; ++#define TCA_NSS_MIRRED_MAX (__TCA_NSS_MIRRED_MAX - 1) ++ ++#endif /* __LINUX_TC_NSS_MIR_H */ From e9c241b296cb4f45821af8bb329f56eca65e0fa7 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 02:01:58 +0300 Subject: [PATCH 188/225] qualcommax: dts: add NSS nodes to IPQ807x devices Signed-off-by: bitthief qualcommax: dts: provide label for NSS reserved-memory Provide a label for the NSS reserved-memory node so it can be easily passed to the NSS DRV instead of having to global match by name which is fragile. Signed-off-by: bitthief --- .../arm64/boot/dts/qcom/ipq8070-cax1800.dts | 1 + .../arm64/boot/dts/qcom/ipq8071-ax3600.dtsi | 1 + .../arm64/boot/dts/qcom/ipq8071-eap102.dts | 1 + .../arch/arm64/boot/dts/qcom/ipq8072-301w.dts | 1 + .../arm64/boot/dts/qcom/ipq8072-ax9000.dts | 1 + .../arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts | 1 + .../arch/arm64/boot/dts/qcom/ipq8072-haze.dts | 1 + .../arm64/boot/dts/qcom/ipq8072-wax218.dts | 1 + .../arm64/boot/dts/qcom/ipq8072-wax620.dts | 1 + .../arm64/boot/dts/qcom/ipq8072-wpq873.dts | 1 + .../arm64/boot/dts/qcom/ipq8074-nbg7815.dts | 1 + .../arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi | 271 ++++++++++++++++++ .../arm64/boot/dts/qcom/ipq8074-rax120v2.dts | 1 + .../arm64/boot/dts/qcom/ipq8074-wax630.dts | 1 + .../boot/dts/qcom/ipq8074-wxr-5950ax12.dts | 1 + ...ts-ipq8074-add-reserved-memory-nodes.patch | 6 +- 16 files changed, 288 insertions(+), 3 deletions(-) create mode 100644 target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts index e62ae314fb5d82..4359c3d5b1c8fd 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts @@ -6,6 +6,7 @@ #include "ipq8074-512m.dtsi" #include "ipq8074-ac-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi index 6afafb35546e00..c2c5f4ce8362c0 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi @@ -4,6 +4,7 @@ #include "ipq8074-512m.dtsi" #include "ipq8074-ac-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-eap102.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-eap102.dts index d55904a24a447b..ba03e147fbf799 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-eap102.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-eap102.dts @@ -6,6 +6,7 @@ #include "ipq8074.dtsi" #include "ipq8074-ac-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-301w.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-301w.dts index 2fe723591e77f4..0c80020cd1b373 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-301w.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-301w.dts @@ -6,6 +6,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts index ec66d47d16a93f..fe5a1367226177 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts @@ -6,6 +6,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts index c5c089c00f7dd4..24dd51b47fc585 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts @@ -6,6 +6,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-haze.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-haze.dts index 289680d678be07..3c63c0b00350bc 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-haze.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-haze.dts @@ -5,6 +5,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts index 0e71faea72a220..2c1e0f5e472fdb 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts @@ -3,6 +3,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax620.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax620.dts index ceb719d81322e1..66bf68eb656460 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax620.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax620.dts @@ -5,6 +5,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wpq873.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wpq873.dts index 5b2c1d570fd943..ebc68e15a840e1 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wpq873.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wpq873.dts @@ -6,6 +6,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts index b18f38cc6cf4dc..1390b3a286b166 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts @@ -9,6 +9,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi new file mode 100644 index 00000000000000..d85a37230a0e04 --- /dev/null +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi @@ -0,0 +1,271 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/ { + nss_dummy_reg: nss-regulator { + compatible = "regulator-fixed"; + regulator-name = "nss-reg"; + regulator-min-microvolt = <848000>; + regulator-max-microvolt = <848000>; + regulator-always-on; + regulator-boot-on; + }; +}; + +&soc { + nss-common { + compatible = "qcom,nss-common"; + reg = <0x01868010 0x1000>; + reg-names = "nss-misc-reset"; + memory-region = <&nss_region>; + }; + + nss0: nss@40000000 { + compatible = "qcom,nss"; + interrupts = , + , + , + , + , + , + , + , + , + ; + reg = <0x39000000 0x1000>, + <0x38000000 0x30000>, + <0x0b111000 0x1000>; + reg-names = "nphys", "vphys", "qgic-phys"; + clocks = <&gcc GCC_NSS_NOC_CLK>, + <&gcc GCC_NSS_PTP_REF_CLK>, + <&gcc GCC_NSS_CSR_CLK>, + <&gcc GCC_NSS_CFG_CLK>, + <&gcc GCC_NSS_IMEM_CLK>, + <&gcc GCC_NSSNOC_QOSGEN_REF_CLK>, + <&gcc GCC_MEM_NOC_NSS_AXI_CLK>, + <&gcc GCC_NSSNOC_SNOC_CLK>, + <&gcc GCC_NSSNOC_TIMEOUT_REF_CLK>, + <&gcc GCC_NSS_CE_AXI_CLK>, + <&gcc GCC_NSS_CE_APB_CLK>, + <&gcc GCC_NSSNOC_CE_AXI_CLK>, + <&gcc GCC_NSSNOC_CE_APB_CLK>, + <&gcc GCC_NSSNOC_UBI0_AHB_CLK>, + <&gcc GCC_UBI0_CORE_CLK>, + <&gcc GCC_UBI0_AHB_CLK>, + <&gcc GCC_UBI0_AXI_CLK>, + <&gcc GCC_UBI0_MPT_CLK>, + <&gcc GCC_UBI0_NC_AXI_CLK>; + clock-names = "nss-noc-clk", + "nss-ptp-ref-clk", + "nss-csr-clk", + "nss-cfg-clk", + "nss-imem-clk", + "nss-nssnoc-qosgen-ref-clk", + "nss-mem-noc-nss-axi-clk", + "nss-nssnoc-snoc-clk", + "nss-nssnoc-timeout-ref-clk", + "nss-ce-axi-clk", + "nss-ce-apb-clk", + "nss-nssnoc-ce-axi-clk", + "nss-nssnoc-ce-apb-clk", + "nss-nssnoc-ahb-clk", + "nss-core-clk", + "nss-ahb-clk", + "nss-axi-clk", + "nss-mpt-clk", + "nss-nc-axi-clk"; + qcom,id = <0>; + qcom,num-queue = <4>; + qcom,num-irq = <10>; + qcom,num-pri = <4>; + qcom,load-addr = <0x40000000>; + qcom,low-frequency = <187200000>; + qcom,mid-frequency = <748800000>; + qcom,max-frequency = <1689600000>; + qcom,bridge-enabled; + qcom,ipv4-enabled; + qcom,ipv4-reasm-enabled; + qcom,ipv6-enabled; + qcom,ipv6-reasm-enabled; + qcom,wlanredirect-enabled; + qcom,tun6rd-enabled; + qcom,l2tpv2-enabled; + qcom,gre-enabled; + qcom,gre-redir-enabled; + qcom,gre-redir-mark-enabled; + qcom,map-t-enabled; + qcom,portid-enabled; + qcom,ppe-enabled; + qcom,pppoe-enabled; + qcom,pptp-enabled; + qcom,tunipip6-enabled; + qcom,shaping-enabled; + qcom,wlan-dataplane-offload-enabled; + qcom,vlan-enabled; + qcom,igs-enabled; + qcom,vxlan-enabled; + qcom,match-enabled; + qcom,mirror-enabled; + qcom,udp-st-enabled; + mx-supply = <&nss_dummy_reg>; + npu-supply = <&nss_dummy_reg>; + }; + + nss1: nss@40800000 { + compatible = "qcom,nss"; + interrupts = , + , + , + , + , + , + , + , + ; + reg = <0x39400000 0x1000>, + <0x38030000 0x30000>, + <0x0b111000 0x1000>; + reg-names = "nphys", "vphys", "qgic-phys"; + clocks = <&gcc GCC_NSS_NOC_CLK>, + <&gcc GCC_NSS_PTP_REF_CLK>, + <&gcc GCC_NSS_CSR_CLK>, + <&gcc GCC_NSS_CFG_CLK>, + <&gcc GCC_NSS_IMEM_CLK>, + <&gcc GCC_NSSNOC_QOSGEN_REF_CLK>, + <&gcc GCC_MEM_NOC_NSS_AXI_CLK>, + <&gcc GCC_NSSNOC_SNOC_CLK>, + <&gcc GCC_NSSNOC_TIMEOUT_REF_CLK>, + <&gcc GCC_NSS_CE_AXI_CLK>, + <&gcc GCC_NSS_CE_APB_CLK>, + <&gcc GCC_NSSNOC_CE_AXI_CLK>, + <&gcc GCC_NSSNOC_CE_APB_CLK>, + <&gcc GCC_NSSNOC_UBI1_AHB_CLK>, + <&gcc GCC_UBI1_CORE_CLK>, + <&gcc GCC_UBI1_AHB_CLK>, + <&gcc GCC_UBI1_AXI_CLK>, + <&gcc GCC_UBI1_MPT_CLK>, + <&gcc GCC_UBI1_NC_AXI_CLK>; + clock-names = "nss-noc-clk", + "nss-ptp-ref-clk", + "nss-csr-clk", + "nss-cfg-clk", + "nss-imem-clk", + "nss-nssnoc-qosgen-ref-clk", + "nss-mem-noc-nss-axi-clk", + "nss-nssnoc-snoc-clk", + "nss-nssnoc-timeout-ref-clk", + "nss-ce-axi-clk", + "nss-ce-apb-clk", + "nss-nssnoc-ce-axi-clk", + "nss-nssnoc-ce-apb-clk", + "nss-nssnoc-ahb-clk", + "nss-core-clk", + "nss-ahb-clk", + "nss-axi-clk", + "nss-mpt-clk", + "nss-nc-axi-clk"; + qcom,id = <1>; + qcom,num-queue = <4>; + qcom,num-irq = <9>; + qcom,num-pri = <4>; + qcom,load-addr = <0x40800000>; + qcom,capwap-enabled; + qcom,dtls-enabled; + qcom,tls-enabled; + qcom,crypto-enabled; + qcom,ipsec-enabled; + qcom,qvpn-enabled; + qcom,pvxlan-enabled; + qcom,clmap-enabled; + qcom,rmnet_rx-enabled; + }; + + nss_crypto: qcom,nss_crypto { + compatible = "qcom,nss-crypto"; + #address-cells = <1>; + #size-cells = <1>; + qcom,max-contexts = <64>; + qcom,max-context-size = <32>; + ranges; + + eip197_node { + compatible = "qcom,eip197"; + reg-names = "crypto_pbase"; + reg = <0x39800000 0x7ffff>; + clocks = <&gcc GCC_NSS_CRYPTO_CLK>, + <&gcc GCC_NSSNOC_CRYPTO_CLK>, + <&gcc GCC_CRYPTO_PPE_CLK>; + clock-names = "crypto_clk", + "crypto_nocclk", + "crypto_ppeclk"; + clock-frequency = /bits/ 64 <600000000 600000000 300000000>; + qcom,dma-mask = <0xff>; + qcom,transform-enabled; + qcom,aes128-cbc; + qcom,aes192-cbc; + qcom,aes256-cbc; + qcom,aes128-ctr; + qcom,aes192-ctr; + qcom,aes256-ctr; + qcom,aes128-ecb; + qcom,aes192-ecb; + qcom,aes256-ecb; + qcom,3des-cbc; + qcom,md5-hash; + qcom,sha160-hash; + qcom,sha224-hash; + qcom,sha384-hash; + qcom,sha512-hash; + qcom,sha256-hash; + qcom,md5-hmac; + qcom,sha160-hmac; + qcom,sha224-hmac; + qcom,sha256-hmac; + qcom,sha384-hmac; + qcom,sha512-hmac; + qcom,aes128-gcm-gmac; + qcom,aes192-gcm-gmac; + qcom,aes256-gcm-gmac; + qcom,aes128-cbc-md5-hmac; + qcom,aes128-cbc-sha160-hmac; + qcom,aes192-cbc-md5-hmac; + qcom,aes192-cbc-sha160-hmac; + qcom,aes256-cbc-md5-hmac; + qcom,aes256-cbc-sha160-hmac; + qcom,aes128-ctr-sha160-hmac; + qcom,aes192-ctr-sha160-hmac; + qcom,aes256-ctr-sha160-hmac; + qcom,aes128-ctr-md5-hmac; + qcom,aes192-ctr-md5-hmac; + qcom,aes256-ctr-md5-hmac; + qcom,3des-cbc-md5-hmac; + qcom,3des-cbc-sha160-hmac; + qcom,aes128-cbc-sha256-hmac; + qcom,aes192-cbc-sha256-hmac; + qcom,aes256-cbc-sha256-hmac; + qcom,aes128-ctr-sha256-hmac; + qcom,aes192-ctr-sha256-hmac; + qcom,aes256-ctr-sha256-hmac; + qcom,3des-cbc-sha256-hmac; + qcom,aes128-cbc-sha384-hmac; + qcom,aes192-cbc-sha384-hmac; + qcom,aes256-cbc-sha384-hmac; + qcom,aes128-ctr-sha384-hmac; + qcom,aes192-ctr-sha384-hmac; + qcom,aes256-ctr-sha384-hmac; + qcom,aes128-cbc-sha512-hmac; + qcom,aes192-cbc-sha512-hmac; + qcom,aes256-cbc-sha512-hmac; + qcom,aes128-ctr-sha512-hmac; + qcom,aes192-ctr-sha512-hmac; + qcom,aes256-ctr-sha512-hmac; + + engine0 { + reg_offset = <0x80000>; + qcom,ifpp-enabled; + qcom,ipue-enabled; + qcom,ofpp-enabled; + qcom,opue-enabled; + }; + }; + }; +}; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-rax120v2.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-rax120v2.dts index ceb47f14fdd0a2..9fca32578d769a 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-rax120v2.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-rax120v2.dts @@ -4,6 +4,7 @@ #include "ipq8074.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include "ipq8074-hk-cpu.dtsi" #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wax630.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wax630.dts index 3393efd7b550f3..d241ae642acbac 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wax630.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wax630.dts @@ -5,6 +5,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts index d8237e81dde950..dfe27a99d18e64 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts @@ -5,6 +5,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/patches-6.6/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch b/target/linux/qualcommax/patches-6.6/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch index 6d97641f658cc1..64f8da87aadedb 100644 --- a/target/linux/qualcommax/patches-6.6/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch +++ b/target/linux/qualcommax/patches-6.6/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch @@ -22,8 +22,8 @@ Signed-off-by: Robert Marko @@ -86,6 +86,16 @@ #size-cells = <2>; ranges; - -+ nss@40000000 { + ++ nss_region: nss@40000000 { + no-map; + reg = <0x0 0x40000000 0x0 0x01000000>; + }; @@ -56,5 +56,5 @@ Signed-off-by: Robert Marko + reg = <0x0 0x51000000 0x0 0x100000>; + }; }; - + firmware { From a8cc29f2dda0c56907c200ce4b21c81fdb478d06 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 01:24:45 +0300 Subject: [PATCH 189/225] qualcommax: net: QCA NSS igs support Signed-off-by: bitthief --- .../include/uapi/linux/tc_act/tc_nss_mirred.h | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 target/linux/qualcommax/files/include/uapi/linux/tc_act/tc_nss_mirred.h diff --git a/target/linux/qualcommax/files/include/uapi/linux/tc_act/tc_nss_mirred.h b/target/linux/qualcommax/files/include/uapi/linux/tc_act/tc_nss_mirred.h new file mode 100644 index 00000000000000..3a368fcc8c17ee --- /dev/null +++ b/target/linux/qualcommax/files/include/uapi/linux/tc_act/tc_nss_mirred.h @@ -0,0 +1,36 @@ +#ifndef __LINUX_TC_NSS_MIRRED_H +#define __LINUX_TC_NSS_MIRRED_H + +#include + +/* + * Type of nss mirred action. + */ +#define TCA_ACT_MIRRED_NSS 17 + +/* + * Types of parameters for nss mirred action. + */ +enum { + TC_NSS_MIRRED_UNSPEC, + TC_NSS_MIRRED_TM, + TC_NSS_MIRRED_PARMS, + __TC_NSS_MIRRED_MAX +}; +#define TC_NSS_MIRRED_MAX (__TC_NSS_MIRRED_MAX - 1) + +/* + * tc_nss_mirred + * tc command structure for nss mirred action. + */ +struct tc_nss_mirred { + tc_gen; /* General tc structure. */ + __u32 from_ifindex; /* ifindex of the port from which traffic + * will be redirected. + */ + __u32 to_ifindex; /* ifindex of the port to which traffic + * will be redirected. + */ +}; + +#endif /* __LINUX_TC_NSS_MIRRED_H */ From 4eaacbdcf8a6acdc29359a8137f6b1066bbddca2 Mon Sep 17 00:00:00 2001 From: bitthief Date: Tue, 18 Jul 2023 01:25:01 +0300 Subject: [PATCH 190/225] qualcommax: net: QCA NSS qdisc ifb support Signed-off-by: bitthief --- .../netfilter/nf_conntrack_dscpremark_ext.h | 95 +++++++++++++++++++ .../netfilter/nf_conntrack_dscpremark_ext.c | 61 ++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 target/linux/qualcommax/files/include/net/netfilter/nf_conntrack_dscpremark_ext.h create mode 100644 target/linux/qualcommax/files/net/netfilter/nf_conntrack_dscpremark_ext.c diff --git a/target/linux/qualcommax/files/include/net/netfilter/nf_conntrack_dscpremark_ext.h b/target/linux/qualcommax/files/include/net/netfilter/nf_conntrack_dscpremark_ext.h new file mode 100644 index 00000000000000..dc6a5004ef6d7a --- /dev/null +++ b/target/linux/qualcommax/files/include/net/netfilter/nf_conntrack_dscpremark_ext.h @@ -0,0 +1,95 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* DSCP remark conntrack extension APIs. */ + +#ifndef _NF_CONNTRACK_DSCPREMARK_H +#define _NF_CONNTRACK_DSCPREMARK_H + +#include +#include + +/* Rule flags */ +#define NF_CT_DSCPREMARK_EXT_DSCP_RULE_VALID 0x1 + +/* Rule validity */ +#define NF_CT_DSCPREMARK_EXT_RULE_VALID 0x1 +#define NF_CT_DSCPREMARK_EXT_RULE_NOT_VALID 0x0 + +/* Which QoS features are set flags */ +#define NF_CT_DSCPREMARK_EXT_PRIO 0x1 +#define NF_CT_DSCPREMARK_EXT_DSCP 0x2 +#define NF_CT_DSCPREMARK_EXT_IGS_QOS 0x4 +#define NF_CT_DSCPREMARK_EXT_MARK 0x8 + +/* + * DSCP remark conntrack extension structure. + */ +struct nf_ct_dscpremark_ext { + __u32 flow_priority; /* Original direction packet priority */ + __u32 reply_priority; /* Reply direction packet priority */ + __u32 flow_mark; /* Original direction packet mark */ + __u32 reply_mark; /* Reply direction packet mark */ + __u16 igs_flow_qos_tag; /* Original direction ingress packet priority */ + __u16 igs_reply_qos_tag; /* Reply direction ingress packet priority */ + __u8 flow_dscp; /* IP DSCP value for original direction */ + __u8 reply_dscp; /* IP DSCP value for reply direction */ + __u16 rule_flags; /* Rule Validity flags */ + __u16 flow_set_flags; /* Original direction set flags */ + __u16 return_set_flags; /* Reply direction set flags */ +}; + +/* + * nf_ct_dscpremark_ext_find() + * Finds the extension data of the conntrack entry if it exists. + */ +static inline struct nf_ct_dscpremark_ext * +nf_ct_dscpremark_ext_find(const struct nf_conn *ct) +{ +#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT + return nf_ct_ext_find(ct, NF_CT_EXT_DSCPREMARK); +#else + return NULL; +#endif +} + +/* + * nf_ct_dscpremark_ext_add() + * Adds the extension data to the conntrack entry. + */ +static inline +struct nf_ct_dscpremark_ext *nf_ct_dscpremark_ext_add(struct nf_conn *ct, + gfp_t gfp) +{ +#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT + struct nf_ct_dscpremark_ext *ncde; + + ncde = nf_ct_ext_add(ct, NF_CT_EXT_DSCPREMARK, gfp); + if (!ncde) + return NULL; + + return ncde; +#else + return NULL; +#endif +}; + +#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT +extern int nf_conntrack_dscpremark_ext_set_dscp_rule_valid(struct nf_conn *ct); +extern int nf_conntrack_dscpremark_ext_get_dscp_rule_validity(struct nf_conn *ct); +#endif /* CONFIG_NF_CONNTRACK_DSCPREMARK_EXT */ +#endif /* _NF_CONNTRACK_DSCPREMARK_H */ diff --git a/target/linux/qualcommax/files/net/netfilter/nf_conntrack_dscpremark_ext.c b/target/linux/qualcommax/files/net/netfilter/nf_conntrack_dscpremark_ext.c new file mode 100644 index 00000000000000..678d27ac9df9c2 --- /dev/null +++ b/target/linux/qualcommax/files/net/netfilter/nf_conntrack_dscpremark_ext.c @@ -0,0 +1,61 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* DSCP remark handling conntrack extension registration. */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +/* nf_conntrack_dscpremark_ext_set_dscp_rule_valid() + * Set DSCP rule validity flag in the extension + */ +int nf_conntrack_dscpremark_ext_set_dscp_rule_valid(struct nf_conn *ct) +{ + struct nf_ct_dscpremark_ext *ncde; + + ncde = nf_ct_dscpremark_ext_find(ct); + if (!ncde) + return -1; + + ncde->rule_flags = NF_CT_DSCPREMARK_EXT_DSCP_RULE_VALID; + return 0; +} +EXPORT_SYMBOL(nf_conntrack_dscpremark_ext_set_dscp_rule_valid); + +/* nf_conntrack_dscpremark_ext_get_dscp_rule_validity() + * Check if the DSCP rule flag is valid from the extension + */ +int nf_conntrack_dscpremark_ext_get_dscp_rule_validity(struct nf_conn *ct) +{ + struct nf_ct_dscpremark_ext *ncde; + + ncde = nf_ct_dscpremark_ext_find(ct); + if (!ncde) + return NF_CT_DSCPREMARK_EXT_RULE_NOT_VALID; + + if (ncde->rule_flags & NF_CT_DSCPREMARK_EXT_DSCP_RULE_VALID) + return NF_CT_DSCPREMARK_EXT_RULE_VALID; + + return NF_CT_DSCPREMARK_EXT_RULE_NOT_VALID; +} +EXPORT_SYMBOL(nf_conntrack_dscpremark_ext_get_dscp_rule_validity); From 6066b1a16a371dc4a5b07df0650f440195aaaa2a Mon Sep 17 00:00:00 2001 From: dimfish Date: Wed, 2 Aug 2023 11:43:48 +0300 Subject: [PATCH 191/225] feeds: use forked dimfishr/nss-packages --- feeds.conf.default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feeds.conf.default b/feeds.conf.default index e0bad42753507c..4699f733f878e2 100644 --- a/feeds.conf.default +++ b/feeds.conf.default @@ -2,7 +2,7 @@ src-git packages https://git.openwrt.org/feed/packages.git src-git luci https://git.openwrt.org/project/luci.git src-git routing https://git.openwrt.org/feed/routing.git src-git telephony https://git.openwrt.org/feed/telephony.git -src-git nss_packages https://github.com/bitthief/nss-packages.git +src-git nss_packages https://github.com/dimfishr/nss-packages.git #src-git video https://github.com/openwrt/video.git #src-git targets https://github.com/openwrt/targets.git #src-git oldpackages http://git.openwrt.org/packages.git From 0e58a1cbdb56cbf87174b5008ce39cc22a209281 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 16 Dec 2023 18:09:40 -0500 Subject: [PATCH 192/225] ath11k-nss: Add NSS WiFi feature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Attempt at getting NSS WiFi Offload working on kernel 6.1 (backport 6.5) These patches are a mix of @ansuel branch for 5.15 (ipq807x-5.15-ecm-wifi) https://github.com/Ansuel/openwrt/commit/3ecaee768e8d08d20eaf2a554eb2bf1da9bbf21b And QUIC's upstream NSS patches on [NHSS.QSDK.12.4.5.r3](https://git.codelinaro.org/clo/qsdk/oss/system/feeds/wlan-open.git) For the actual package setup (Makfiles,ath.mk) Qualcomm's branch is under 'wlan-open/NHSS.QSDK.12.4.5.r3' Looks like they've swtiched to using backports 6.5-rc3, and figured to use a mix of their patches on 'NHSS.QSDK.12.4.5.r3' (nss) 'wlan-open/NHSS.QSDK.12.4.5.r3' (syncing with openwrt main). Booting with "nss_offload=1 frame_mode=2" Logs show: [ 16.606282] WARNING: CPU: 2 PID: 3524 at ath11k_nss_tx+0x1d4/0x1e0 [ath11k] [ 16.611060] Modules linked in: ecm pppoe ppp_async nft_fib_inet nf_flow_table_inet ath11k_ahb ath11k pptp pppox ppp_generic nft_reject_ipv6 nft_reject_ipv4 nft_reject_inet nft_reject nft_redir nft_quota nft_objref nft_numgen nft_nat nft_masq nft_log nft_limit nft_hash nft_fullcone nft_flow_offload nft_fib_ipv6 nft_fib_ipv4 nft_fib nft_ct nft_compat nft_chain_nat nf_tables nf_nat nf_flow_table nf_conntrack_netlink nf_conntrack mac80211 iptable_mangle iptable_filter ipt_REJECT ipt_ECN ip_tables cfg80211 xt_time xt_tcpudp xt_tcpmss xt_statistic xt_multiport xt_mark xt_mac xt_limit xt_length xt_hl xt_ecn xt_dscp xt_comment xt_TCPMSS xt_LOG xt_HL xt_DSCP xt_CLASSIFY x_tables wireguard slhc sch_cake qrtr_smd qrtr qmi_helpers nfnetlink nf_reject_ipv6 nf_reject_ipv4 nf_log_syslog nf_defrag_ipv4 mhi libcrc32c libchacha20poly1305 compat sch_tbf sch_ingress sch_htb sch_hfsc em_u32 cls_u32 cls_route cls_matchall cls_fw cls_flow cls_basic act_skbedit act_mirred act_gact qca_nss_cfi_cryptoapi [ 16.611215] qca_nss_crypto qca_nss_qdisc qca_nss_wifi_meshmgr qca_nss_gre ledtrig_usbport qca_mcs bonding ip6_gre ip_gre gre ifb nat46 nf_defrag_ipv6 sit qca_nss_drv ip6_tunnel tunnel6 tunnel4 nls_utf8 nls_iso8859_1 nls_cp437 vxlan seqiv michael_mic uas usb_storage leds_gpio xhci_plat_hcd xhci_pci xhci_hcd dwc3 dwc3_qcom qca_nss_dp qca_ssdk ramoops reed_solomon pstore gpio_button_hotplug ext4 mbcache jbd2 aquantia hwmon crc_ccitt crc32c_generic [ 16.721723] CPU: 2 PID: 3524 Comm: hostapd Not tainted 6.1.68 #0 [ 16.743958] Hardware name: Dynalink DL-WRX36 (DT) [ 16.750032] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 16.754635] pc : ath11k_nss_tx+0x1d4/0x1e0 [ath11k] [ 16.761403] lr : ath11k_nss_tx+0x1bc/0x1e0 [ath11k] [ 16.766264] sp : ffffffc00b1db790 [ 16.771122] x29: ffffffc00b1db790 x28: 0000000000000038 x27: 0000000000000000 [ 16.774602] x26: ffffff8006dd7430 x25: ffffff8007ea9dc8 x24: 0000000060000012 [ 16.781719] x23: ffffff8005c6a060 x22: ffffff8005c6a060 x21: ffffff80072f12d8 [ 16.788837] x20: ffffff8007ea9dc8 x19: ffffff8006082800 x18: 0000000000000005 [ 16.795957] x17: 6976312065707974 x16: 207061636e652062 x15: 6b73207874207373 [ 16.803075] x14: ffffffc00a0dd518 x13: 000000000000018b x12: 000000000000018b [ 16.810192] x11: 00000000ffffffea x10: ffffffc00a135518 x9 : 0000000000000001 [ 16.817310] x8 : 0000000000000001 x7 : 0000000000017fe8 x6 : c0000000ffffefff [ 16.824429] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000 [ 16.831547] x2 : ffffff80072f1370 x1 : 0000000000000000 x0 : 0000000000000001 [ 16.838665] Call trace: [ 16.845774] ath11k_nss_tx+0x1d4/0x1e0 [ath11k] [ 16.848035] ath11k_mac_tx_mgmt_pending_free+0x3034/0x9600 [ath11k] [ 16.852551] ieee80211_handle_wake_tx_queue+0x68/0xb10 [mac80211] [ 16.858801] ieee80211_probereq_get+0xca4/0x11f0 [mac80211] [ 16.865049] ieee80211_tx_prepare_skb+0x1dc/0x240 [mac80211] [ 16.870432] ieee80211_xmit+0xcc/0x120 [mac80211] [ 16.876333] __ieee80211_subif_start_xmit+0x2b8/0x380 [mac80211] [ 16.880937] ieee80211_subif_start_xmit+0x40/0x3b0 [mac80211] [ 16.887013] ieee80211_subif_start_xmit_8023+0xb8/0x430 [mac80211] [ 16.892656] dev_hard_start_xmit+0x8c/0x110 [ 16.898728] __dev_queue_xmit+0x1f0/0xbc0 [ 16.902808] dev_queue_xmit+0x14/0x20 [ 16.906975] packet_sendmsg+0x768/0x1260 [ 16.910620] __sys_sendto+0xdc/0x140 [ 16.914613] __arm64_sys_sendto+0x28/0x40 [ 16.918174] invoke_syscall.constprop.0+0x5c/0x110 [ 16.922081] do_el0_svc+0x58/0x170 [ 16.926765] el0_svc+0x18/0x60 [ 16.930149] el0t_64_sync_handler+0x114/0x120 [ 16.933190] el0t_64_sync+0x174/0x178 [ 16.933197] ---[ end trace 0000000000000000 ]--- [ 16.933230] ath11k c000000.wifi: failed to transmit frame -22 [ 17.041495] ath11k c000000.wifi: encap mismatch in nss tx skb encap type 1vif encap type 2 [ 17.041578] ath11k c000000.wifi: failed to transmit frame -22 Which is confusing since the parameter is definitley set to '2'. ➤ cat /sys/module/ath11k/parameters/frame_mode 2 Booting with either "nss_offload=1 frame_mode=3" (RAW), or "nss_offload=1 frame_mode=1" (Native Wifi) Results in: [ 15.644742] ath11k c000000.wifi: peer not found for nss peer delete [ 15.744742] ath11k c000000.wifi: peer not found for nss peer delete [ 15.745742] ath11k c000000.wifi: peer not found for nss peer delete [ 15.746682] ath11k c000000.wifi: peer not found for nss peer delete Clients connect and then are immediately kicked off, stuck in a loop. ath11k-nss: Wifi offloading working (unstable) Wifi offloading seems to be working, however it is not stable. Logs will initially show a lot of flooding. ``` [Sun Dec 17 02:43:25 2023] ath11k c000000.wifi: peer not found for nss peer delete [Sun Dec 17 02:43:28 2023] ath11k c000000.wifi: peer not found for nss peer delete [Sun Dec 17 02:43:30 2023] ath11k c000000.wifi: peer not found for nss peer delete [Sun Dec 17 02:43:32 2023] ath11k c000000.wifi: peer not found for nss peer delete [Sun Dec 17 02:43:34 2023] ath11k c000000.wifi: peer not found for nss peer delete [Sun Dec 17 02:43:40 2023] ath11k c000000.wifi: peer not found for nss peer delete [Sun Dec 17 02:43:41 2023] ath11k c000000.wifi: peer not found for nss peer delete [Sun Dec 17 02:43:46 2023] ath11k c000000.wifi: peer not found for nss peer delete ``` But eventually ends up subsiding. Needs heavy testing... ath11k_nss: Add mac address to debug `nss peer delete` warnings also delete ath10k patch, and refresh. ath11k_nss: FIX `nss peer delete` + encap errors This should hopefullly fix the following errors: ``` [Sun Dec 24 22:03:21 2023] ath11k c000000.wifi: encap mismatch in nss tx skb encap type 1vif encap type 2 [Sun Dec 24 22:03:21 2023] ath11k c000000.wifi: failed to transmit frame -22 [Sun Dec 24 22:08:25 2023] ath11k c000000.wifi: encap mismatch in nss tx skb encap type 1vif encap type 2 [Sun Dec 24 22:08:25 2023] ath11k c000000.wifi: failed to transmit frame -22 ``` Clients should also be able to switch between 2Ghz and 5Ghz AP, as well as join using password (no longer required to boot with NSS off first, connect the client to acquire PSK, and reboot back with nss wifi offload enabled). Uptime has been 5 hours and so far no issues. ath11k_nss: Remove unecessary clang-tidy formatting ath11k_nss: add 'debug_mode' flag quiet warnings Will properly handle: ``` [Mon Dec 25 16:51:34 2023] ath11k c000000.wifi: encap mismatch in nss tx skb encap type 1 vif encap type 2 ``` should take the path for native wifi encap ath11k_nss: Rework depends, make `nss_redirect` optional 1.) Added a reworked `qca-nss-pbuf` init script from QSDK that will set sysctl NSS `n2hcfg` wifi options based on board type and available RAM. 2.) ath11k is fully capable of offloading wifi, it does not need mac80211 to create any NSS vifs. This lowers overhead and has actually shown considerable speed improvements for CPU programs on the router side (i.e. SMB). I believe ax3600's IoT (ath10k) would require it for offloading. I've added 2 new makemenu options, `MAC80211_NSS_SUPPORT` which enables NSS related features, and `MAC80211_NSS_REDIRECT` which provides the option to autoload the module on boot with `nss_redirect=1`. 3.) Reverted the option that deafulted `ATH11K_MEM_PROFILE_512M` to true. This was not required for platforms with 1GB or more memory (which is most of them). The default is 1GB. Select for platforms like Xiaomi AX3600. ath11k_nss: remove requirement for '/sys/kernel/debug/ath11k' ath11k_nss: set default values lower to avoid eating up memory ath11k_nss: Add NSS VLAN support + improvements 1) tweaked qca-nss-pbuf script to better handle different board configs 2) added some QSDK NSS patches for dynamic vlan, WDS. 3) added QSDK fixes for beacon, and bt-coex For devices that keep getting disconnected (mostly on 2G). It is recommended to use the following settings for wifi. Change for your country. config wifi-device 'radio0' option type 'mac80211' option path 'platform/soc/c000000.wifi' option band '5g' option txpower '24' option country 'PA' option channel '100' option htmode 'HE160' option cell_density '0' config wifi-iface 'default_radio0' option device 'radio0' option network 'lan' option mode 'ap' option encryption 'psk2' option key 'SOME_PASSWORD' option ssid 'EXAMPLE_5G' option dtim_period '3' option max_inactivity '86400' option disassoc_low_ack '0' config wifi-device 'radio1' option type 'mac80211' option path 'platform/soc/c000000.wifi+1' option band '2g' option htmode 'HT20' option channel '1' option txpower '36' option country 'PA' option cell_density '0' config wifi-iface 'default_radio1' option device 'radio1' option network 'lan' option mode 'ap' option ssid 'EXAMPLE_2G' option encryption 'psk2' option key 'SOME_PASSWORD' option max_inactivity '86400' option dtim_period '3' option disassoc_low_ack '0' WPA3 should be disabled, and left as WPA2. Experimenting with max_inactivity, dtim_period, and disassoc_low_ack to hopefully resolve the deauth disconnects. --- package/kernel/mac80211/Makefile | 32 +- package/kernel/mac80211/ath.mk | 29 +- .../mac80211/files/etc/init.d/qca-nss-pbuf | 91 + ...th11k-fix-for-peer-memory-corruption.patch | 48 + ...dma-counter-increamenting-improperly.patch | 51 + ...nitor-crash-if-tx-offload-is-enabled.patch | 60 + .../107-ath11k-tid-counter-fix.patch | 21 + .../113-ath11k-add-8023-undecap-support.patch | 55 + ...-adding-support-for-mgmt-frame-stats.patch | 292 ++ ...-when-using-encapsulation-offloading.patch | 12 + ...91-ath11k-add-mgmt-and-data-ack-rssi.patch | 48 + .../199-001-mac80211-add-nss-support.patch | 461 +++ ...-ath11k_nss-add-nss-driver-interface.patch | 3020 +++++++++++++++++ .../199-003-ath11k-add-nss-support.patch | 1283 +++++++ ...t-callback-when-hwencap-enable-in-st.patch | 35 + ...-ath11k-Add-support-for-dynamic-vlan.patch | 60 + ...th11k-Enable-512MB-profile-in-ath11k.patch | 332 ++ ...07-mac80211-add-nss-redirect-support.patch | 268 ++ .../211-ath11k-add-obss-pd-support.patch | 56 + ...14-ath11k-qos-null-frame-tx-over-wmi.patch | 519 +++ ...11k-Disable-rx_header-tlv-for-2K-SKB.patch | 906 +++++ ...01-ath11k-account-tx-rx-packets-flow.patch | 494 +++ ...-mac80211-account-tx-rx-packets-flow.patch | 369 ++ ...th11k-Add-support-for-beacon-tx-mode.patch | 45 + ...80211-Add-support-for-beacon-tx-mode.patch | 159 + ...dd-provision-to-configure-rx-hashmap.patch | 208 ++ ...dst-ring-descriptors-from-cacheable-.patch | 147 + ...ow-fast-rx-by-bypassing-stats-update.patch | 412 +++ .../ath11k_nss/245-compilation_fix.patch | 192 ++ .../245-revert-dev-sw-netstats-txrx-add.patch | 145 + ...-nss-thread-priority-during-pdev_ini.patch | 109 + ...avoid-stack-corrupt-in-nwifi-undecap.patch | 11 + ...e-free-of-peer-rx_tid-during-reo-cmd.patch | 40 + ...-0005-mac80211-simple-tx-for-AP-mode.patch | 99 + ...1k-skip-status-ring-entry-processing.patch | 191 ++ ...ccess-of-the-dma-buffer-back-to-dma-.patch | 28 + ...mac80211-fix-unconditional-sta-usage.patch | 50 + ...-fix-clear-peer-keys-during-disassoc.patch | 50 + ...-fix-tkip-encryption-traffic-failure.patch | 25 + ...-event-handler-support-for-link-desc.patch | 73 + ...unused-RX_FLAGS-from-mac80211_rx_fla.patch | 85 + .../640-006-mac80211-add-eht-radiotap.patch | 506 +++ ...ncapsulation-of-EAPOL-frames-if-OFFL.patch | 232 ++ .../702-ath11k-fix-memory-leak-in-dp-rx.patch | 48 + ...-the-frame-to-driver-tx-ops-directly.patch | 74 + ...se-HW-checksum-offload-only-for-ethm.patch | 140 + .../patches/ath11k_nss/900-fix-build.patch | 236 ++ ...N-iftype-support-on-NSS-offload-case.patch | 206 ++ ...load-changes-to-NSS-driver-interface.patch | 701 ++++ ...-dynamic-VLAN-support-on-NSS-offload.patch | 102 + ...-support-on-NSS-offload-for-STA-mode.patch | 973 ++++++ ...02-ath11k-add-HE-stats-in-peer-stats.patch | 777 +++++ .../902-ath11k-add-btcoex-config.patch | 612 ++++ ...vdev-in-NSS-for-AP_VLAN-vif-handling.patch | 784 +++++ ...pport-for-WDS-offload-in-NSS-offload.patch | 575 ++++ ...dev-in-NSS-for-dynamic-VLAN-handling.patch | 213 ++ ...-dynamic-VLAN-support-in-NSS-offload.patch | 557 +++ .../patches-6.6/9999-add-btcoex-dts.patch | 30 + 58 files changed, 17374 insertions(+), 3 deletions(-) create mode 100755 package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf create mode 100644 package/kernel/mac80211/patches/ath11k_nss/033-ath11k-fix-for-peer-memory-corruption.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/087-ath11k-fix-ul-ofdma-counter-increamenting-improperly.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/105-ath11k-fix-monitor-crash-if-tx-offload-is-enabled.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/107-ath11k-tid-counter-fix.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/113-ath11k-add-8023-undecap-support.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/142-ath11k-adding-support-for-mgmt-frame-stats.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/146-mac80211-enable-TKIP-when-using-encapsulation-offloading.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/191-ath11k-add-mgmt-and-data-ack-rssi.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/199-mac80211-fix-xmit-callback-when-hwencap-enable-in-st.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-512MB-profile-in-ath11k.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/207-mac80211-add-nss-redirect-support.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/211-ath11k-add-obss-pd-support.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/214-ath11k-qos-null-frame-tx-over-wmi.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/234-001-ath11k-account-tx-rx-packets-flow.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/234-002-mac80211-account-tx-rx-packets-flow.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/235-001-ath11k-Add-support-for-beacon-tx-mode.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/235-002-mac80211-Add-support-for-beacon-tx-mode.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/237-002-ath11k-Add-provision-to-configure-rx-hashmap.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/237-003-ath11k-allocate-dst-ring-descriptors-from-cacheable-.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/245-compilation_fix.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/245-revert-dev-sw-netstats-txrx-add.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/318-ath11k-avoid-stack-corrupt-in-nwifi-undecap.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/319-ath11k-fix-double-free-of-peer-rx_tid-during-reo-cmd.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/335-0005-mac80211-simple-tx-for-AP-mode.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/336-ath11k-skip-status-ring-entry-processing.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/342-ath11k-provide-access-of-the-dma-buffer-back-to-dma-.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/342-mac80211-fix-unconditional-sta-usage.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/357-ath11k-fix-clear-peer-keys-during-disassoc.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/359-ath11k-fix-tkip-encryption-traffic-failure.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/376-ath11k-Add-nss-event-handler-support-for-link-desc.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/640-006-mac80211-add-eht-radiotap.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/702-ath11k-fix-memory-leak-in-dp-rx.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/902-000-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/902-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/902-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/902-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-HE-stats-in-peer-stats.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-btcoex-config.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/903-002-ath11k-add-support-for-ext-vdev-in-NSS-for-AP_VLAN-vif-handling.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/904-002-ath11k-extend-ext-vdev-in-NSS-for-dynamic-VLAN-handling.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/904-003-ath11k-add-dynamic-VLAN-support-in-NSS-offload.patch create mode 100644 target/linux/qualcommax/patches-6.6/9999-add-btcoex-dts.patch diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 566cfdd7b2efcb..c65898aa46c0eb 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -36,6 +36,8 @@ PKG_CONFIG_DEPENDS:= \ CONFIG_PACKAGE_MAC80211_DEBUGFS \ CONFIG_PACKAGE_MAC80211_MESH \ CONFIG_PACKAGE_MAC80211_TRACING \ + CONFIG_PACKAGE_MAC80211_NSS_SUPPORT \ + CONFIG_PACKAGE_MAC80211_NSS_REDIRECT \ CONFIG_PACKAGE_IWLWIFI_DEBUG \ CONFIG_PACKAGE_IWLWIFI_DEBUGFS \ CONFIG_PACKAGE_RTLWIFI_DEBUG \ @@ -129,10 +131,15 @@ define KernelPackage/mac80211 $(call KernelPackage/mac80211/Default) TITLE:=Linux 802.11 Wireless Networking Stack # +kmod-crypto-cmac is a runtime only dependency of net/mac80211/aes_cmac.c - DEPENDS+= +kmod-cfg80211 +kmod-crypto-cmac +kmod-crypto-ccm +kmod-crypto-gcm +hostapd-common + DEPENDS+= +kmod-cfg80211 +kmod-crypto-cmac +kmod-crypto-ccm +kmod-crypto-gcm +hostapd-common \ + +ATH11K_NSS_SUPPORT:kmod-qca-nss-drv KCONFIG:=\ CONFIG_AVERAGE=y FILES:= $(PKG_BUILD_DIR)/net/mac80211/mac80211.ko +ifdef CONFIG_PACKAGE_MAC80211_NSS_REDIRECT + AUTOLOAD:=$(call AutoProbe, mac80211) + MODPARAMS.mac80211:=nss_redirect=1 +endif ABI_VERSION:=$(PKG_VERSION)-$(PKG_RELEASE) MENU:=1 endef @@ -140,6 +147,21 @@ endef define KernelPackage/mac80211/config if PACKAGE_kmod-mac80211 + if PACKAGE_kmod-qca-nss-drv + config PACKAGE_MAC80211_NSS_SUPPORT + bool "Enable NSS support" + default y + help + This option enables support for NSS in QCA boards. + config PACKAGE_MAC80211_NSS_REDIRECT + bool "Enable autoloading with 'nss_redirect=1' (not needed on ath11k)" + depends on PACKAGE_MAC80211_NSS_SUPPORT + default n + help + This option enables autoloading mac80211 with 'nss_redirect=1'. + However, it is not required for wifi offloading. + endif + config PACKAGE_MAC80211_DEBUGFS bool "Export mac80211 internals in DebugFS" select KERNEL_DEBUG_FS @@ -281,6 +303,12 @@ ifeq ($(BUILD_VARIANT),smallbuffers) C_DEFINES+= -DCONFIG_ATH10K_SMALLBUFFERS endif +ifdef CONFIG_ATH11K_NSS_SUPPORT + IREMAP_CFLAGS+=-I$(STAGING_DIR)/usr/include/qca-nss-drv -I$(STAGING_DIR)/usr/include/qca-nss-clients +endif + +config-$(CONFIG_PACKAGE_MAC80211_NSS_SUPPORT) += MAC80211_NSS_SUPPORT + MAKE_OPTS:= \ $(subst -C $(LINUX_DIR),-C "$(PKG_BUILD_DIR)",$(KERNEL_MAKEOPTS)) \ EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/include $(IREMAP_CFLAGS) $(C_DEFINES)" \ @@ -349,6 +377,7 @@ define Build/Patch $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath9k,ath9k/) $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/) $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/) + $(if $(CONFIG_ATH11K_NSS_SUPPORT),$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k_nss,ath11k_nss/)) $(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/) @@ -365,6 +394,7 @@ define Quilt/Refresh/Package $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath9k,ath9k/) $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/) $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/) + $(if $(CONFIG_ATH11K_NSS_SUPPORT),$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k_nss,ath11k_nss/)) $(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/) diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk index b0c3691a572ae6..6795818446ace6 100644 --- a/package/kernel/mac80211/ath.mk +++ b/package/kernel/mac80211/ath.mk @@ -13,7 +13,10 @@ PKG_CONFIG_DEPENDS += \ CONFIG_ATH10K_LEDS \ CONFIG_ATH10K_THERMAL \ CONFIG_ATH11K_THERMAL \ - CONFIG_ATH_USER_REGD + CONFIG_ATH_USER_REGD \ + CONFIG_ATH11K_MEM_PROFILE_512M \ + CONFIG_ATH11K_NSS_SUPPORT \ + CONFIG_ATH11K_SMART_ANT_ALG ifdef CONFIG_PACKAGE_MAC80211_DEBUGFS config-y += \ @@ -56,6 +59,9 @@ config-$(CONFIG_ATH9K_UBNTHSR) += ATH9K_UBNTHSR config-$(CONFIG_ATH10K_LEDS) += ATH10K_LEDS config-$(CONFIG_ATH10K_THERMAL) += ATH10K_THERMAL config-$(CONFIG_ATH11K_THERMAL) += ATH11K_THERMAL +config-$(CONFIG_ATH11K_MEM_PROFILE_512M) += ATH11K_MEM_PROFILE_512M +config-$(CONFIG_ATH11K_NSS_SUPPORT) += ATH11K_NSS_SUPPORT +config-$(CONFIG_ATH11K_SMART_ANT_ALG) += ATH11K_SMART_ANT_ALG config-$(call config_package,ath9k-htc) += ATH9K_HTC config-$(call config_package,ath10k,regular) += ATH10K ATH10K_PCI @@ -297,9 +303,14 @@ define KernelPackage/ath11k TITLE:=Qualcomm 802.11ax wireless chipset support (common code) 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 + +kmod-crypto-michael-mic +ATH11K_THERMAL:kmod-hwmon-core +ATH11K_THERMAL:kmod-thermal \ + +ATH11K_NSS_SUPPORT:kmod-qca-nss-drv 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 + AUTOLOAD:=$(call AutoProbe,ath11k) + MODPARAMS.ath11k:=nss_offload=1 frame_mode=2 +endif endef define KernelPackage/ath11k/description @@ -314,6 +325,20 @@ define KernelPackage/ath11k/config depends on PACKAGE_kmod-ath11k default y if TARGET_qualcommax + config ATH11K_NSS_SUPPORT + bool "Enable NSS WiFi offload" + default y if TARGET_qualcommax + + config ATH11K_MEM_PROFILE_512M + bool "Use limits for the 512MB memory size" + default n + help + This allows selecting the ath11k memory size profile to be used. + + config ATH11K_SMART_ANT_ALG + bool "Enable smart antenna" + depends on PACKAGE_ATH_DEBUG + default n endef define KernelPackage/ath11k-ahb diff --git a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf new file mode 100755 index 00000000000000..40f05c46fb28fb --- /dev/null +++ b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf @@ -0,0 +1,91 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (c) 2021 The Linux Foundation. All rights reserved. +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +START=20 + +apply_sysctl() { + [ $(sysctl -n -e dev.nss.general.redirect) = "0" ] && /etc/init.d/qca-nss-ecm start + + 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 + + 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 > /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 > /dev/null 2> /dev/null + +} + +apply_nss_config() { + + 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 + + board=$(board_name) + + case "$board" in + # 1GB+ profile + buffalo,wxr-5950ax12 | \ + dynalink,dl-wrx36 | \ + edgecore,eap102 | \ + linksys,mx5300 | \ + linksys,mx4200v2 | \ + netgear,rax120v2 | \ + netgear,wax620 | \ + netgear,wax630 | \ + prpl,haze | \ + qnap,301w | \ + xiaomi,ax9000 | \ + zyxel,nbg7815) + extra_pbuf_core0=10000000 n2h_high_water_core0=72512 n2h_wifi_pool_buf=36864 apply_sysctl + ;; + # 512MB profile + edimax,cax1800 | \ + linksys,mx4200v1 | \ + xiaomi,ax3600) # 512MB profile + extra_pbuf_core0=3100000 n2h_high_water_core0=30624 n2h_wifi_pool_buf=8192 apply_sysctl + ;; + # 256MB profile + netgear,wax218) + 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 + + enable_nss_offload=$(cat /sys/module/ath11k/parameters/nss_offload) + + if [ "$enable_nss_offload" = "0" ]; then + logger -t ath11k_nss "Module parameter 'nss_offload=0'. Skipping applying wifi nss configs" + exit 1 + fi + + # 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. + extra_pbuf_core0=$(sysctl -n -e dev.nss.n2hcfg.extra_pbuf_core0) + + if [ "$extra_pbuf_core0" = "0" ]; then + apply_nss_config + else + logger -t ath11k_nss "Sysctl key 'extra_pbuf_core0' already set to '"$extra_pbuf_core0"'. Skipping applying wifi nss configs" + fi +} diff --git a/package/kernel/mac80211/patches/ath11k_nss/033-ath11k-fix-for-peer-memory-corruption.patch b/package/kernel/mac80211/patches/ath11k_nss/033-ath11k-fix-for-peer-memory-corruption.patch new file mode 100644 index 00000000000000..5c9c723913b09a --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/033-ath11k-fix-for-peer-memory-corruption.patch @@ -0,0 +1,48 @@ +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -4178,22 +4178,28 @@ static int ath11k_clear_peer_keys(struct + int ret; + int i; + u32 flags = 0; ++ struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; + + lockdep_assert_held(&ar->conf_mutex); + + spin_lock_bh(&ab->base_lock); + peer = ath11k_peer_find(ab, arvif->vdev_id, addr); +- spin_unlock_bh(&ab->base_lock); +- +- if (!peer) ++ if (!peer) { ++ spin_unlock_bh(&ab->base_lock); + return -ENOENT; ++ } ++ for (i = 0; i < ARRAY_SIZE(keys); i++) { ++ keys[i]= peer->keys[i]; ++ peer->keys[i]= NULL; ++ } ++ spin_unlock_bh(&ab->base_lock); + +- for (i = 0; i < ARRAY_SIZE(peer->keys); i++) { +- if (!peer->keys[i]) ++ for (i = 0; i < ARRAY_SIZE(keys); i++) { ++ if (!keys[i]) + continue; + + /* key flags are not required to delete the key */ +- ret = ath11k_install_key(arvif, peer->keys[i], ++ ret = ath11k_install_key(arvif, keys[i], + DISABLE_KEY, addr, flags); + if (ret < 0 && first_errno == 0) + first_errno = ret; +@@ -4201,10 +4207,6 @@ static int ath11k_clear_peer_keys(struct + if (ret < 0) + ath11k_warn(ab, "failed to remove peer key %d: %d\n", + i, ret); +- +- spin_lock_bh(&ab->base_lock); +- peer->keys[i] = NULL; +- spin_unlock_bh(&ab->base_lock); + } + + return first_errno; diff --git a/package/kernel/mac80211/patches/ath11k_nss/087-ath11k-fix-ul-ofdma-counter-increamenting-improperly.patch b/package/kernel/mac80211/patches/ath11k_nss/087-ath11k-fix-ul-ofdma-counter-increamenting-improperly.patch new file mode 100644 index 00000000000000..326db09145b342 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/087-ath11k-fix-ul-ofdma-counter-increamenting-improperly.patch @@ -0,0 +1,51 @@ + drivers/net/wireless/ath/ath11k/dp_rx.c | 3 ++- + drivers/net/wireless/ath/ath11k/hal_rx.c | 3 +++ + drivers/net/wireless/ath/ath11k/hal_rx.h | 2 ++ + 3 files changed, 7 insertions(+), 1 deletion(-) + +--- 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 + goto next_skb; + } + +- arsta = ath11k_sta_to_arsta(peer->sta); +- ath11k_dp_rx_update_peer_stats(arsta, ppdu_info); ++ 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); ++ } + + if (ath11k_debugfs_is_pktlog_peer_valid(ar, peer->addr)) + trace_ath11k_htt_rxdesc(ar, skb->data, log_type, rx_buf_sz); +--- a/drivers/net/wireless/ath/ath11k/hal_rx.c ++++ b/drivers/net/wireless/ath/ath11k/hal_rx.c +@@ -900,6 +900,9 @@ ath11k_hal_rx_parse_mon_status_tlv(struc + ppdu_info->ast_index = + FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO2_AST_INDEX, + __le32_to_cpu(eu_stats->info2)); ++ ppdu_info->fc_valid = ++ FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO1_FC_VALID, ++ __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; +--- 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 { + }; + + #define HAL_RX_FCS_LEN 4 ++#define HAL_AST_IDX_INVALID 0xFFFF + + enum hal_rx_mon_status { + HAL_RX_MON_STATUS_PPDU_NOT_DONE, +@@ -150,6 +151,7 @@ struct hal_rx_mon_ppdu_info { + u8 rssi_comb; + u8 rssi_chain_pri20[HAL_RX_MAX_NSS]; + u16 tid; ++ u8 fc_valid; + u16 ht_flags; + u16 vht_flags; + u16 he_flags; diff --git a/package/kernel/mac80211/patches/ath11k_nss/105-ath11k-fix-monitor-crash-if-tx-offload-is-enabled.patch b/package/kernel/mac80211/patches/ath11k_nss/105-ath11k-fix-monitor-crash-if-tx-offload-is-enabled.patch new file mode 100644 index 00000000000000..9304833c87d1c3 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/105-ath11k-fix-monitor-crash-if-tx-offload-is-enabled.patch @@ -0,0 +1,60 @@ + drivers/net/wireless/ath/ath11k/dp_tx.c | 20 +++++++++++++++++--- + 1 file changed, 17 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/dp_tx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_tx.c +@@ -322,6 +322,8 @@ ath11k_dp_tx_htt_tx_complete_buf(struct + struct ath11k_skb_cb *skb_cb; + struct ath11k *ar; + struct ath11k_peer *peer; ++ struct ieee80211_vif *vif; ++ u8 flags = 0; + + spin_lock(&tx_ring->tx_idr_lock); + msdu = idr_remove(&tx_ring->txbuf_idr, ts->msdu_id); +@@ -348,6 +350,14 @@ ath11k_dp_tx_htt_tx_complete_buf(struct + return; + } + ++ if (!skb_cb->vif) { ++ dev_kfree_skb_any(msdu); ++ return; ++ } ++ ++ flags = skb_cb->flags; ++ vif = skb_cb->vif; ++ + memset(&info->status, 0, sizeof(info->status)); + + if (ts->acked) { +@@ -555,6 +565,8 @@ static void ath11k_dp_tx_complete_msdu(s + struct ath11k_peer *peer; + struct ath11k_sta *arsta; + struct rate_info rate; ++ struct ieee80211_vif *vif; ++ u8 flags = 0; + + if (WARN_ON_ONCE(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) { + /* Must not happen */ +@@ -575,6 +587,9 @@ static void ath11k_dp_tx_complete_msdu(s + return; + } + ++ flags = skb_cb->flags; ++ vif = skb_cb->vif; ++ + info = IEEE80211_SKB_CB(msdu); + memset(&info->status, 0, sizeof(info->status)); + +@@ -641,7 +656,10 @@ static void ath11k_dp_tx_complete_msdu(s + + spin_unlock_bh(&ab->base_lock); + +- ieee80211_tx_status_ext(ar->hw, &status); ++ if (flags & ATH11K_SKB_HW_80211_ENCAP) ++ ieee80211_tx_status_8023(ar->hw, vif, msdu); ++ else ++ ieee80211_tx_status_ext(ar->hw, &status); + } + + static inline void ath11k_dp_tx_status_parse(struct ath11k_base *ab, 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 new file mode 100644 index 00000000000000..1826e64bbcba05 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/107-ath11k-tid-counter-fix.patch @@ -0,0 +1,21 @@ +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/113-ath11k-add-8023-undecap-support.patch b/package/kernel/mac80211/patches/ath11k_nss/113-ath11k-add-8023-undecap-support.patch new file mode 100644 index 00000000000000..8ef3d9ba7c4d91 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/113-ath11k-add-8023-undecap-support.patch @@ -0,0 +1,55 @@ +--- 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 + ether_addr_copy(ieee80211_get_SA(hdr), sa); + } + ++static void ath11k_dp_rx_h_undecap_snap(struct ath11k *ar, ++ struct sk_buff *msdu, ++ u8 *first_hdr, ++ enum hal_encrypt_type enctype, ++ struct ieee80211_rx_status *status) ++{ ++ struct ieee80211_hdr *hdr; ++ size_t hdr_len; ++ u8 l3_pad_bytes; ++ struct hal_rx_desc *rx_desc; ++ ++ /* Delivered decapped frame: ++ * [amsdu header] <-- replaced with 802.11 hdr ++ * [rfc1042/llc] ++ * [payload] ++ */ ++ ++ rx_desc = (void *)msdu->data - sizeof(*rx_desc); ++ l3_pad_bytes = ath11k_dp_rx_h_msdu_end_l3pad(ar->ab, rx_desc); ++ ++ skb_put(msdu, l3_pad_bytes); ++ skb_pull(msdu, sizeof(struct ath11k_dp_amsdu_subframe_hdr) + l3_pad_bytes); ++ ++ hdr = (struct ieee80211_hdr *)first_hdr; ++ 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)); ++ } ++ ++ memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); ++} ++ + 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 + enctype, status); + break; + case DP_RX_DECAP_TYPE_8023: +- /* TODO: Handle undecap for these formats */ ++ ath11k_dp_rx_h_undecap_snap(ar, msdu, first_hdr, ++ enctype, status); + break; + } + } diff --git a/package/kernel/mac80211/patches/ath11k_nss/142-ath11k-adding-support-for-mgmt-frame-stats.patch b/package/kernel/mac80211/patches/ath11k_nss/142-ath11k-adding-support-for-mgmt-frame-stats.patch new file mode 100644 index 00000000000000..f1dfc0f7b9a887 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/142-ath11k-adding-support-for-mgmt-frame-stats.patch @@ -0,0 +1,292 @@ +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -311,6 +311,16 @@ struct ath11k_rekey_data { + bool enable_offload; + }; + ++#define ATH11K_STATS_MGMT_FRM_TYPE_MAX 16 ++ ++struct ath11k_mgmt_frame_stats { ++ u32 tx_succ_cnt[ATH11K_STATS_MGMT_FRM_TYPE_MAX]; ++ u32 tx_fail_cnt[ATH11K_STATS_MGMT_FRM_TYPE_MAX]; ++ u32 rx_cnt[ATH11K_STATS_MGMT_FRM_TYPE_MAX]; ++ u32 tx_compl_succ[ATH11K_STATS_MGMT_FRM_TYPE_MAX]; ++ u32 tx_compl_fail[ATH11K_STATS_MGMT_FRM_TYPE_MAX]; ++}; ++ + struct ath11k_vif { + u32 vdev_id; + enum wmi_vdev_type vdev_type; +@@ -369,6 +379,8 @@ struct ath11k_vif { + #ifdef CPTCFG_ATH11K_DEBUGFS + struct dentry *debugfs_twt; + #endif /* CPTCFG_ATH11K_DEBUGFS */ ++ ++ struct ath11k_mgmt_frame_stats mgmt_stats; + }; + + struct ath11k_vif_iter { +--- a/drivers/net/wireless/ath/ath11k/debugfs.c ++++ b/drivers/net/wireless/ath/ath11k/debugfs.c +@@ -1588,6 +1588,87 @@ static const struct file_operations fops + .llseek = default_llseek, + }; + ++static ssize_t ath11k_dump_mgmt_stats(struct file *file, char __user *ubuf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath11k *ar = file->private_data; ++ struct ath11k_vif *arvif = NULL; ++ struct ath11k_mgmt_frame_stats *mgmt_stats; ++ int len = 0, ret, i; ++ int size = (TARGET_NUM_VDEVS - 1) * 1500; ++ char *buf; ++ const char *mgmt_frm_type[ATH11K_STATS_MGMT_FRM_TYPE_MAX-1] = {"assoc_req", "assoc_resp", ++ "reassoc_req", "reassoc_resp", ++ "probe_req", "probe_resp", ++ "timing_advertisement", "reserved", ++ "beacon", "atim", "disassoc", ++ "auth", "deauth", "action", "action_no_ack"}; ++ ++ if (ar->state != ATH11K_STATE_ON) ++ return -ENETDOWN; ++ ++ buf = kzalloc(size, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ mutex_lock(&ar->conf_mutex); ++ spin_lock_bh(&ar->data_lock); ++ ++ list_for_each_entry (arvif, &ar->arvifs, list) { ++ if (!arvif) ++ break; ++ ++ if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) ++ continue; ++ ++ mgmt_stats = &arvif->mgmt_stats; ++ len += scnprintf(buf + len, size - len, "MGMT frame stats for vdev %u :\n", ++ arvif->vdev_id); ++ len += scnprintf(buf + len, size - len, " TX stats :\n "); ++ len += scnprintf(buf + len, size - len, " Success frames:\n"); ++ for (i = 0; i < ATH11K_STATS_MGMT_FRM_TYPE_MAX-1; i++) ++ len += scnprintf(buf + len, size - len, " %s: %d\n", mgmt_frm_type[i], ++ mgmt_stats->tx_succ_cnt[i]); ++ ++ len += scnprintf(buf + len, size - len, " Failed frames:\n"); ++ ++ for (i = 0; i < ATH11K_STATS_MGMT_FRM_TYPE_MAX-1; i++) ++ len += scnprintf(buf + len, size - len, " %s: %d\n", mgmt_frm_type[i], ++ mgmt_stats->tx_fail_cnt[i]); ++ ++ len += scnprintf(buf + len, size - len, " RX stats :\n"); ++ len += scnprintf(buf + len, size - len, " Success frames:\n"); ++ for (i = 0; i < ATH11K_STATS_MGMT_FRM_TYPE_MAX-1; i++) ++ len += scnprintf(buf + len, size - len, " %s: %d\n", mgmt_frm_type[i], ++ mgmt_stats->rx_cnt[i]); ++ ++ len += scnprintf(buf + len, size - len, " Tx completion stats :\n"); ++ len += scnprintf(buf + len, size - len, " success completions:\n"); ++ for (i = 0; i < ATH11K_STATS_MGMT_FRM_TYPE_MAX-1; i++) ++ len += scnprintf(buf + len, size - len, " %s: %d\n", mgmt_frm_type[i], ++ mgmt_stats->tx_compl_succ[i]); ++ len += scnprintf(buf + len, size - len, " failure completions:\n"); ++ for (i = 0; i < ATH11K_STATS_MGMT_FRM_TYPE_MAX-1; i++) ++ len += scnprintf(buf + len, size - len, " %s: %d\n", mgmt_frm_type[i], ++ mgmt_stats->tx_compl_fail[i]); ++ } ++ ++ spin_unlock_bh(&ar->data_lock); ++ ++ if (len > size) ++ len = size; ++ ++ ret = simple_read_from_buffer(ubuf, count, ppos, buf, len); ++ mutex_unlock(&ar->conf_mutex); ++ kfree(buf); ++ return ret; ++} ++ ++static const struct file_operations fops_dump_mgmt_stats = { ++ .read = ath11k_dump_mgmt_stats, ++ .open = simple_open ++}; ++ + int ath11k_debugfs_register(struct ath11k *ar) + { + struct ath11k_base *ab = ar->ab; +@@ -1620,6 +1701,9 @@ int ath11k_debugfs_register(struct ath11 + 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, +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -6148,9 +6148,9 @@ static int ath11k_mac_mgmt_tx(struct ath + */ + if (is_prb_rsp && + atomic_read(&ar->num_pending_mgmt_tx) > ATH11K_PRB_RSP_DROP_THRESHOLD) { +- ath11k_warn(ar->ab, ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, + "dropping probe response as pending queue is almost full\n"); +- return -ENOSPC; ++ return -EBUSY; + } + + if (skb_queue_len_lockless(q) >= ATH11K_TX_MGMT_NUM_PENDING_MAX) { +@@ -6176,9 +6176,11 @@ static void ath11k_mac_op_tx(struct ieee + struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_key_conf *key = info->control.hw_key; ++ struct ath11k_mgmt_frame_stats *mgmt_stats = &arvif->mgmt_stats; + struct ath11k_sta *arsta = NULL; + u32 info_flags = info->flags; + bool is_prb_rsp; ++ u16 frm_type = 0; + int ret; + + memset(skb_cb, 0, sizeof(*skb_cb)); +@@ -6192,12 +6194,21 @@ static void ath11k_mac_op_tx(struct ieee + if (info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { + skb_cb->flags |= ATH11K_SKB_HW_80211_ENCAP; + } else if (ieee80211_is_mgmt(hdr->frame_control)) { ++ frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, hdr->frame_control); + is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control); + ret = ath11k_mac_mgmt_tx(ar, skb, is_prb_rsp); + if (ret) { +- ath11k_warn(ar->ab, "failed to queue management frame %d\n", +- ret); ++ if (ret != -EBUSY) ++ ath11k_warn(ar->ab, "failed to queue management frame %d\n", ++ ret); + ieee80211_free_txskb(ar->hw, skb); ++ spin_lock_bh(&ar->data_lock); ++ mgmt_stats->tx_fail_cnt[frm_type]++; ++ spin_unlock_bh(&ar->data_lock); ++ } else { ++ spin_lock_bh(&ar->data_lock); ++ mgmt_stats->tx_succ_cnt[frm_type]++; ++ spin_unlock_bh(&ar->data_lock); + } + return; + } +--- 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 + + peer->sec_type = HAL_ENCRYPT_TYPE_OPEN; + peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; ++ peer->vif = arvif->vif; + + if (sta) { + 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 @@ + struct ath11k_peer { + struct list_head list; + struct ieee80211_sta *sta; ++ struct ieee80211_vif *vif; + int vdev_id; + u8 addr[ETH_ALEN]; + int peer_id; +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -5823,6 +5823,12 @@ static int wmi_process_mgmt_tx_comp(stru + struct sk_buff *msdu; + 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->txmgmt_idr_lock); +@@ -5850,6 +5856,31 @@ static int wmi_process_mgmt_tx_comp(stru + info->status.ack_signal = tx_compl_param->ack_rssi; + } + ++ 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 (!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); +@@ -7519,6 +7550,11 @@ static void ath11k_mgmt_rx_event(struct + struct ieee80211_hdr *hdr; + u16 fc; + struct ieee80211_supported_band *sband; ++ struct ath11k_peer *peer; ++ struct ieee80211_vif *vif; ++ struct ath11k_vif *arvif; ++ struct ath11k_mgmt_frame_stats *mgmt_stats; ++ u16 frm_type = 0; + + if (ath11k_pull_mgmt_rx_params_tlv(ab, skb, &rx_ev) != 0) { + ath11k_warn(ab, "failed to extract mgmt rx event"); +@@ -7584,7 +7620,34 @@ static void ath11k_mgmt_rx_event(struct + + hdr = (struct ieee80211_hdr *)skb->data; + fc = le16_to_cpu(hdr->frame_control); ++ frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, fc); ++ ++ spin_lock_bh(&ab->base_lock); ++ ++ peer = ath11k_peer_find_by_addr(ab, hdr->addr1); ++ if(!peer) ++ peer = ath11k_peer_find_by_addr(ab, hdr->addr3); ++ if (!peer) { ++ spin_unlock_bh(&ab->base_lock); ++ goto skip_mgmt_stats; ++ } ++ ++ vif = peer->vif; ++ ++ spin_unlock_bh(&ab->base_lock); ++ ++ if (!vif) ++ goto skip_mgmt_stats; ++ ++ spin_lock_bh(&ar->data_lock); ++ ++ arvif = ath11k_vif_to_arvif(vif); ++ mgmt_stats = &arvif->mgmt_stats; ++ mgmt_stats->rx_cnt[frm_type]++; ++ ++ spin_unlock_bh(&ar->data_lock); + ++skip_mgmt_stats: + /* Firmware is guaranteed to report all essential management frames via + * WMI while it can deliver some extra via HTT. Since there can be + * duplicates split the reporting wrt monitor/sniffing. diff --git a/package/kernel/mac80211/patches/ath11k_nss/146-mac80211-enable-TKIP-when-using-encapsulation-offloading.patch b/package/kernel/mac80211/patches/ath11k_nss/146-mac80211-enable-TKIP-when-using-encapsulation-offloading.patch new file mode 100644 index 00000000000000..82d8c4e05bb11f --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/146-mac80211-enable-TKIP-when-using-encapsulation-offloading.patch @@ -0,0 +1,12 @@ +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -4686,8 +4686,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8 + if (!key) + key = rcu_dereference(sdata->default_unicast_key); + +- if (key && (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) || +- key->conf.cipher == WLAN_CIPHER_SUITE_TKIP)) ++ if (key && (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))) + goto skip_offload; + + sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift); diff --git a/package/kernel/mac80211/patches/ath11k_nss/191-ath11k-add-mgmt-and-data-ack-rssi.patch b/package/kernel/mac80211/patches/ath11k_nss/191-ath11k-add-mgmt-and-data-ack-rssi.patch new file mode 100644 index 00000000000000..dea5600324f536 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/191-ath11k-add-mgmt-and-data-ack-rssi.patch @@ -0,0 +1,48 @@ +--- 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 + 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/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -4065,6 +4065,7 @@ 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; +@@ -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-001-mac80211-add-nss-support.patch b/package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch new file mode 100644 index 00000000000000..0b017ec97ad24d --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch @@ -0,0 +1,461 @@ +From 193bfea2185a0ee976f54812e41ace77e6ee85e4 Mon Sep 17 00:00:00 2001 +From: Sriram R +Date: Fri, 10 Jul 2020 12:46:12 +0530 +Subject: [PATCH 1/3] mac80211: add nss support + +Add Support for NSS Offload if the HW supports it. +New flag is introduced to indicate HW support for NSS +offload + +Signed-off-by: Sriram R +--- + include/net/mac80211.h | 13 +++++++++++++ + net/mac80211/debugfs.c | 1 + + net/mac80211/util.c | 16 ++++++++++++++++ + 3 files changed, 30 insertions(+) + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -380,6 +380,20 @@ enum ieee80211_bss_change { + /* when adding here, make sure to change ieee80211_reconfig */ + }; + ++/** ++ * enum ieee80211_nss_bss_change - NSS BSS change notification flags ++ * ++ * These flags are used with the nss_bss_info_changed() callback ++ * to indicate which NSS BSS parameter changed. ++ * ++ * @BSS_CHANGED_NSS_AP_ISOLATE: AP Isolate feature in NSS mode ++ * ++ */ ++ ++enum ieee80211_nss_bss_change { ++ BSS_CHANGED_NSS_AP_ISOLATE = BIT(0), ++}; ++ + /* + * The maximum number of IPv4 addresses listed for ARP filtering. If the number + * of addresses for an interface increase beyond this value, hardware ARP +@@ -683,6 +697,7 @@ struct ieee80211_fils_discovery { + * beamformee + * @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 + */ + struct ieee80211_bss_conf { + struct ieee80211_vif *vif; +@@ -776,6 +791,7 @@ struct ieee80211_bss_conf { + bool eht_su_beamformer; + bool eht_su_beamformee; + bool eht_mu_beamformer; ++ bool nss_ap_isolate; + }; + + /** +@@ -1406,7 +1422,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 +- * ++ * + * - DATA3_DATA_MCS + * - DATA3_DATA_DCM + * - DATA3_CODING +@@ -1414,7 +1430,7 @@ ieee80211_tx_info_clear_status(struct ie + * - DATA5_DATA_BW_RU_ALLOC + * - DATA6_NSTS + * - DATA3_STBC +- * ++ * + * 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 + lockdep_vif_mutex_held(vif)) + + /** ++ * ieee80211_vif_to_wdev_relaxed - return a wdev struct from a vif ++ * @vif: the vif to get the wdev for ++ * ++ * This function is similar to ieee80211_vif_to_wdev, but the wdev ++ * is returned even if sdata is not running. ++ * ++ */ ++struct wireless_dev *ieee80211_vif_to_wdev_relaxed(struct ieee80211_vif *vif); ++ ++/** + * enum ieee80211_key_flags - key flags + * + * These flags are used for communication about keys between the driver +@@ -2677,6 +2703,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. + * ++ * @IEEE80211_HW_SUPPORTS_NSS_OFFLOAD: Hardware/driver supports NSS offload ++ * + * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays + */ + enum ieee80211_hw_flags { +@@ -2734,6 +2762,7 @@ enum ieee80211_hw_flags { + IEEE80211_HW_SUPPORTS_CONC_MON_RX_DECAP, + IEEE80211_HW_DETECTS_COLOR_COLLISION, + IEEE80211_HW_MLO_MCAST_MULTI_LINK_TX, ++ IEEE80211_HW_SUPPORTS_NSS_OFFLOAD, + + /* keep last, obviously */ + NUM_IEEE80211_HW_FLAGS +@@ -3746,6 +3775,10 @@ struct ieee80211_prep_tx_info { + * non-MLO connections. + * The callback can sleep. + * ++ * @nss_bss_info_changed: Handler for configuration requests related to NSS BSS ++ * parameters that may vary during BSS's lifespan, and may affect low level ++ * driver. ++ * + * @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 { + 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); + 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 { + int (*reset_tid_config)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, u8 tids); +- void (*update_vif_offload)(struct ieee80211_hw *hw, ++ int (*update_vif_offload)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); + void (*sta_set_4addr)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + 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[] = { + FLAG(SUPPORTS_CONC_MON_RX_DECAP), + FLAG(DETECTS_COLOR_COLLISION), + FLAG(MLO_MCAST_MULTI_LINK_TX), ++ FLAG(SUPPORTS_NSS_OFFLOAD), + #undef FLAG + }; + +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -868,6 +868,22 @@ struct wireless_dev *ieee80211_vif_to_wd + } + EXPORT_SYMBOL_GPL(ieee80211_vif_to_wdev); + ++struct wireless_dev *ieee80211_vif_to_wdev_relaxed(struct ieee80211_vif *vif) ++{ ++ struct ieee80211_sub_if_data *sdata; ++ ++ if (!vif) ++ return NULL; ++ ++ sdata = vif_to_sdata(vif); ++ ++ if (sdata) ++ return &sdata->wdev; ++ ++ return NULL; ++} ++EXPORT_SYMBOL(ieee80211_vif_to_wdev_relaxed); ++ + /* + * Nothing should have been stuffed into the workqueue during + * the suspend->resume cycle. Since we can't check each caller +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -291,6 +291,17 @@ void ieee80211_link_info_change_notify(s + drv_link_info_changed(local, sdata, link->conf, link->link_id, changed); + } + ++void ieee80211_nss_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, ++ u64 changed) ++{ ++ struct ieee80211_local *local = sdata->local; ++ ++ if (!changed || sdata->vif.type == NL80211_IFTYPE_AP_VLAN) ++ return; ++ ++ drv_nss_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed); ++} ++ + 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_ + NL80211_FEATURE_FULL_AP_CLIENT_STATE; + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_STA); + wiphy_ext_feature_set(wiphy, +- NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211); +- wiphy_ext_feature_set(wiphy, +- NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH); +- wiphy_ext_feature_set(wiphy, +- NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS); +- wiphy_ext_feature_set(wiphy, + 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 + return -EINVAL; + } + ++ /* Control port over nl80211 is disabled for nss offload as ++ * sending per packet tx status is not supported and only ++ * rx over netdev from driver is done currently */ ++ if (!ieee80211_hw_check(hw, SUPPORTS_NSS_OFFLOAD)) { ++ wiphy_ext_feature_set(hw->wiphy, ++ NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211); ++ wiphy_ext_feature_set(hw->wiphy, ++ NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH); ++ wiphy_ext_feature_set(hw->wiphy, ++ NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS); ++ } ++ + #ifdef CONFIG_PM + if (hw->wiphy->wowlan && (!local->ops->suspend || !local->ops->resume)) + return -EINVAL; +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -2379,6 +2379,9 @@ sta_get_last_rx_stats(struct sta_info *s + struct ieee80211_sta_rx_stats *stats = &sta->deflink.rx_stats; + int cpu; + ++ if (ieee80211_hw_check(&sta->local->hw, SUPPORTS_NSS_OFFLOAD)) ++ return stats; ++ + if (!sta->deflink.pcpu_rx_stats) + return stats; + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -1028,11 +1028,23 @@ ieee80211_tx_h_stats(struct ieee80211_tx + { + struct sk_buff *skb; + int ac = -1; ++ struct ieee80211_hdr *hdr; ++ bool nss_offload; + + if (!tx->sta) + return TX_CONTINUE; + ++ nss_offload = ieee80211_hw_check(&tx->local->hw, SUPPORTS_NSS_OFFLOAD); ++ + skb_queue_walk(&tx->skbs, skb) { ++ /* Do not increment stats for data packets if NSS offload is enabled. ++ * As we use the stats from NSS, this will be a duplication ++ */ ++ if (nss_offload) { ++ hdr = (void *) skb->data; ++ if (ieee80211_is_data(hdr->frame_control)) ++ continue; ++ } + 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 + + if (unlikely(!multicast && ((skb->sk && + skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) || +- ctrl_flags & IEEE80211_TX_CTL_REQ_TX_STATUS))) ++ ctrl_flags & IEEE80211_TX_CTL_REQ_TX_STATUS) && ++ !(ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD) && ++ ieee80211_is_data(fc) && !ieee80211_is_qos_nullfunc(fc)))) + info_id = ieee80211_store_ack_skb(local, skb, &info_flags, + cookie); + +@@ -4639,13 +4653,16 @@ static void ieee80211_8023_xmit(struct i + } + + if (unlikely(skb->sk && +- skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) ++ skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS && ++ !ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD))) + info->ack_frame_id = ieee80211_store_ack_skb(local, skb, + &info->flags, NULL); + + dev_sw_netstats_tx_add(dev, skbs, len); +- sta->deflink.tx_stats.packets[queue] += skbs; +- sta->deflink.tx_stats.bytes[queue] += len; ++ if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) { ++ sta->deflink.tx_stats.packets[queue] += skbs; ++ sta->deflink.tx_stats.bytes[queue] += len; ++ } + + ieee80211_tpt_led_trig_tx(local, len); + +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -2447,6 +2447,9 @@ bool cfg80211_does_bw_fit_range(const st + + int cfg80211_sinfo_alloc_tid_stats(struct station_info *sinfo, gfp_t gfp) + { ++ if(sinfo->pertid) ++ return 0; ++ + sinfo->pertid = kcalloc(IEEE80211_NUM_TIDS + 1, + sizeof(*(sinfo->pertid)), + gfp); +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -2675,7 +2675,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; +- u64 changed = 0; ++ u32 changed = 0, nss_changed = 0; + + 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 + sdata->flags |= IEEE80211_SDATA_DONT_BRIDGE_PACKETS; + else + sdata->flags &= ~IEEE80211_SDATA_DONT_BRIDGE_PACKETS; ++ sdata->vif.bss_conf.nss_ap_isolate = params->ap_isolate; ++ nss_changed |= BSS_CHANGED_NSS_AP_ISOLATE; + ieee80211_check_fast_rx_iface(sdata); + } + +@@ -2753,6 +2755,8 @@ static int ieee80211_change_bss(struct w + + ieee80211_link_info_change_notify(sdata, link, changed); + ++ ieee80211_nss_bss_info_change_notify(sdata, nss_changed); ++ + return 0; + } + +--- a/net/mac80211/driver-ops.h ++++ b/net/mac80211/driver-ops.h +@@ -172,6 +172,23 @@ void drv_link_info_changed(struct ieee80 + struct ieee80211_bss_conf *info, + int link_id, u64 changed); + ++static inline void drv_nss_bss_info_changed(struct ieee80211_local *local, ++ struct ieee80211_sub_if_data *sdata, ++ struct ieee80211_bss_conf *info, ++ u32 changed) ++{ ++ might_sleep(); ++ ++ if (!check_sdata_in_driver(sdata)) ++ return; ++ ++ trace_drv_nss_bss_info_changed(local, sdata, info, changed); ++ if (local->ops->nss_bss_info_changed) { ++ local->ops->nss_bss_info_changed(&local->hw, &sdata->vif, changed); ++ } ++ trace_drv_nss_return_void(local); ++} ++ + static inline u64 drv_prepare_multicast(struct ieee80211_local *local, + struct netdev_hw_addr_list *mc_list) + { +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1845,6 +1845,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); ++void ieee80211_nss_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, ++ u64 changed); + void ieee80211_configure_filter(struct ieee80211_local *local); + u64 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata); + +--- a/net/mac80211/trace.h ++++ b/net/mac80211/trace.h +@@ -389,6 +389,38 @@ TRACE_EVENT(drv_config, + LOCAL_PR_ARG, __entry->changed, CHANDEF_PR_ARG + ) + ); ++TRACE_EVENT(drv_nss_bss_info_changed, ++ TP_PROTO(struct ieee80211_local *local, ++ struct ieee80211_sub_if_data *sdata, ++ struct ieee80211_bss_conf *info, ++ u32 changed), ++ ++ TP_ARGS(local, sdata, info, changed), ++ ++ TP_STRUCT__entry( ++ LOCAL_ENTRY ++ VIF_ENTRY ++ __field(u32, changed) ++ __field(bool, nss_ap_isolate); ++ ), ++ ++ TP_fast_assign( ++ LOCAL_ASSIGN; ++ VIF_ASSIGN; ++ __entry->changed = changed; ++ __entry->nss_ap_isolate = info->nss_ap_isolate; ++ ), ++ ++ TP_printk( ++ LOCAL_PR_FMT VIF_PR_FMT " changed:%#x", ++ LOCAL_PR_ARG, VIF_PR_ARG, __entry->changed ++ ) ++); ++ ++DEFINE_EVENT(local_only_evt, drv_nss_return_void, ++ TP_PROTO(struct ieee80211_local *local), ++ TP_ARGS(local) ++); + + TRACE_EVENT(drv_vif_cfg_changed, + TP_PROTO(struct ieee80211_local *local, +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -969,7 +969,8 @@ static bool ieee80211_set_sdata_offload_ + local->hw.wiphy->frag_threshold != (u32)-1) + flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED; + +- if (local->monitors) ++ if (local->monitors && ++ !ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) + flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED; + } else { + flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED; +--- a/net/mac80211/Kconfig ++++ b/net/mac80211/Kconfig +@@ -104,6 +104,15 @@ menuconfig MAC80211_DEBUG_MENU + help + This option collects various mac80211 debug settings. + ++config MAC80211_NSS_SUPPORT ++ bool "QTI mac80211 nss support" ++ depends on ATH11K_NSS_SUPPORT ++ default n ++ ---help--- ++ Enables NSS offload support for ATH11K driver ++ ++ If unsure, say Y to enable NSS offload support. ++ + config MAC80211_NOINLINE + bool "Do not inline TX/RX handlers" + depends on MAC80211_DEBUG_MENU +--- a/local-symbols ++++ b/local-symbols +@@ -65,6 +65,7 @@ MAC80211_MESH_PS_DEBUG= + MAC80211_TDLS_DEBUG= + MAC80211_DEBUG_COUNTERS= + MAC80211_STA_HASH_MAX_SIZE= ++MAC80211_NSS_SUPPORT= + QCOM_AOSS_QMP= + QCOM_COMMAND_DB= + QCOM_CPR= +@@ -174,6 +175,7 @@ ATH11K_DEBUGFS= + ATH11K_TRACING= + ATH11K_SPECTRAL= + ATH11K_THERMAL= ++ATH11K_MEM_PROFILE_512M= + ATH12K= + ATH12K_DEBUG= + ATH12K_TRACING= diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch b/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch new file mode 100644 index 00000000000000..beee16098f14c3 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch @@ -0,0 +1,3020 @@ +From 0fa55ca418c8afd6da242407a184c23548c553dc Mon Sep 17 00:00:00 2001 +From: Sriram R +Date: Fri, 5 Jun 2020 12:21:15 +0530 +Subject: [PATCH 2/3] ath11k: Add nss driver interface + +This patch adds interface support for accessing nss driver with +support for initialization, teardown, vap up/down, peer create/delete, +tx/rx. NSS Stats addition is not part of this version. + +Signed-off-by: Sriram R +--- + drivers/net/wireless/ath/ath11k/Kconfig | 9 + + drivers/net/wireless/ath/ath11k/Makefile | 1 + + drivers/net/wireless/ath/ath11k/nss.c | 1762 ++++++++++++++++++++++++++++++ + drivers/net/wireless/ath/ath11k/nss.h | 217 ++++ + 4 files changed, 1989 insertions(+) + create mode 100644 drivers/net/wireless/ath/ath11k/nss.c + create mode 100644 drivers/net/wireless/ath/ath11k/nss.h + +--- a/drivers/net/wireless/ath/ath11k/Kconfig ++++ b/drivers/net/wireless/ath/ath11k/Kconfig +@@ -13,6 +13,16 @@ config ATH11K + + If you choose to build a module, it'll be called ath11k. + ++config ATH11K_NSS_SUPPORT ++ bool "QCA ath11k nss support" ++ depends on ATH11K ++ default n ++ select MAC80211_NSS_SUPPORT ++ ---help--- ++ Enables NSS offload support for ATH11K driver ++ ++ If unsure, say Y to enable NSS offload support. ++ + config ATH11K_AHB + tristate "Atheros ath11k AHB support" + depends on m +--- a/drivers/net/wireless/ath/ath11k/Makefile ++++ b/drivers/net/wireless/ath/ath11k/Makefile +@@ -25,6 +25,7 @@ ath11k-$(CPTCFG_ATH11K_TRACING) += trace + ath11k-$(CPTCFG_ATH11K_THERMAL) += thermal.o + ath11k-$(CPTCFG_ATH11K_SPECTRAL) += spectral.o + ath11k-$(CONFIG_PM) += wow.o ++ath11k-$(CPTCFG_ATH11K_NSS_SUPPORT) += nss.o + + obj-$(CPTCFG_ATH11K_AHB) += ath11k_ahb.o + ath11k_ahb-y += ahb.o +--- /dev/null ++++ b/drivers/net/wireless/ath/ath11k/nss.c +@@ -0,0 +1,2392 @@ ++// SPDX-License-Identifier: BSD-3-Clause-Clear ++/* ++ * Copyright (c) 2020 The Linux Foundation. All rights reserved. ++ */ ++ ++#include "debug.h" ++#include "mac.h" ++#include "nss.h" ++#include "core.h" ++#include "peer.h" ++#include "hif.h" ++#include "wmi.h" ++#include "../../../../../net/mac80211/sta_info.h" ++ ++/*-----------------------------ATH11K-NSS Helpers--------------------------*/ ++ ++static enum ath11k_nss_opmode ++ath11k_nss_get_vdev_opmode(struct ath11k_vif *arvif) ++{ ++ switch (arvif->vdev_type) { ++ case WMI_VDEV_TYPE_AP: ++ return ATH11K_NSS_OPMODE_AP; ++ case WMI_VDEV_TYPE_STA: ++ return ATH11K_NSS_OPMODE_STA; ++ default: ++ ath11k_warn(arvif->ar->ab, "unsupported nss vdev type %d\n", ++ arvif->vdev_type); ++ } ++ ++ return ATH11K_NSS_OPMODE_UNKNOWN; ++} ++ ++static void ath11k_nss_wifili_stats_sync(struct ath11k_base *ab, ++ struct nss_wifili_stats_sync_msg *wlsoc_stats) ++{ ++ struct nss_wifili_device_stats *devstats = &wlsoc_stats->stats; ++ struct ath11k_soc_dp_stats *soc_stats = &ab->soc_stats; ++ int i; ++ ++ spin_lock_bh(&ab->base_lock); ++ ++ soc_stats->err_ring_pkts += devstats->rxwbm_stats.err_src_rxdma; ++ soc_stats->invalid_rbm += devstats->rxwbm_stats.invalid_buf_mgr; ++ ++ for (i = 0; i < HAL_REO_ENTR_RING_RXDMA_ECODE_MAX; i++) ++ soc_stats->rxdma_error[i] += devstats->rxwbm_stats.err_dma_codes[i]; ++ ++ for (i = 0; i < HAL_REO_DEST_RING_ERROR_CODE_MAX; i++) ++ soc_stats->reo_error[i] += devstats->rxwbm_stats.err_reo_codes[i]; ++ ++ for (i = 0; i < DP_REO_DST_RING_MAX; i++) ++ soc_stats->hal_reo_error[i] += devstats->rxreo_stats[i].ring_error; ++ ++ for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) ++ soc_stats->tx_err.desc_na[i] += devstats->tcl_stats[i].tcl_ring_full; ++ ++ ++ for (i = 0; i < NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG; i++) ++ atomic_add(devstats->txcomp_stats[i].invalid_bufsrc ++ + devstats->txcomp_stats[i].invalid_cookie ++ + devstats->tx_sw_pool_stats[i].desc_alloc_fail ++ + devstats->tx_ext_sw_pool_stats[i].desc_alloc_fail, ++ &soc_stats->tx_err.misc_fail); ++ ++ for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) ++ atomic_add(devstats->tx_data_stats[i].tx_send_fail_cnt, ++ &soc_stats->tx_err.misc_fail); ++ ++ spin_unlock_bh(&ab->base_lock); ++} ++ ++static void ath11k_nss_get_peer_stats(struct ath11k_base *ab, struct nss_wifili_peer_stats *stats) ++{ ++ struct ath11k_peer *peer; ++ struct nss_wifili_peer_ctrl_stats *pstats = NULL; ++ int i, j; ++ u64 tx_packets, tx_bytes, tx_dropped = 0; ++ u64 rx_packets, rx_bytes, rx_dropped; ++ ++ if (!ab->nss.stats_enabled) ++ return; ++ ++ for (i = 0; i < stats->npeers; i++) { ++ pstats = &stats->wpcs[i]; ++ ++ rcu_read_lock(); ++ spin_lock_bh(&ab->base_lock); ++ ++ peer = ath11k_peer_find_by_id(ab, pstats->peer_id); ++ if (!peer || !peer->sta) { ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "nss wifili: unable to find peer %d\n", pstats->peer_id); ++ spin_unlock_bh(&ab->base_lock); ++ rcu_read_unlock(); ++ continue; ++ } ++ ++ if (!peer->nss.nss_stats) { ++ spin_unlock_bh(&ab->base_lock); ++ rcu_read_unlock(); ++ return; ++ } ++ ++ if (pstats->tx.tx_success_cnt) ++ peer->nss.nss_stats->last_ack = jiffies; ++ ++ if (pstats->rx.rx_recvd) { ++ peer->nss.nss_stats->last_rx = jiffies; ++ } ++ ++ tx_packets = pstats->tx.tx_mcast_cnt + ++ pstats->tx.tx_ucast_cnt + ++ pstats->tx.tx_bcast_cnt; ++ peer->nss.nss_stats->tx_packets += tx_packets; ++ tx_bytes = pstats->tx.tx_mcast_bytes + ++ pstats->tx.tx_ucast_bytes + ++ pstats->tx.tx_bcast_bytes; ++ peer->nss.nss_stats->tx_bytes += tx_bytes; ++ peer->nss.nss_stats->tx_retries += pstats->tx.retries; ++ ++ for (j = 0; j < NSS_WIFILI_TQM_RR_MAX; j++) ++ tx_dropped += pstats->tx.dropped.drop_stats[j]; ++ ++ peer->nss.nss_stats->tx_failed += tx_dropped; ++ ++ ATH11K_NSS_TXRX_NETDEV_STATS(tx, peer->vif, tx_bytes, tx_packets); ++ ++ rx_packets = pstats->rx.rx_recvd; ++ peer->nss.nss_stats->rx_packets += rx_packets; ++ rx_bytes = pstats->rx.rx_recvd_bytes; ++ peer->nss.nss_stats->rx_bytes += rx_bytes; ++ rx_dropped = pstats->rx.err.mic_err + ++ 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); ++ ++ spin_unlock_bh(&ab->base_lock); ++ rcu_read_unlock(); ++ } ++} ++ ++void ath11k_nss_ext_rx_stats(struct ath11k_base *ab, struct htt_rx_ring_tlv_filter *tlv_filter) ++{ ++ if (ab->nss.enabled) ++ tlv_filter->rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS; ++} ++ ++static u32 ath11k_nss_cipher_type(struct ath11k_base *ab, u32 cipher) ++{ ++ switch (cipher) { ++ case WLAN_CIPHER_SUITE_CCMP: ++ return PEER_SEC_TYPE_AES_CCMP; ++ case WLAN_CIPHER_SUITE_TKIP: ++ return PEER_SEC_TYPE_TKIP; ++ case WLAN_CIPHER_SUITE_CCMP_256: ++ return PEER_SEC_TYPE_AES_CCMP_256; ++ case WLAN_CIPHER_SUITE_GCMP: ++ return PEER_SEC_TYPE_AES_GCMP; ++ case WLAN_CIPHER_SUITE_GCMP_256: ++ return PEER_SEC_TYPE_AES_GCMP_256; ++ default: ++ ath11k_warn(ab, "unknown cipher type %d\n", cipher); ++ return PEER_SEC_TYPE_NONE; ++ } ++} ++ ++static void ath11k_nss_tx_encap_nwifi(struct sk_buff *skb) ++{ ++ struct ieee80211_hdr *hdr = (void *)skb->data; ++ u8 *qos_ctl; ++ ++ if (!ieee80211_is_data_qos(hdr->frame_control)) ++ return; ++ ++ qos_ctl = ieee80211_get_qos_ctl(hdr); ++ memmove(skb->data + IEEE80211_QOS_CTL_LEN, ++ skb->data, (void *)qos_ctl - (void *)skb->data); ++ skb_pull(skb, IEEE80211_QOS_CTL_LEN); ++ ++ hdr = (void *)skb->data; ++ hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA); ++} ++ ++static void ath11k_nss_tx_encap_raw(struct sk_buff *skb) ++{ ++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); ++ struct ieee80211_hdr *hdr = (void *)skb->data; ++ u32 cipher; ++ ++ if (!ieee80211_has_protected(hdr->frame_control) || !info->control.hw_key) ++ return; ++ ++ /* Include length for MIC */ ++ skb_put(skb, IEEE80211_CCMP_MIC_LEN); ++ ++ /* Include length for ICV if TKIP is used */ ++ cipher = info->control.hw_key->cipher; ++ if (cipher == WLAN_CIPHER_SUITE_TKIP) ++ skb_put(skb, IEEE80211_TKIP_ICV_LEN); ++} ++ ++static void ath11k_nss_peer_mem_free(struct ath11k_base *ab, u32 peer_id) ++{ ++ struct ath11k_peer *peer; ++ ++ spin_lock_bh(&ab->base_lock); ++ ++ 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); ++ return; ++ } ++ ++ dma_unmap_single(ab->dev, peer->nss.paddr, ++ WIFILI_NSS_PEER_BYTE_SIZE, DMA_FROM_DEVICE); ++ ++ kfree(peer->nss.vaddr); ++ if (peer->nss.nss_stats) { ++ kfree(peer->nss.nss_stats); ++ peer->nss.nss_stats = NULL; ++ } ++ ++ complete(&peer->nss.complete); ++ spin_unlock_bh(&ab->base_lock); ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "nss peer %d mem freed\n", peer_id); ++} ++ ++/*-----------------------------Events/Callbacks------------------------------*/ ++ ++void ath11k_nss_wifili_event_receive(struct ath11k_base *ab, struct nss_wifili_msg *msg) ++{ ++ u32 msg_type = msg->cm.type; ++ enum nss_cmn_response response = msg->cm.response; ++ u32 error = msg->cm.error; ++ u32 peer_id; ++ struct nss_wifili_peer_stats *peer_stats; ++ ++ if (!ab) ++ return; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "nss wifili event received %d response %d error %d\n", ++ msg_type, response, error); ++ ++ switch (msg_type) { ++ case NSS_WIFILI_INIT_MSG: ++ case NSS_WIFILI_PDEV_INIT_MSG: ++ case NSS_WIFILI_START_MSG: ++ case NSS_WIFILI_SOC_RESET_MSG: ++ case NSS_WIFILI_STOP_MSG: ++ case NSS_WIFILI_PDEV_DEINIT_MSG: ++ ab->nss.response = response; ++ complete(&ab->nss.complete); ++ break; ++ ++ case NSS_WIFILI_PEER_CREATE_MSG: ++ if (response != NSS_CMN_RESPONSE_EMSG) ++ break; ++ ++ peer_id = (&msg->msg.peermsg)->peer_id; ++ ++ /* free peer memory allocated during peer create due to failure */ ++ ath11k_nss_peer_mem_free(ab, peer_id); ++ break; ++ case NSS_WIFILI_PEER_DELETE_MSG: ++ peer_id = (&msg->msg.peermsg)->peer_id; ++ ++ if (response == NSS_CMN_RESPONSE_EMSG) ++ ath11k_warn(ab, "ath11k_nss: peer delete failed%d\n", ++ peer_id); ++ ++ /* free peer memory allocated during peer create irrespective of ++ * delete status ++ */ ++ ath11k_nss_peer_mem_free(ab, peer_id); ++ break; ++ case NSS_WIFILI_PEER_SECURITY_TYPE_MSG: ++ if (response == NSS_CMN_RESPONSE_EMSG) ++ ath11k_warn(ab, "peer securty config failed\n"); ++ ++ break; ++ case NSS_WIFILI_PEER_UPDATE_AUTH_FLAG: ++ if (response == NSS_CMN_RESPONSE_EMSG) ++ ath11k_warn(ab, "peer authorize config failed\n"); ++ ++ break; ++ case NSS_WIFILI_STATS_MSG: ++ if (response == NSS_CMN_RESPONSE_EMSG) { ++ ath11k_warn(ab, "soc_dp_stats failed to get updated\n"); ++ break; ++ } ++ ath11k_nss_wifili_stats_sync(ab, &msg->msg.wlsoc_stats); ++ break; ++ case NSS_WIFILI_PEER_STATS_MSG: ++ peer_stats = &msg->msg.peer_stats.stats; ++ if (response == NSS_CMN_RESPONSE_EMSG) { ++ ath11k_warn(ab, "peer stats msg failed with error = %u\n", error); ++ break; ++ } ++ ath11k_nss_get_peer_stats(ab, peer_stats); ++ break; ++ case NSS_WIFILI_TID_REOQ_SETUP_MSG: ++ /* TODO setup tidq */ ++ break; ++ default: ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "unhandled event %d\n", msg_type); ++ break; ++ } ++} ++ ++void ath11k_nss_process_mic_error(struct ath11k_base *ab, struct sk_buff *skb) ++{ ++ struct ath11k_vif *arvif; ++ struct ath11k_peer *peer = NULL; ++ struct hal_rx_desc *desc = (struct hal_rx_desc *)skb->data; ++ struct wireless_dev *wdev; ++ u16 peer_id; ++ u8 peer_addr[ETH_ALEN]; ++ u8 ucast_keyidx, mcast_keyidx; ++ bool is_mcbc; ++ ++ if (!ath11k_dp_rx_h_msdu_end_first_msdu(ab, desc)) ++ goto fail; ++ ++ is_mcbc = ath11k_dp_rx_h_attn_is_mcbc(ab, desc); ++ peer_id = ath11k_dp_rx_h_mpdu_start_peer_id(ab, desc); ++ ++ spin_lock_bh(&ab->base_lock); ++ peer = ath11k_peer_find_by_id(ab, peer_id); ++ if (!peer) { ++ ath11k_info(ab, "ath11k_nss:peer not found"); ++ spin_unlock_bh(&ab->base_lock); ++ goto fail; ++ } ++ ++ if (!peer->vif) { ++ ath11k_warn(ab, "ath11k_nss:vif not found"); ++ spin_unlock_bh(&ab->base_lock); ++ goto fail; ++ } ++ ++ ether_addr_copy(peer_addr, peer->addr); ++ mcast_keyidx = peer->mcast_keyidx; ++ ucast_keyidx = peer->ucast_keyidx; ++ arvif = ath11k_vif_to_arvif(peer->vif); ++ spin_unlock_bh(&ab->base_lock); ++ ++ if (!arvif->is_started) { ++ ath11k_warn(ab, "ath11k_nss:arvif not started"); ++ goto fail; ++ } ++ ++ wdev = ieee80211_vif_to_wdev_relaxed(arvif->vif); ++ if (!wdev) { ++ ath11k_warn(ab, "ath11k_nss: wdev is null\n"); ++ goto fail; ++ } ++ ++ if (!wdev->netdev) { ++ ath11k_warn(ab, "ath11k_nss: netdev is null\n"); ++ goto fail; ++ } ++ ++ cfg80211_michael_mic_failure(wdev->netdev, peer_addr, ++ is_mcbc ? NL80211_KEYTYPE_GROUP : ++ NL80211_KEYTYPE_PAIRWISE, ++ is_mcbc ? mcast_keyidx : ucast_keyidx, ++ NULL, GFP_ATOMIC); ++ dev_kfree_skb_any(skb); ++ return; ++ ++fail: ++ dev_kfree_skb_any(skb); ++ ath11k_warn(ab, "ath11k_nss: Failed to handle mic error\n"); ++ return; ++} ++ ++static void ++ath11k_nss_wifili_ext_callback_fn(struct ath11k_base *ab, struct sk_buff *skb, ++ __attribute__((unused)) struct napi_struct *napi) ++{ ++ struct nss_wifili_soc_per_packet_metadata *wepm; ++ ++ wepm = (struct nss_wifili_soc_per_packet_metadata *)(skb->head + ++ NSS_WIFILI_SOC_PER_PACKET_METADATA_OFFSET); ++ ++ switch (wepm->pkt_type) { ++ case NSS_WIFILI_SOC_EXT_DATA_PKT_MIC_ERROR: ++ ath11k_nss_process_mic_error(ab, skb); ++ break; ++ default: ++ kfree(skb); ++ break; ++ } ++} ++ ++void ath11k_nss_vdev_cfg_cb(void *app_data, struct nss_cmn_msg *msg) ++{ ++ struct ath11k_vif *arvif = (struct ath11k_vif *)app_data; ++ ++ if (!arvif) ++ return; ++ ++ ath11k_dbg(arvif->ar->ab, ATH11K_DBG_NSS, "vdev cfg msg callback received msg:%d rsp:%d\n", ++ msg->type, msg->response); ++ ++ complete(&arvif->nss.complete); ++} ++ ++static void ath11k_nss_vdev_event_receive(void *dev, struct nss_cmn_msg *vdev_msg) ++{ ++ /*TODO*/ ++} ++ ++static void ++ath11k_nss_vdev_special_data_receive(struct net_device *dev, struct sk_buff *skb, ++ __attribute__((unused)) struct napi_struct *napi) ++{ ++ /* TODO */ ++} ++ ++/* 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) ++{ ++ struct sk_buff_head subframe_list; ++ struct ieee80211_hdr *hdr; ++ struct sk_buff *subframe; ++ struct net_device *dev; ++ int hdr_len; ++ u8 *qc; ++ ++ dev = skb->dev; ++ ++ if (eth) ++ goto deliver_msdu; ++ ++ hdr = (struct ieee80211_hdr *)skb->data; ++ hdr_len = ieee80211_hdrlen(hdr->frame_control); ++ ++ if (ieee80211_is_data_qos(hdr->frame_control)) { ++ qc = ieee80211_get_qos_ctl(hdr); ++ if (*qc & IEEE80211_QOS_CTL_A_MSDU_PRESENT) ++ goto deliver_amsdu; ++ } ++ ++ if (ieee80211_data_to_8023_exthdr(skb, NULL, vif->addr, vif->type, ++ data_offs - hdr_len, false)) { ++ dev_kfree_skb_any(skb); ++ return -EINVAL; ++ } ++ ++deliver_msdu: ++ skb->protocol = eth_type_trans(skb, dev); ++ napi_gro_receive(napi, skb); ++ return 0; ++ ++deliver_amsdu: ++ /* Move to the start of the first subframe */ ++ skb_pull(skb, data_offs); ++ ++ __skb_queue_head_init(&subframe_list); ++ ++ /* create list containing all the subframes */ ++ ieee80211_amsdu_to_8023s(skb, &subframe_list, NULL, ++ vif->type, 0, NULL, NULL); ++ ++ /* This shouldn't happen, indicating error during defragmentation */ ++ if (skb_queue_empty(&subframe_list)) ++ return -EINVAL; ++ ++ while (!skb_queue_empty(&subframe_list)) { ++ subframe = __skb_dequeue(&subframe_list); ++ subframe->protocol = eth_type_trans(subframe, dev); ++ napi_gro_receive(napi, subframe); ++ } ++ ++ return 0; ++} ++ ++static int ath11k_nss_undecap_raw(struct ath11k_vif *arvif, struct sk_buff *skb, ++ int *data_offset) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ struct ath11k *ar = arvif->ar; ++ enum hal_encrypt_type enctype; ++ struct ath11k_peer *peer = NULL; ++ struct ieee80211_hdr *hdr; ++ int hdr_len; ++ ++ hdr = (struct ieee80211_hdr *)skb->data; ++ hdr_len = ieee80211_hdrlen(hdr->frame_control); ++ ++ *data_offset = hdr_len; ++ ++ /* FCS is included in the raw mode skb, we can trim it, fcs error ++ * packets are not expected to be received in this path ++ */ ++ skb_trim(skb, skb->len - FCS_LEN); ++ ++ spin_lock_bh(&ab->base_lock); ++ ++ peer = ath11k_peer_find_by_addr(ab, hdr->addr2); ++ if (!peer) { ++ ath11k_warn(ab, "peer not found for raw/nwifi undecap, drop this packet\n"); ++ spin_unlock_bh(&ab->base_lock); ++ return -EINVAL; ++ } ++ enctype = peer->sec_type; ++ ++ spin_unlock_bh(&ab->base_lock); ++ ++ *data_offset += ath11k_dp_rx_crypto_param_len(ar, enctype); ++ ++ /* Strip ICV, MIC, MMIC */ ++ skb_trim(skb, skb->len - ++ ath11k_dp_rx_crypto_mic_len(ar, enctype)); ++ ++ skb_trim(skb, skb->len - ++ ath11k_dp_rx_crypto_icv_len(ar, enctype)); ++ ++ if (enctype == HAL_ENCRYPT_TYPE_TKIP_MIC) ++ skb_trim(skb, skb->len - IEEE80211_CCMP_MIC_LEN); ++ ++ return 0; ++} ++ ++static int ath11k_nss_undecap_nwifi(struct ath11k_vif *arvif, struct sk_buff *skb, ++ int *data_offset) ++{ ++ struct ieee80211_hdr *hdr; ++ int hdr_len; ++ ++ hdr = (struct ieee80211_hdr *)skb->data; ++ hdr_len = ieee80211_hdrlen(hdr->frame_control); ++ ++ *data_offset = hdr_len; ++ ++ /* We dont receive the IV from nss host on slow path ++ * hence we can return only the header length as offset. ++ **/ ++ return 0; ++} ++ ++static void ++ath11k_nss_vdev_data_receive(struct net_device *dev, struct sk_buff *skb, ++ __attribute__((unused)) struct napi_struct *napi) ++{ ++ enum ath11k_hw_txrx_mode decap_type; ++ 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) { ++ 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; ++ if (!arvif) { ++ dev_kfree_skb_any(skb); ++ return; ++ } ++ ++ 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: ", ++ skb->data, skb->len); ++ ++ decap_type = arvif->nss.decap; ++ ++ switch (decap_type) { ++ case ATH11K_HW_TXRX_RAW: ++ ret = ath11k_nss_undecap_raw(arvif, skb, &data_offs); ++ break; ++ case ATH11K_HW_TXRX_NATIVE_WIFI: ++ ret = ath11k_nss_undecap_nwifi(arvif, skb, &data_offs); ++ break; ++ case ATH11K_HW_TXRX_ETHERNET: ++ /* no changes required for ethernet decap */ ++ ret = 0; ++ eth_decap = true; ++ break; ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ ++ if (ret) { ++ ath11k_warn(ab, "error in nss rx undecap, type %d err %d\n", decap_type, ++ ret); ++ dev_kfree_skb_any(skb); ++ return; ++ } ++ ++ ath11k_nss_deliver_rx(arvif->vif, skb, eth_decap, data_offs, napi); ++} ++ ++int ath11k_nss_tx(struct ath11k_vif *arvif, struct sk_buff *skb) ++{ ++ struct ath11k *ar = arvif->ar; ++ 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; ++ ++ 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; ++ } ++ ++ if (encap_type == HAL_TCL_ENCAP_TYPE_ETHERNET) ++ goto send; ++ ++ if (encap_type == HAL_TCL_ENCAP_TYPE_RAW) ++ ath11k_nss_tx_encap_raw(skb); ++ else ++ ath11k_nss_tx_encap_nwifi(skb); ++ ++send: ++ ath11k_dbg_dump(ar->ab, ATH11K_DBG_DP_TX, "", "nss tx msdu: ", ++ 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), ++ "nss tx failure: %d\n", status); ++ atomic_inc(&soc_stats->tx_err.nss_tx_fail); ++ } ++ ++ return status; ++drop: ++ atomic_inc(&soc_stats->tx_err.misc_fail); ++ WARN_ON_ONCE(1); ++ return -EINVAL; ++} ++ ++int ath11k_nss_vdev_set_cmd(struct ath11k_vif *arvif, int cmd, int val) ++{ ++ struct nss_wifi_vdev_msg *vdev_msg = NULL; ++ struct nss_wifi_vdev_cmd_msg *vdev_cmd; ++ struct ath11k *ar = arvif->ar; ++ nss_tx_status_t status; ++ ++ if (!ar->ab->nss.enabled) ++ return 0; ++ ++ /* Monitor interface is not offloaded to nss */ ++ if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) ++ return 0; ++ ++ vdev_msg = kzalloc(sizeof(*vdev_msg), GFP_ATOMIC); ++ if (!vdev_msg) ++ return -ENOMEM; ++ ++ /* TODO: Convert to function for conversion in case of many ++ * such commands ++ */ ++ if (cmd == NSS_WIFI_VDEV_SECURITY_TYPE_CMD) ++ val = ath11k_nss_cipher_type(ar->ab, val); ++ ++ if (cmd == NSS_WIFI_VDEV_ENCAP_TYPE_CMD) ++ arvif->nss.encap = val; ++ else if (cmd == NSS_WIFI_VDEV_DECAP_TYPE_CMD) ++ arvif->nss.decap = val; ++ ++ vdev_cmd = &vdev_msg->msg.vdev_cmd; ++ vdev_cmd->cmd = cmd; ++ vdev_cmd->value = val; ++ ++ nss_wifi_vdev_msg_init(vdev_msg, arvif->nss.if_num, ++ NSS_WIFI_VDEV_INTERFACE_CMD_MSG, ++ sizeof(struct nss_wifi_vdev_cmd_msg), ++ NULL, NULL); ++ ++ status = nss_wifi_vdev_tx_msg(ar->nss.ctx, vdev_msg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "nss vdev set cmd failure cmd:%d val:%d", ++ cmd, val); ++ goto free; ++ } ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss vdev set cmd success cmd:%d val:%d\n", ++ cmd, val); ++free: ++ kfree(vdev_msg); ++ return status; ++} ++ ++static int ath11k_nss_vdev_configure(struct ath11k_vif *arvif) ++{ ++ struct ath11k *ar = arvif->ar; ++ struct nss_wifi_vdev_msg *vdev_msg; ++ struct nss_wifi_vdev_config_msg *vdev_cfg; ++ nss_tx_status_t status; ++ int ret; ++ ++ vdev_msg = kzalloc(sizeof(struct nss_wifi_vdev_msg), GFP_ATOMIC); ++ if (!vdev_msg) ++ return -ENOMEM; ++ ++ vdev_cfg = &vdev_msg->msg.vdev_config; ++ ++ vdev_cfg->radio_ifnum = ar->nss.if_num; ++ vdev_cfg->vdev_id = arvif->vdev_id; ++ ++ vdev_cfg->opmode = ath11k_nss_get_vdev_opmode(arvif); ++ ++ ether_addr_copy(vdev_cfg->mac_addr, arvif->vif->addr); ++ ++ reinit_completion(&arvif->nss.complete); ++ ++ nss_wifi_vdev_msg_init(vdev_msg, arvif->nss.if_num, ++ NSS_WIFI_VDEV_INTERFACE_CONFIGURE_MSG, ++ sizeof(struct nss_wifi_vdev_config_msg), ++ (nss_wifi_vdev_msg_callback_t *)ath11k_nss_vdev_cfg_cb, ++ arvif); ++ ++ status = nss_wifi_vdev_tx_msg(ar->nss.ctx, vdev_msg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "failed to configure nss vdev nss_err:%d\n", ++ status); ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ ret = wait_for_completion_timeout(&arvif->nss.complete, ++ msecs_to_jiffies(ATH11K_NSS_MSG_TIMEOUT_MS)); ++ if (!ret) { ++ ath11k_warn(ar->ab, "timeout in receiving nss vdev cfg response\n"); ++ ret = -ETIMEDOUT; ++ goto free; ++ } ++ ++ ret = 0; ++free: ++ kfree(vdev_msg); ++ ++ return ret; ++} ++ ++static void ath11k_nss_vdev_unregister(struct ath11k_vif *arvif) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ ++ switch (arvif->vif->type) { ++ case NL80211_IFTYPE_AP: ++ case NL80211_IFTYPE_STATION: ++ nss_unregister_wifi_vdev_if(arvif->nss.if_num); ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "unregistered nss vdev %d \n", ++ arvif->nss.if_num); ++ break; ++ default: ++ ath11k_warn(ab, "unsupported interface type %d for nss vdev unregister\n", ++ arvif->vif->type); ++ return; ++ } ++} ++ ++static int ath11k_nss_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; ++ ++ switch (arvif->vif->type) { ++ case NL80211_IFTYPE_AP: ++ case NL80211_IFTYPE_STATION: ++ status = nss_register_wifi_vdev_if(ar->nss.ctx, ++ arvif->nss.if_num, ++ ath11k_nss_vdev_data_receive, ++ ath11k_nss_vdev_special_data_receive, ++ ath11k_nss_vdev_event_receive, ++ netdev, features); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "failed to register nss vdev if_num %d nss_err:%d\n", ++ arvif->nss.if_num, status); ++ return -EINVAL; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "registered nss vdev if_num %d\n", ++ arvif->nss.if_num); ++ ++ break; ++ default: ++ ath11k_warn(ab, "unsupported interface type %d for nss vdev register\n", ++ arvif->vif->type); ++ return -ENOTSUPP; ++ } ++ ++ return 0; ++} ++ ++void ath11k_nss_vdev_free(struct ath11k_vif *arvif) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ nss_tx_status_t status; ++ ++ switch (arvif->vif->type) { ++ case NL80211_IFTYPE_AP: ++ case NL80211_IFTYPE_STATION: ++ 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 vdev nss_err:%d\n", ++ status); ++ else ++ ath11k_dbg(ab, ATH11K_DBG_NSS, ++ "nss vdev interface deallocated\n"); ++ ++ return; ++ default: ++ ath11k_warn(ab, "unsupported interface type %d for nss vdev dealloc\n", ++ arvif->vif->type); ++ return; ++ } ++} ++ ++static int ath11k_nss_vdev_alloc(struct ath11k_vif *arvif) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ enum nss_dynamic_interface_type if_type; ++ int if_num; ++ ++ /* Initialize completion for verifying NSS message response */ ++ init_completion(&arvif->nss.complete); ++ ++ switch (arvif->vif->type) { ++ case NL80211_IFTYPE_AP: ++ case NL80211_IFTYPE_STATION: ++ if_type = NSS_DYNAMIC_INTERFACE_TYPE_VAP; ++ /* allocate interface context with NSS driver for the new vdev */ ++ if_num = nss_dynamic_interface_alloc_node(if_type); ++ if (if_num < 0) { ++ ath11k_warn(ab, "failed to allocate nss vdev\n"); ++ return -EINVAL; ++ } ++ ++ arvif->nss.if_num = if_num; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "allocated nss vdev if_num %d\n", ++ arvif->nss.if_num); ++ ++ break; ++ default: ++ ath11k_warn(ab, "unsupported interface type %d for nss vdev alloc\n", ++ arvif->vif->type); ++ return -ENOTSUPP; ++ } ++ ++ return 0; ++} ++ ++int ath11k_nss_vdev_create(struct ath11k_vif *arvif) ++{ ++ struct ath11k *ar = arvif->ar; ++ struct ath11k_base *ab = ar->ab; ++ struct wireless_dev *wdev; ++ int ret; ++ ++ if (!ab->nss.enabled) ++ return 0; ++ ++ /* Monitor interface is not offloaded to nss */ ++ if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) ++ return 0; ++ ++ if (arvif->nss.created) ++ return 0; ++ ++ 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; ++ } ++ ++ ret = ath11k_nss_vdev_alloc(arvif); ++ if (ret) ++ return ret; ++ ++ ret = ath11k_nss_vdev_register(arvif, wdev->netdev); ++ if (ret) ++ goto free_vdev; ++ ++ switch (arvif->vif->type) { ++ case NL80211_IFTYPE_AP: ++ case NL80211_IFTYPE_STATION: ++ ret = ath11k_nss_vdev_configure(arvif); ++ if (ret) ++ goto unregister_vdev; ++ ++ break; ++ default: ++ ret = -ENOTSUPP; ++ goto unregister_vdev; ++ } ++ ++ arvif->nss.created = true; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, ++ "nss vdev interface created ctx %pK, ifnum %d\n", ++ ar->nss.ctx, arvif->nss.if_num); ++ ++ return ret; ++ ++unregister_vdev: ++ ath11k_nss_vdev_unregister(arvif); ++free_vdev: ++ ath11k_nss_vdev_free(arvif); ++ ++ return ret; ++} ++ ++void ath11k_nss_vdev_delete(struct ath11k_vif *arvif) ++{ ++ if (!arvif->ar->ab->nss.enabled) ++ return; ++ ++ /* Monitor interface is not offloaded to nss */ ++ if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) ++ return; ++ ++ if (!arvif->nss.created) ++ return; ++ ++ ath11k_nss_vdev_unregister(arvif); ++ ++ ath11k_nss_vdev_free(arvif); ++ ++ arvif->nss.created = false; ++} ++ ++int ath11k_nss_vdev_up(struct ath11k_vif *arvif) ++{ ++ struct nss_wifi_vdev_msg *vdev_msg = NULL; ++ struct nss_wifi_vdev_enable_msg *vdev_en; ++ struct ath11k *ar = arvif->ar; ++ nss_tx_status_t status; ++ int ret = 0; ++ ++ if (!ar->ab->nss.enabled) ++ return 0; ++ ++ /* Monitor interface is not offloaded to nss */ ++ if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) ++ return 0; ++ ++ vdev_msg = kzalloc(sizeof(struct nss_wifi_vdev_msg), GFP_ATOMIC); ++ if (!vdev_msg) ++ return -ENOMEM; ++ ++ vdev_en = &vdev_msg->msg.vdev_enable; ++ ++ ether_addr_copy(vdev_en->mac_addr, arvif->vif->addr); ++ ++ nss_wifi_vdev_msg_init(vdev_msg, arvif->nss.if_num, ++ NSS_WIFI_VDEV_INTERFACE_UP_MSG, ++ sizeof(struct nss_wifi_vdev_enable_msg), ++ NULL, NULL); ++ ++ status = nss_wifi_vdev_tx_msg(ar->nss.ctx, vdev_msg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "nss vdev up tx msg error %d\n", status); ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss vdev up tx msg success\n"); ++free: ++ kfree(vdev_msg); ++ return ret; ++} ++ ++int ath11k_nss_vdev_down(struct ath11k_vif *arvif) ++{ ++ struct nss_wifi_vdev_msg *vdev_msg = NULL; ++ struct ath11k *ar = arvif->ar; ++ nss_tx_status_t status; ++ int ret = 0; ++ ++ if (!ar->ab->nss.enabled) ++ return 0; ++ ++ /* Monitor interface is not offloaded to nss */ ++ if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) ++ return 0; ++ ++ vdev_msg = kzalloc(sizeof(struct nss_wifi_vdev_msg), GFP_ATOMIC); ++ if (!vdev_msg) ++ return -ENOMEM; ++ ++ nss_wifi_vdev_msg_init(vdev_msg, arvif->nss.if_num, ++ NSS_WIFI_VDEV_INTERFACE_DOWN_MSG, ++ sizeof(struct nss_wifi_vdev_disable_msg), ++ NULL, NULL); ++ ++ status = nss_wifi_vdev_tx_msg(ar->nss.ctx, vdev_msg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "nss vdev down tx msg error %d\n", status); ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss vdev down tx msg success\n"); ++free: ++ kfree(vdev_msg); ++ return ret; ++} ++ ++/*----------------------------Peer Setup/Config -----------------------------*/ ++ ++int ath11k_nss_set_peer_sec_type(struct ath11k *ar, ++ struct ath11k_peer *peer, ++ struct ieee80211_key_conf *key_conf) ++{ ++ struct nss_wifili_peer_security_type_msg *sec_msg; ++ nss_wifili_msg_callback_t msg_cb; ++ struct nss_wifili_msg *wlmsg; ++ nss_tx_status_t status; ++ u8 *mic_key; ++ ++ if (!ar->ab->nss.enabled) ++ return 0; ++ ++ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); ++ if (!wlmsg) ++ return -ENOMEM; ++ ++ sec_msg = &wlmsg->msg.securitymsg; ++ sec_msg->peer_id = peer->peer_id; ++ ++ /* 0 -unicast , 1 - mcast/unicast */ ++ sec_msg->pkt_type = !(key_conf->flags & IEEE80211_KEY_FLAG_PAIRWISE); ++ ++ sec_msg->security_type = ath11k_nss_cipher_type(ar->ab, ++ key_conf->cipher); ++ ++ if (sec_msg->security_type == PEER_SEC_TYPE_TKIP) { ++ mic_key = &key_conf->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; ++ memcpy(&sec_msg->mic_key[0], mic_key, NSS_WIFILI_MIC_KEY_LEN); ++ } ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ar->ab->nss.if_num, ++ NSS_WIFILI_PEER_SECURITY_TYPE_MSG, ++ sizeof(struct nss_wifili_peer_security_type_msg), ++ msg_cb, NULL); ++ ++ status = nss_wifili_tx_msg(ar->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "nss peer %d security cfg fail %d\n", ++ peer->peer_id, status); ++ goto free; ++ } ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss peer id %d security cfg complete\n", ++ peer->peer_id); ++free: ++ kfree(wlmsg); ++ return status; ++} ++ ++int ath11k_nss_set_peer_authorize(struct ath11k *ar, u16 peer_id) ++{ ++ struct nss_wifili_peer_update_auth_flag *auth_msg; ++ nss_wifili_msg_callback_t msg_cb; ++ struct nss_wifili_msg *wlmsg; ++ nss_tx_status_t status; ++ ++ if (!ar->ab->nss.enabled) ++ return 0; ++ ++ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); ++ if (!wlmsg) ++ return -ENOMEM; ++ ++ auth_msg = &wlmsg->msg.peer_auth; ++ auth_msg->peer_id = peer_id; ++ auth_msg->auth_flag = 1; ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ar->ab->nss.if_num, ++ NSS_WIFILI_PEER_UPDATE_AUTH_FLAG, ++ sizeof(struct nss_wifili_peer_update_auth_flag), ++ msg_cb, NULL); ++ ++ status = nss_wifili_tx_msg(ar->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "nss peer %d auth cfg fail %d\n", ++ peer_id, status); ++ goto free; ++ } ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss peer id %d auth cfg complete\n", ++ peer_id); ++free: ++ kfree(wlmsg); ++ return status; ++} ++ ++void ath11k_nss_update_sta_stats(struct station_info *sinfo, ++ struct ieee80211_sta *sta, ++ struct ath11k_sta *arsta) ++{ ++ struct sta_info *stainfo; ++ struct ath11k_peer *peer; ++ int tid_idx; ++ struct ath11k *ar = arsta->arvif->ar; ++ struct ath11k_base *ab = ar->ab; ++ ++ if (!ab->nss.enabled) ++ return; ++ ++ spin_lock_bh(&ab->base_lock); ++ peer = ath11k_peer_find_by_addr(arsta->arvif->ar->ab, sta->addr); ++ if (!peer) { ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "unable to find peer %pM\n", ++ sta->addr); ++ goto exit; ++ } ++ ++ if (!peer->nss.nss_stats) ++ goto exit; ++ ++ stainfo = container_of(sta, struct sta_info, sta); ++ if (peer->nss.nss_stats->last_rx && ++ time_after((unsigned long)peer->nss.nss_stats->last_rx, stainfo->deflink.rx_stats.last_rx)) ++ stainfo->deflink.rx_stats.last_rx = peer->nss.nss_stats->last_rx; ++ ++ if (peer->nss.nss_stats->last_ack && ++ time_after((unsigned long)peer->nss.nss_stats->last_ack, stainfo->deflink.status_stats.last_ack)) ++ stainfo->deflink.status_stats.last_ack = peer->nss.nss_stats->last_ack; ++ ++ stainfo->deflink.rx_stats.dropped += peer->nss.nss_stats->rx_dropped - ++ peer->nss.nss_stats->last_rxdrop; ++ peer->nss.nss_stats->last_rxdrop = peer->nss.nss_stats->rx_dropped; ++ ++ sinfo->tx_packets = 0; ++ /* Add only ac-0 count as mgmt packets uses WME_AC_BE */ ++ sinfo->tx_packets += stainfo->deflink.tx_stats.packets[WME_AC_BE]; ++ sinfo->tx_packets += peer->nss.nss_stats->tx_packets; ++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS); ++ sinfo->tx_bytes = 0; ++ ++ /* Add only ac-0 count as mgmt packets uses WME_AC_BE */ ++ sinfo->tx_bytes += stainfo->deflink.tx_stats.bytes[WME_AC_BE]; ++ sinfo->tx_bytes += peer->nss.nss_stats->tx_bytes; ++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES); ++ ++ sinfo->tx_failed = stainfo->deflink.status_stats.retry_failed + ++ peer->nss.nss_stats->tx_failed; ++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); ++ ++ sinfo->tx_retries = stainfo->deflink.status_stats.retry_count + ++ peer->nss.nss_stats->tx_retries; ++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); ++ ++ sinfo->rx_packets = stainfo->deflink.rx_stats.packets + ++ peer->nss.nss_stats->rx_packets; ++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS); ++ ++ sinfo->rx_bytes = stainfo->deflink.rx_stats.bytes + ++ peer->nss.nss_stats->rx_bytes; ++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES); ++ ++ if (peer->nss.nss_stats->rxrate.legacy || peer->nss.nss_stats->rxrate.nss) { ++ if (peer->nss.nss_stats->rxrate.legacy) { ++ sinfo->rxrate.legacy = peer->nss.nss_stats->rxrate.legacy; ++ } else { ++ sinfo->rxrate.mcs = peer->nss.nss_stats->rxrate.mcs; ++ sinfo->rxrate.nss = peer->nss.nss_stats->rxrate.nss; ++ sinfo->rxrate.bw = peer->nss.nss_stats->rxrate.bw; ++ sinfo->rxrate.he_gi = peer->nss.nss_stats->rxrate.he_gi; ++ sinfo->rxrate.he_dcm = peer->nss.nss_stats->rxrate.he_dcm; ++ sinfo->rxrate.he_ru_alloc = peer->nss.nss_stats->rxrate.he_ru_alloc; ++ } ++ sinfo->rxrate.flags = peer->nss.nss_stats->rxrate.flags; ++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE); ++ } ++ ++exit: ++ spin_unlock_bh(&ab->base_lock); ++} ++ ++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) ++{ ++ struct ath11k_sta *arsta = (struct ath11k_sta *)peer->sta->drv_priv; ++ u16 ath11k_hal_rx_legacy_rates[] = ++ { 10, 20, 55, 60, 90, 110, 120, 180, 240, 360, 480, 540 }; ++ u16 rate = 0; ++ u32 preamble_type; ++ u8 mcs, nss; ++ struct ath11k *ar = arsta->arvif->ar; ++ struct ath11k_base *ab = ar->ab; ++ ++ if (!ab->nss.enabled) ++ return; ++ ++ if (!peer->nss.nss_stats) ++ return; ++ ++ if (user_stats) { ++ mcs = user_stats->mcs; ++ nss = user_stats->nss; ++ preamble_type = user_stats->preamble_type; ++ } else { ++ mcs = ppdu_info->mcs; ++ nss = ppdu_info->nss; ++ preamble_type = ppdu_info->preamble_type; ++ } ++ ++ if ((preamble_type == WMI_RATE_PREAMBLE_CCK || ++ preamble_type == WMI_RATE_PREAMBLE_OFDM) && ++ (ppdu_info->rate < ATH11K_LEGACY_NUM)) { ++ rate = ath11k_hal_rx_legacy_rates[ppdu_info->rate]; ++ } ++ ++ memset(&peer->nss.nss_stats->rxrate, 0, sizeof(peer->nss.nss_stats->rxrate)); ++ ++ switch (preamble_type) { ++ case WMI_RATE_PREAMBLE_OFDM: ++ peer->nss.nss_stats->rxrate.legacy = rate; ++ break; ++ case WMI_RATE_PREAMBLE_CCK: ++ peer->nss.nss_stats->rxrate.legacy = rate; ++ break; ++ case WMI_RATE_PREAMBLE_HT: ++ if (mcs >= ATH11K_HT_MCS_NUM) { ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS, ++ "Received invalid mcs in HT mode %d\n", mcs); ++ return; ++ } ++ peer->nss.nss_stats->rxrate.mcs = mcs; ++ peer->nss.nss_stats->rxrate.flags = RATE_INFO_FLAGS_MCS; ++ if (ppdu_info->gi) ++ peer->nss.nss_stats->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI; ++ break; ++ case WMI_RATE_PREAMBLE_VHT: ++ if (mcs > ATH11K_VHT_MCS_MAX) { ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS, ++ "Received invalid mcs in VHT mode %d\n", mcs); ++ return; ++ } ++ peer->nss.nss_stats->rxrate.mcs = mcs; ++ peer->nss.nss_stats->rxrate.flags = RATE_INFO_FLAGS_VHT_MCS; ++ if (ppdu_info->gi) ++ peer->nss.nss_stats->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI; ++ break; ++ case WMI_RATE_PREAMBLE_HE: ++ if (mcs > ATH11K_HE_MCS_MAX) { ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS, ++ "Received invalid mcs in HE mode %d\n", mcs); ++ return; ++ } ++ 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; ++ peer->nss.nss_stats->rxrate.he_gi = ath11k_he_gi_to_nl80211_he_gi(ppdu_info->gi); ++ peer->nss.nss_stats->rxrate.he_ru_alloc = ppdu_info->ru_alloc; ++ break; ++ } ++ ++ peer->nss.nss_stats->rxrate.nss = nss; ++ peer->nss.nss_stats->rxrate.bw = ath11k_mac_bw_to_mac80211_bw(ppdu_info->bw); ++} ++ ++int ath11k_nss_peer_delete(struct ath11k_base *ab, const u8 *addr) ++{ ++ struct nss_wifili_peer_msg *peer_msg; ++ struct nss_wifili_msg *wlmsg = NULL; ++ struct ath11k_peer *peer; ++ nss_wifili_msg_callback_t msg_cb; ++ nss_tx_status_t status; ++ int ret; ++ ++ if (!ab->nss.enabled) ++ return 0; ++ ++ spin_lock_bh(&ab->base_lock); ++ ++ peer = ath11k_peer_find_by_addr(ab, addr); ++ if (!peer) { ++ ath11k_warn(ab, "peer (%pM) not found for nss peer delete\n", addr); ++ spin_unlock_bh(&ab->base_lock); ++ return -EINVAL; ++ } ++ ++ if (!peer->nss.vaddr) { ++ ath11k_warn(ab, "peer already deleted or peer create failed %pM\n", ++ addr); ++ spin_unlock_bh(&ab->base_lock); ++ return -EINVAL; ++ } ++ ++ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); ++ if (!wlmsg) { ++ ath11k_warn(ab, "nss send peer delete msg alloc failure\n"); ++ ret = -ENOMEM; ++ goto free_peer; ++ } ++ ++ peer_msg = &wlmsg->msg.peermsg; ++ ++ peer_msg->vdev_id = peer->vdev_id; ++ peer_msg->peer_id = peer->peer_id; ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_PEER_DELETE_MSG, ++ sizeof(struct nss_wifili_peer_msg), ++ msg_cb, NULL); ++ ++ reinit_completion(&peer->nss.complete); ++ ++ status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "nss send peer (%pM) delete msg tx error %d\n", ++ addr, status); ++ ret = -EINVAL; ++ kfree(wlmsg); ++ goto free_peer; ++ } else { ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "nss peer delete message success : peer_id %d\n", ++ peer->peer_id); ++ ret = 0; ++ } ++ ++ spin_unlock_bh(&ab->base_lock); ++ ++ kfree(wlmsg); ++ ++ /* No need to return failure or free up here, since the msg was tx succesfully ++ * the peer delete response would be received from NSS which will free up ++ * the allocated memory ++ */ ++ ret = wait_for_completion_timeout(&peer->nss.complete, ++ msecs_to_jiffies(ATH11K_NSS_MSG_TIMEOUT_MS)); ++ if (!ret) ++ ath11k_warn(ab, "timeout while waiting for nss peer delete msg response\n"); ++ ++ return 0; ++ ++free_peer: ++ dma_unmap_single(ab->dev, peer->nss.paddr, ++ WIFILI_NSS_PEER_BYTE_SIZE, DMA_FROM_DEVICE); ++ kfree(peer->nss.vaddr); ++ if (peer->nss.nss_stats) { ++ kfree(peer->nss.nss_stats); ++ peer->nss.nss_stats = NULL; ++ } ++ spin_unlock_bh(&ab->base_lock); ++ return ret; ++} ++ ++int ath11k_nss_peer_create(struct ath11k_base *ab, struct ath11k_peer *peer) ++{ ++ struct nss_wifili_peer_msg *peer_msg; ++ struct nss_wifili_msg *wlmsg = NULL; ++ nss_wifili_msg_callback_t msg_cb; ++ nss_tx_status_t status; ++ int ret; ++ ++ if (!ab->nss.enabled) ++ return -ENOTSUPP; ++ ++ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); ++ if (!wlmsg) ++ return -ENOMEM; ++ ++ peer_msg = &wlmsg->msg.peermsg; ++ ++ peer_msg->vdev_id = peer->vdev_id; ++ peer_msg->peer_id = peer->peer_id; ++ peer_msg->hw_ast_idx = peer->hw_peer_id; ++ peer_msg->tx_ast_hash = peer->ast_hash; ++ ether_addr_copy(peer_msg->peer_mac_addr, peer->addr); ++ ++ peer->nss.vaddr = kzalloc(WIFILI_NSS_PEER_BYTE_SIZE, GFP_ATOMIC); ++ ++ /* Initialize completion for verifying Peer NSS message response */ ++ init_completion(&peer->nss.complete); ++ ++ if (!peer->nss.vaddr) { ++ ath11k_warn(ab, "failed to allocate memory for nss peer info\n"); ++ kfree(wlmsg); ++ return -ENOMEM; ++ } ++ ++ peer->nss.paddr = dma_map_single(ab->dev, peer->nss.vaddr, ++ WIFILI_NSS_PEER_BYTE_SIZE, DMA_TO_DEVICE); ++ ++ ret = dma_mapping_error(ab->dev, peer->nss.paddr); ++ if (ret) { ++ ath11k_warn(ab, "error during nss peer info memalloc\n"); ++ kfree(peer->nss.vaddr); ++ ret = -ENOMEM; ++ goto msg_free; ++ } ++ ++ peer_msg->nss_peer_mem = peer->nss.paddr; ++ peer_msg->psta_vdev_id = peer->vdev_id; ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_PEER_CREATE_MSG, ++ sizeof(struct nss_wifili_peer_msg), ++ msg_cb, NULL); ++ ++ status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ret = -EINVAL; ++ ath11k_warn(ab, "nss send peer (%pM) create msg tx error\n", ++ peer->addr); ++ goto peer_mem_free; ++ } ++ ++ ret = 0; ++ ath11k_dbg(ab, ATH11K_DBG_NSS, ++ "nss peer_create msg success mac:%pM vdev:%d peer_id:%d hw_ast_idx:%d ast_hash:%d\n", ++ peer_msg->peer_mac_addr, peer_msg->vdev_id, peer_msg->peer_id, ++ peer_msg->hw_ast_idx, peer_msg->tx_ast_hash); ++ ++ peer->nss.nss_stats = kzalloc(sizeof(*peer->nss.nss_stats), GFP_ATOMIC); ++ if (!peer->nss.nss_stats) { ++ ret = -ENOMEM; ++ ath11k_warn(ab, "Unable to create nss stats memory\n"); ++ goto peer_mem_free; ++ } ++ ++ goto msg_free; ++ ++peer_mem_free: ++ dma_unmap_single(ab->dev, peer->nss.paddr, ++ WIFILI_NSS_PEER_BYTE_SIZE, DMA_FROM_DEVICE); ++ kfree(peer->nss.vaddr); ++msg_free: ++ kfree(wlmsg); ++ return ret; ++} ++ ++/*-------------------------------INIT/DEINIT---------------------------------*/ ++ ++static int ath11k_nss_radio_buf_cfg(struct ath11k *ar, int range, int buf_sz) ++{ ++ struct nss_wifili_radio_buf_cfg_msg *buf_cfg; ++ struct nss_wifili_radio_cfg_msg *radio_buf_cfg_msg; ++ struct nss_wifili_msg *wlmsg = NULL; ++ nss_tx_status_t status; ++ int ret = 0; ++ ++ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); ++ if (!wlmsg) ++ return -ENOMEM; ++ ++ radio_buf_cfg_msg = &wlmsg->msg.radiocfgmsg; ++ ++ radio_buf_cfg_msg->radio_if_num = ar->nss.if_num; ++ buf_cfg = &wlmsg->msg.radiocfgmsg.radiomsg.radiobufcfgmsg; ++ buf_cfg->range = range; ++ buf_cfg->buf_cnt = buf_sz; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ar->ab->nss.if_num, ++ NSS_WIFILI_RADIO_BUF_CFG, ++ sizeof(struct nss_wifili_radio_buf_cfg_msg), ++ NULL, NULL); ++ ++ status = nss_wifili_tx_msg(ar->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "nss radio buf cfg send failed %d\n", status); ++ ret = -EINVAL; ++ } else { ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS, ++ "nss radio cfg message range:%d buf_sz:%d if_num:%d ctx:%p\n", ++ range, buf_sz, ar->nss.if_num, ar->nss.ctx); ++ } ++ ++ kfree(wlmsg); ++ return ret; ++} ++ ++static void ath11k_nss_fill_srng_info(struct ath11k_base *ab, int ring_id, ++ struct nss_wifili_hal_srng_info *hsi) ++{ ++ struct ath11k_hal *hal = &ab->hal; ++ struct hal_srng *srng; ++ u32 offset; ++ int i; ++ ++ if (ring_id < 0) { ++ ath11k_warn(ab, "Invalid ring id used for nss init\n"); ++ WARN_ON(1); ++ return; ++ } ++ ++ srng = &hal->srng_list[ring_id]; ++ ++ hsi->ring_id = srng->ring_id; ++ hsi->ring_dir = srng->ring_dir; ++ hsi->ring_base_paddr = srng->ring_base_paddr; ++ hsi->entry_size = srng->entry_size; ++ hsi->num_entries = srng->num_entries; ++ hsi->flags = srng->flags; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, ++ "Ring info to send to nss - ring_id:%d ring_dir:%d ring_paddr:%d entry_size:%d num_entries:%d flags:%d\n", ++ hsi->ring_id, hsi->ring_dir, hsi->ring_base_paddr, ++ hsi->entry_size, hsi->num_entries, hsi->flags); ++ ++ for (i = 0; i < HAL_SRNG_NUM_REG_GRP; i++) { ++ offset = srng->hwreg_base[i]; ++ ++ /* For PCI based devices, get the umac ring base address offset ++ * based on window register configuration. ++ */ ++ if (!(srng->flags & HAL_SRNG_FLAGS_LMAC_RING)) ++ offset = ath11k_hif_get_window_offset(ab, srng->hwreg_base[i]); ++ ++ hsi->hwreg_base[i] = (u32)ab->mem_pa + offset; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "SRNG Register %d address %d\n", ++ i, hsi->hwreg_base[i]); ++ } ++} ++ ++static void ath11k_nss_tx_desc_mem_free(struct ath11k_base *ab) ++{ ++ int i; ++ ++ for (i = 0; i < ATH11K_NSS_MAX_NUMBER_OF_PAGE; i++) { ++ if (!ab->nss.tx_desc_paddr[i]) ++ continue; ++ ++ dma_free_coherent(ab->dev, ++ ab->nss.tx_desc_size[i], ++ ab->nss.tx_desc_vaddr[i], ++ ab->nss.tx_desc_paddr[i]); ++ ab->nss.tx_desc_vaddr[i] = NULL; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "allocated tx desc mem freed\n"); ++} ++ ++static int ath11k_nss_tx_desc_mem_alloc(struct ath11k_base *ab, u32 required_size, u32 *page_idx) ++{ ++ int i, alloc_size; ++ int curr_page_idx; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "tx desc mem alloc size: %d\n", required_size); ++ ++ curr_page_idx = *page_idx; ++ ++ for (i = 0, alloc_size = 0; i < required_size; i += alloc_size) { ++ alloc_size = required_size - i; ++ ++ if (alloc_size > WIFILI_NSS_MAX_MEM_PAGE_SIZE) ++ alloc_size = WIFILI_NSS_MAX_MEM_PAGE_SIZE; ++ ++ ab->nss.tx_desc_vaddr[curr_page_idx] = ++ dma_alloc_coherent(ab->dev, alloc_size, ++ &ab->nss.tx_desc_paddr[curr_page_idx], ++ GFP_KERNEL); ++ ++ if (!ab->nss.tx_desc_vaddr[curr_page_idx]) ++ return -ENOMEM; ++ ++ ab->nss.tx_desc_size[curr_page_idx] = alloc_size; ++ curr_page_idx++; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, ++ "curr page %d, allocated %d, total allocated %d\n", ++ curr_page_idx, alloc_size, i + alloc_size); ++ ++ if (curr_page_idx == ATH11K_NSS_MAX_NUMBER_OF_PAGE) { ++ ath11k_warn(ab, "max page number reached while tx desc mem allocation\n"); ++ return -EINVAL; ++ } ++ } ++ *page_idx = curr_page_idx; ++ return 0; ++} ++ ++static int ath11k_nss_fill_tx_desc_info(struct ath11k_base *ab, ++ struct nss_wifili_init_msg *wim) ++{ ++ struct nss_wifili_tx_desc_addtnl_mem_msg *dam; ++ u32 required_size, required_size_ext; ++ struct nss_wifili_tx_desc_init_msg *dim; ++ u32 tx_desc_limit_0 = 0; ++ u32 tx_desc_limit_1 = 0; ++ u32 tx_desc_limit_2 = 0; ++ u32 dam_page_idx = 0; ++ int page_idx = 0; ++ int i; ++ ++ wim->tx_sw_internode_queue_size = ATH11K_WIFIILI_MAX_TX_PROCESSQ; ++ ++ dim = &wim->wtdim; ++ dam = &wim->wtdam; ++ ++ dim->num_pool = ab->num_radios; ++ dim->num_tx_device_limit = ATH11K_WIFILI_MAX_TX_DESC; ++ ++ //TODO Revisit below calc based on platform/mem cfg ++ switch (dim->num_pool) { ++ case 1: ++ tx_desc_limit_0 = ATH11K_WIFILI_DBDC_NUM_TX_DESC; ++ break; ++ case 2: ++ tx_desc_limit_0 = ATH11K_WIFILI_DBDC_NUM_TX_DESC; ++ tx_desc_limit_1 = ATH11K_WIFILI_DBDC_NUM_TX_DESC; ++ break; ++ case 3: ++ tx_desc_limit_0 = ATH11K_WIFILI_DBTC_NUM_TX_DESC; ++ tx_desc_limit_1 = ATH11K_WIFILI_DBTC_NUM_TX_DESC; ++ tx_desc_limit_2 = ATH11K_WIFILI_DBTC_NUM_TX_DESC; ++ break; ++ default: ++ ath11k_warn(ab, "unexpected num radios during tx desc alloc\n"); ++ return -EINVAL; ++ } ++ ++ dim->num_tx_desc = tx_desc_limit_0; ++ dim->num_tx_desc_ext = tx_desc_limit_0; ++ dim->num_tx_desc_2 = tx_desc_limit_1; ++ dim->num_tx_desc_ext_2 = tx_desc_limit_1; ++ dim->num_tx_desc_3 = tx_desc_limit_2; ++ dim->num_tx_desc_ext_3 = tx_desc_limit_2; ++ ++ required_size = (dim->num_tx_desc + dim->num_tx_desc_2 + ++ dim->num_tx_desc_3 + ++ dim->num_pool) * WIFILI_NSS_TX_DESC_SIZE; ++ ++ required_size_ext = (dim->num_tx_desc_ext + dim->num_tx_desc_ext_2 + ++ dim->num_tx_desc_ext_3 + ++ dim->num_pool) * WIFILI_NSS_TX_EXT_DESC_SIZE; ++ ++ if (ath11k_nss_tx_desc_mem_alloc(ab, required_size, &page_idx)) { ++ ath11k_warn(ab, "memory allocation for tx desc of size %d failed\n", ++ required_size); ++ return -ENOMEM; ++ } ++ ++ /* Fill the page number from where extension tx descriptor is available */ ++ dim->ext_desc_page_num = page_idx; ++ ++ if (ath11k_nss_tx_desc_mem_alloc(ab, required_size_ext, &page_idx)) { ++ ath11k_warn(ab, "memory allocation for extension tx desc of size %d failed\n", ++ required_size_ext); ++ return -ENOMEM; ++ } ++ ++ for (i = 0; i < page_idx; i++) { ++ if (i < NSS_WIFILI_MAX_NUMBER_OF_PAGE_MSG) { ++ dim->memory_addr[i] = (u32)ab->nss.tx_desc_paddr[i]; ++ dim->memory_size[i] = (u32)ab->nss.tx_desc_size[i]; ++ dim->num_memaddr++; ++ } else { ++ dam_page_idx = i - NSS_WIFILI_MAX_NUMBER_OF_PAGE_MSG; ++ dam->addtnl_memory_addr[dam_page_idx] = (u32)ab->nss.tx_desc_paddr[i]; ++ dam->addtnl_memory_size[dam_page_idx] = (u32)ab->nss.tx_desc_size[i]; ++ dam->num_addtnl_addr++; ++ } ++ } ++ ++ if (i > NSS_WIFILI_MAX_NUMBER_OF_PAGE_MSG) ++ wim->flags |= WIFILI_ADDTL_MEM_SEG_SET; ++ ++ return 0; ++} ++ ++static int ath11k_nss_get_target_type(struct ath11k_base *ab) ++{ ++ switch (ab->hw_rev) { ++ case ATH11K_HW_IPQ8074: ++ return ATH11K_WIFILI_TARGET_TYPE_QCA8074V2; ++ case ATH11K_HW_IPQ6018_HW10: ++ return ATH11K_WIFILI_TARGET_TYPE_QCA6018; ++ case ATH11K_HW_QCN9074_HW10: ++ return ATH11K_WIFILI_TARGET_TYPE_QCN9074; ++ default: ++ ath11k_warn(ab, "NSS Offload not supported for this HW\n"); ++ return ATH11K_WIFILI_TARGET_TYPE_UNKNOWN; ++ } ++} ++ ++static int ath11k_nss_get_interface_type(struct ath11k_base *ab) ++{ ++ switch (ab->hw_rev) { ++ case ATH11K_HW_IPQ8074: ++ case ATH11K_HW_IPQ6018_HW10: ++ return NSS_WIFILI_INTERNAL_INTERFACE; ++ case ATH11K_HW_QCN9074_HW10: ++ return nss_get_available_wifili_external_if(); ++ default: ++ /* This can't happen since we validated target type earlier */ ++ WARN_ON(1); ++ return NSS_MAX_NET_INTERFACES; ++ } ++} ++ ++static int ath11k_nss_get_dynamic_interface_type(struct ath11k_base *ab) ++{ ++ switch (ab->nss.if_num) { ++ case NSS_WIFILI_INTERNAL_INTERFACE: ++ return NSS_DYNAMIC_INTERFACE_TYPE_WIFILI_INTERNAL; ++ case NSS_WIFILI_EXTERNAL_INTERFACE0: ++ return NSS_DYNAMIC_INTERFACE_TYPE_WIFILI_EXTERNAL0; ++ case NSS_WIFILI_EXTERNAL_INTERFACE1: ++ return NSS_DYNAMIC_INTERFACE_TYPE_WIFILI_EXTERNAL1; ++ default: ++ ath11k_warn(ab, "NSS Offload invalid interface\n"); ++ return NSS_DYNAMIC_INTERFACE_TYPE_NONE; ++ } ++} ++ ++static int ath11k_nss_init(struct ath11k_base *ab) ++{ ++ struct nss_wifili_init_msg *wim = NULL; ++ struct nss_wifili_msg *wlmsg = NULL; ++ struct nss_ctx_instance *nss_contex; ++ nss_wifili_msg_callback_t msg_cb; ++ u32 target_type; ++ u32 features = 0; ++ nss_tx_status_t status; ++ struct ath11k_dp *dp; ++ int i, ret; ++ ++ dp = &ab->dp; ++ ++ target_type = ath11k_nss_get_target_type(ab); ++ ++ if (target_type == ATH11K_WIFILI_TARGET_TYPE_UNKNOWN) ++ return -ENOTSUPP; ++ ++ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); ++ if (!wlmsg) ++ return -ENOMEM; ++ ++ wim = &wlmsg->msg.init; ++ ++ wim->target_type = target_type; ++ ++ /* fill rx parameters to initialize rx context */ ++ wim->wrip.tlv_size = ab->hw_params.hal_desc_sz; ++ wim->wrip.rx_buf_len = DP_RX_BUFFER_SIZE; ++ ++ /* fill hal srng message */ ++ wim->hssm.dev_base_addr = (u32)ab->mem_pa; ++ wim->hssm.shadow_rdptr_mem_addr = (u32)ab->hal.rdp.paddr; ++ wim->hssm.shadow_wrptr_mem_addr = (u32)ab->hal.wrp.paddr; ++ wim->hssm.lmac_rings_start_id = HAL_SRNG_RING_ID_LMAC1_ID_START; ++ ++ /* fill TCL data/completion ring info */ ++ wim->num_tcl_data_rings = DP_TCL_NUM_RING_MAX; ++ for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { ++ ath11k_nss_fill_srng_info(ab, dp->tx_ring[i].tcl_data_ring.ring_id, ++ &wim->tcl_ring_info[i]); ++ ath11k_nss_fill_srng_info(ab, dp->tx_ring[i].tcl_comp_ring.ring_id, ++ &wim->tx_comp_ring[i]); ++ } ++ ++ /* allocate tx desc memory for NSS and fill corresponding info */ ++ ret = ath11k_nss_fill_tx_desc_info(ab, wim); ++ if (ret) ++ goto free; ++ ++ /* fill reo dest ring info */ ++ wim->num_reo_dest_rings = DP_REO_DST_RING_MAX; ++ for (i = 0; i < DP_REO_DST_RING_MAX; i++) { ++ ath11k_nss_fill_srng_info(ab, dp->reo_dst_ring[i].ring_id, ++ &wim->reo_dest_ring[i]); ++ } ++ ++ /* fill reo reinject ring info */ ++ ath11k_nss_fill_srng_info(ab, dp->reo_reinject_ring.ring_id, ++ &wim->reo_reinject_ring); ++ ++ /* fill reo release ring info */ ++ ath11k_nss_fill_srng_info(ab, dp->rx_rel_ring.ring_id, ++ &wim->rx_rel_ring); ++ ++ /* fill reo exception ring info */ ++ ath11k_nss_fill_srng_info(ab, dp->reo_except_ring.ring_id, ++ &wim->reo_exception_ring); ++ ++ ab->nss.if_num = ath11k_nss_get_interface_type(ab); ++ ++ ath11k_info(ab, "nss init soc nss if_num %d userpd_id %d\n", ab->nss.if_num, ab->userpd_id); ++ ++ if (ab->nss.if_num >= NSS_MAX_NET_INTERFACES) { ++ ath11k_warn(ab, "NSS invalid interface\n"); ++ goto free; ++ } ++ ++ /* register callbacks for events and exceptions with nss */ ++ nss_contex = nss_register_wifili_if(ab->nss.if_num, NULL, ++ (nss_wifili_callback_t)ath11k_nss_wifili_ext_callback_fn, ++ (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive, ++ (struct net_device *)ab, features); ++ ++ if (!nss_contex) { ++ ath11k_warn(ab, "nss wifili register failure\n"); ++ goto free; ++ } ++ ++ if (nss_cmn_get_state(nss_contex) != NSS_STATE_INITIALIZED) { ++ ath11k_warn(ab, "nss state in default init state\n"); ++ goto free; ++ } ++ ++ /* The registered soc context is stored in ab, and will be used for ++ * all soc related messages with nss ++ */ ++ ab->nss.ctx = nss_contex; ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ /* Initialize the common part of the wlmsg */ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_INIT_MSG, ++ sizeof(struct nss_wifili_init_msg), ++ msg_cb, NULL); ++ ++ reinit_completion(&ab->nss.complete); ++ ++ /* Note: response is contention free during init sequence */ ++ ab->nss.response = ATH11K_NSS_MSG_ACK; ++ ++ status = nss_wifili_tx_msg(nss_contex, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "failure to send nss init msg\n"); ++ goto unregister; ++ } ++ ++ 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 nss init msg response\n"); ++ goto unregister; ++ } ++ ++ /* Check if the response is success from the callback */ ++ if (ab->nss.response != ATH11K_NSS_MSG_ACK) ++ goto unregister; ++ ++ kfree(wlmsg); ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "NSS Init Message TX Success %p %d\n", ++ ab->nss.ctx, ab->nss.if_num); ++ return 0; ++ ++unregister: ++ nss_unregister_wifili_if(ab->nss.if_num); ++free: ++ ath11k_nss_tx_desc_mem_free(ab); ++ kfree(wlmsg); ++ return -EINVAL; ++} ++ ++static int ath11k_nss_stats_cfg(struct ath11k *ar, int nss_msg, int enable) ++{ ++ struct nss_wifili_msg *wlmsg = NULL; ++ struct nss_wifili_stats_cfg_msg *stats_cfg; ++ nss_wifili_msg_callback_t msg_cb; ++ nss_tx_status_t status; ++ struct ath11k_base *ab = ar->ab; ++ int ret = 0; ++ ++ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); ++ if (!wlmsg) ++ return -ENOMEM; ++ ++ stats_cfg = &wlmsg->msg.scm; ++ stats_cfg->cfg = enable; ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ nss_msg, ++ sizeof(struct nss_wifili_stats_cfg_msg), ++ msg_cb, NULL); ++ ++ status = nss_wifili_tx_msg(ar->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "nss stats cfg %d msg tx failure\n", nss_msg); ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "nss stats %d enable %d\n", nss_msg, enable); ++ ++free: ++ kfree(wlmsg); ++ return ret; ++} ++ ++static void ath11k_nss_sojourn_stats_disable(struct ath11k *ar) ++{ ++ ath11k_nss_stats_cfg(ar, NSS_WIFILI_STATS_V2_CFG_MSG, ++ ATH11K_NSS_STATS_DISABLE); ++} ++ ++void ath11k_nss_peer_stats_disable(struct ath11k *ar) ++{ ++ ath11k_nss_stats_cfg(ar, NSS_WIFILI_STATS_CFG_MSG, ++ ATH11K_NSS_STATS_DISABLE); ++} ++ ++void ath11k_nss_peer_stats_enable(struct ath11k *ar) ++{ ++ ath11k_nss_stats_cfg(ar, NSS_WIFILI_STATS_CFG_MSG, ++ ATH11K_NSS_STATS_ENABLE); ++} ++ ++int ath11k_nss_pdev_init(struct ath11k_base *ab, int radio_id) ++{ ++ struct ath11k *ar = ab->pdevs[radio_id].ar; ++ struct nss_wifili_pdev_init_msg *pdevmsg; ++ struct nss_wifili_msg *wlmsg = NULL; ++ nss_wifili_msg_callback_t msg_cb; ++ nss_tx_status_t status; ++ int radio_if_num = -1; ++ int refill_ring_id; ++ int features = 0; ++ int dyn_if_type; ++ int ret, i; ++ ++ dyn_if_type = ath11k_nss_get_dynamic_interface_type(ab); ++ ++ /* Allocate a node for dynamic interface */ ++ radio_if_num = nss_dynamic_interface_alloc_node(dyn_if_type); ++ ++ if (radio_if_num < 0) ++ return -EINVAL; ++ ++ /* The ifnum and registered radio context is stored in ar and used ++ * for messages related to vdev/radio ++ */ ++ ar->nss.if_num = radio_if_num; ++ ++ /* No callbacks are registered for radio specific events/data */ ++ ar->nss.ctx = nss_register_wifili_radio_if((u32)radio_if_num, NULL, ++ NULL, NULL, (struct net_device *)ar, ++ features); ++ ++ if (!ar->nss.ctx) { ++ ath11k_warn(ab, "failure during nss pdev register\n"); ++ ret = -EINVAL; ++ goto dealloc; ++ } ++ ++ 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); ++ ++ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); ++ if (!wlmsg) { ++ ret = -ENOMEM; ++ goto unregister; ++ } ++ ++ pdevmsg = &wlmsg->msg.pdevmsg; ++ ++ pdevmsg->radio_id = radio_id; ++ 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; ++ ++ /* Store rxdma ring info to the message */ ++ refill_ring_id = ar->dp.rx_refill_buf_ring.refill_buf_ring.ring_id; ++ ath11k_nss_fill_srng_info(ab, refill_ring_id, &pdevmsg->rxdma_ring); ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_PDEV_INIT_MSG, ++ sizeof(struct nss_wifili_pdev_init_msg), ++ msg_cb, NULL); ++ ++ reinit_completion(&ab->nss.complete); ++ ++ /* Note: response is contention free during init sequence */ ++ ab->nss.response = ATH11K_NSS_MSG_ACK; ++ ++ status = nss_wifili_tx_msg(ar->nss.ctx, wlmsg); ++ ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "nss send pdev msg tx error : %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 pdev init msg response\n"); ++ ret = -ETIMEDOUT; ++ goto free; ++ } ++ ++ /* Check if the response is success from the callback */ ++ if (ab->nss.response != ATH11K_NSS_MSG_ACK) { ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ kfree(wlmsg); ++ ++ /* Disable nss sojourn stats by default */ ++ ath11k_nss_sojourn_stats_disable(ar); ++ /* Enable nss wifili peer stats by default */ ++ ath11k_nss_peer_stats_enable(ar); ++ ++ /*TODO CFG Tx buffer limit as per no clients range per radio ++ * this needs to be based on target/mem cfg ++ * similar to tx desc cfg at soc init per radio ++ */ ++ ++ for (i = 0; i < ATH11K_NSS_RADIO_TX_LIMIT_RANGE; i++) ++ ath11k_nss_radio_buf_cfg(ar, i, ATH11K_NSS_RADIO_TX_LIMIT_RANGE3); ++ ++ return 0; ++ ++free: ++ kfree(wlmsg); ++unregister: ++ nss_unregister_wifili_radio_if(ar->nss.if_num); ++dealloc: ++ nss_dynamic_interface_dealloc_node(ar->nss.if_num, dyn_if_type); ++ return ret; ++} ++ ++/* TODO : Check if start, reset and stop messages can be done using single function as ++ * body is similar, having it now for clarity */ ++ ++int ath11k_nss_start(struct ath11k_base *ab) ++{ ++ struct nss_wifili_msg *wlmsg = NULL; ++ nss_wifili_msg_callback_t msg_cb; ++ nss_tx_status_t status; ++ int ret; ++ ++ 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; ++ ++ /* Empty message for NSS Start message */ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_START_MSG, ++ 0, ++ msg_cb, NULL); ++ ++ reinit_completion(&ab->nss.complete); ++ ++ /* Note: response is contention free during init sequence */ ++ ab->nss.response = ATH11K_NSS_MSG_ACK; ++ ++ status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg); ++ ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "nss send start msg tx error %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 response for nss start msg\n"); ++ ret = -ETIMEDOUT; ++ goto free; ++ } ++ ++ /* Check if the response is success from the callback */ ++ if (ab->nss.response != ATH11K_NSS_MSG_ACK) { ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ /* NSS Start success */ ++ ret = 0; ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "nss start success\n"); ++ ++free: ++ kfree(wlmsg); ++ return ret; ++} ++ ++static void ath11k_nss_reset(struct ath11k_base *ab) ++{ ++ struct nss_wifili_msg *wlmsg = NULL; ++ nss_wifili_msg_callback_t msg_cb; ++ nss_tx_status_t status; ++ int ret; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "NSS reset\n"); ++ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); ++ if (!wlmsg) { ++ ath11k_warn(ab, "mem allocation failure during nss reset\n"); ++ return; ++ } ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ /* Empty message for NSS Reset message */ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_SOC_RESET_MSG, ++ 0, ++ msg_cb, NULL); ++ ++ reinit_completion(&ab->nss.complete); ++ ++ /* Note: response is contention free during deinit sequence */ ++ ab->nss.response = ATH11K_NSS_MSG_ACK; ++ ++ status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg); ++ ++ /* Add a retry mechanism to reset nss until success */ ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "nss send reset msg tx error %d\n", status); ++ 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 response for nss reset msg\n"); ++ goto free; ++ } ++ ++ /* Check if the response is success from the callback */ ++ if (ab->nss.response != ATH11K_NSS_MSG_ACK) { ++ ath11k_warn(ab, "failure response during nss reset %d\n", ab->nss.response); ++ goto free; ++ } ++ ++ /* Unregister wifili interface */ ++ nss_unregister_wifili_if(ab->nss.if_num); ++ ++free: ++ kfree(wlmsg); ++} ++ ++static int ath11k_nss_stop(struct ath11k_base *ab) ++{ ++ struct nss_wifili_msg *wlmsg = NULL; ++ nss_wifili_msg_callback_t msg_cb; ++ nss_tx_status_t status; ++ int ret; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "NSS stop\n"); ++ 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; ++ ++ /* Empty message for Stop command */ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_STOP_MSG, ++ 0, ++ msg_cb, NULL); ++ ++ reinit_completion(&ab->nss.complete); ++ ++ /* Note: response is contention free during deinit sequence */ ++ ab->nss.response = ATH11K_NSS_MSG_ACK; ++ ++ status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg); ++ ++ /* Add a retry mechanism to stop nss until success */ ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "nss send stop msg tx error %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 response for nss stop msg\n"); ++ ret = -ETIMEDOUT; ++ goto free; ++ } ++ ++ /* Check if the response is success from the callback */ ++ if (ab->nss.response != ATH11K_NSS_MSG_ACK) { ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ /* NSS Stop success */ ++ ret = 0; ++free: ++ kfree(wlmsg); ++ return ret; ++} ++ ++int ath11k_nss_pdev_deinit(struct ath11k_base *ab, int radio_id) ++{ ++ struct ath11k *ar = ab->pdevs[radio_id].ar; ++ struct nss_wifili_pdev_deinit_msg *deinit; ++ struct nss_wifili_msg *wlmsg = NULL; ++ nss_wifili_msg_callback_t msg_cb; ++ nss_tx_status_t status; ++ int dyn_if_type; ++ int ret; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "NSS pdev %d deinit\n", radio_id); ++ dyn_if_type = ath11k_nss_get_dynamic_interface_type(ab); ++ ++ /* Disable NSS wifili peer stats before teardown */ ++ if (ab->nss.stats_enabled) ++ ath11k_nss_peer_stats_disable(ar); ++ ++ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); ++ if (!wlmsg) ++ return -ENOMEM; ++ ++ deinit = &wlmsg->msg.pdevdeinit; ++ deinit->ifnum = radio_id; ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_PDEV_DEINIT_MSG, ++ sizeof(struct nss_wifili_pdev_deinit_msg), ++ msg_cb, NULL); ++ ++ reinit_completion(&ab->nss.complete); ++ ++ /* Note: response is contention free during deinit sequence */ ++ ab->nss.response = ATH11K_NSS_MSG_ACK; ++ ++ status = nss_wifili_tx_msg(ar->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "nss send pdev deinit msg tx error %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 pdev deinit msg response\n"); ++ ret = -ETIMEDOUT; ++ goto free; ++ } ++ ++ /* Check if the response is success from the callback */ ++ if (ab->nss.response != ATH11K_NSS_MSG_ACK) { ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ /* pdev deinit msg success, dealloc, deregister and return */ ++ ret = 0; ++ ++ nss_dynamic_interface_dealloc_node(ar->nss.if_num, dyn_if_type); ++ nss_unregister_wifili_radio_if(ar->nss.if_num); ++free: ++ kfree(wlmsg); ++ return ret; ++} ++ ++int ath11k_nss_teardown(struct ath11k_base *ab) ++{ ++ int i, ret; ++ ++ if (!ab->nss.enabled) ++ return 0; ++ ++ ath11k_nss_stop(ab); ++ ++ for (i = 0; i < ab->num_radios ; i++) { ++ ret = ath11k_nss_pdev_deinit(ab, i); ++ if (ret) ++ ath11k_warn(ab, "failure during pdev%d deinit\n", i); ++ } ++ ++ ath11k_nss_reset(ab); ++ ath11k_nss_tx_desc_mem_free(ab); ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "NSS Teardown Complete\n"); ++ ++ return 0; ++} ++ ++int ath11k_nss_setup(struct ath11k_base *ab) ++{ ++ int i; ++ int ret = 0; ++ u32 target_type; ++ ++ if (!ab->nss.enabled) ++ return 0; ++ ++ target_type = ath11k_nss_get_target_type(ab); ++ ++ if (target_type == ATH11K_WIFILI_TARGET_TYPE_UNKNOWN) ++ return -ENOTSUPP; ++ ++ /* Verify NSS support is enabled */ ++ if (nss_cmn_get_nss_enabled() == false) { ++ ath11k_warn(ab, "NSS offload support disabled, falling back to default mode\n"); ++ return -ENOTSUPP; ++ } ++ ++ /* Initialize completion for verifying NSS message response */ ++ init_completion(&ab->nss.complete); ++ ++ /* Setup common resources for NSS */ ++ ret = ath11k_nss_init(ab); ++ if (ret) { ++ ath11k_warn(ab, "NSS SOC Initialization Failed :%d\n", ret); ++ goto fail; ++ } ++ ++ /* Setup pdev related resources for NSS */ ++ for (i = 0; i < ab->num_radios; i++) { ++ ret = ath11k_nss_pdev_init(ab, i); ++ if (ret) { ++ ath11k_warn(ab, "NSS PDEV %d Initialization Failed :%d\n", i, ret); ++ goto pdev_deinit; ++ } ++ } ++ ++ /* Set the NSS statemachine to start */ ++ ret = ath11k_nss_start(ab); ++ if (ret) { ++ ath11k_warn(ab, "NSS Start Failed : %d\n", ret); ++ goto pdev_deinit; ++ } ++ ++ /* Default nexthop interface is set to ETH RX */ ++ ret = nss_wifi_vdev_base_set_next_hop(ab->nss.ctx, NSS_ETH_RX_INTERFACE); ++ if (ret != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "Failure to set default next hop : %d\n", ret); ++ goto stop; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "NSS Setup Complete\n"); ++ return ret; ++ ++stop: ++ ath11k_nss_stop(ab); ++ ++pdev_deinit: ++ for (i -= 1; i >= 0; i--) ++ ath11k_nss_pdev_deinit(ab, i); ++ ++ ath11k_nss_reset(ab); ++ ath11k_nss_tx_desc_mem_free(ab); ++fail: ++ return ret; ++} +--- /dev/null ++++ b/drivers/net/wireless/ath/ath11k/nss.h +@@ -0,0 +1,307 @@ ++/* SPDX-License-Identifier: BSD-3-Clause-Clear */ ++/* ++ * Copyright (c) 2020 The Linux Foundation. All rights reserved. ++ */ ++ ++#ifndef ATH11K_NSS_H ++#define ATH11K_NSS_H ++ ++#include "net/cfg80211.h" ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++#include ++#include ++ ++#endif ++struct ath11k; ++struct ath11k_base; ++struct ath11k_vif; ++struct ath11k_peer; ++struct ath11k_sta; ++struct hal_rx_mon_ppdu_info; ++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 0x80000000 ++ ++/* WIFILI Supported Target Types */ ++#define ATH11K_WIFILI_TARGET_TYPE_UNKNOWN 0xFF ++#define ATH11K_WIFILI_TARGET_TYPE_QCA8074 20 ++#define ATH11K_WIFILI_TARGET_TYPE_QCA8074V2 24 ++#define ATH11K_WIFILI_TARGET_TYPE_QCA6018 25 ++#define ATH11K_WIFILI_TARGET_TYPE_QCN9074 26 ++#define ATH11K_WIFILI_TARGET_TYPE_QCA5018 29 ++ ++/* Max limit for NSS Queue */ ++#define ATH11K_WIFIILI_MAX_TX_PROCESSQ 1024 ++ ++/* Max TX Desc limit */ ++#define ATH11K_WIFILI_MAX_TX_DESC 65536 ++ ++/* TX Desc related info */ ++/*TODO : Check this again during experiments for lowmem or ++ changes for platforms based on num radios supported */ ++#define ATH11K_WIFILI_DBDC_NUM_TX_DESC (1024 * 8) ++#define ATH11K_WIFILI_DBTC_NUM_TX_DESC (1024 * 8) ++ ++// TODO Revisit these page size calc ++#define WIFILI_NSS_TX_DESC_SIZE 20*4 ++#define WIFILI_NSS_TX_EXT_DESC_SIZE 40*4 ++/* Number of desc per page(12bit) should be<4096, page limit per 1024 byte is 80*3=240 */ ++#define WIFILI_NSS_TX_DESC_PAGE_LIMIT 240 ++#define WIFILI_NSS_MAX_MEM_PAGE_SIZE (WIFILI_NSS_TX_DESC_PAGE_LIMIT * 1024) ++#define WIFILI_NSS_MAX_EXT_MEM_PAGE_SIZE (WIFILI_NSS_TX_DESC_PAGE_LIMIT * 1024) ++#define WIFILI_RX_DESC_POOL_WEIGHT 3 ++ ++/* Status of the NSS messages sent from driver */ ++#define ATH11K_NSS_MSG_ACK 0 ++/* Timeout for waiting for response from NSS on TX msg */ ++#define ATH11K_NSS_MSG_TIMEOUT_MS 5000 ++ ++/* Init Flags */ ++#define WIFILI_NSS_CCE_DISABLED 0x1 ++#define WIFILI_ADDTL_MEM_SEG_SET 0x000000002 ++ ++/* ATH11K NSS PEER Info */ ++/* Host memory allocated for peer info storage in nss */ ++#define WIFILI_NSS_PEER_BYTE_SIZE NSS_WIFILI_PEER_SIZE ++ ++/* ATH11K NSS Stats */ ++#define ATH11K_NSS_STATS_ENABLE 1 ++#define ATH11K_NSS_STATS_DISABLE 0 ++ ++/* TX Buf cfg range */ ++#define ATH11K_NSS_RADIO_TX_LIMIT_RANGE 4 ++ ++/* TODO : Analysis based on platform */ ++/* TX Limit till 64 clients */ ++#define ATH11K_NSS_RADIO_TX_LIMIT_RANGE0 8192 ++/* TX Limit till 128 clients */ ++#define ATH11K_NSS_RADIO_TX_LIMIT_RANGE1 8192 ++/* TX Limit till 256 clients */ ++#define ATH11K_NSS_RADIO_TX_LIMIT_RANGE2 8192 ++/* TX Limit > 256 clients */ ++#define ATH11K_NSS_RADIO_TX_LIMIT_RANGE3 8192 ++ ++#define ATH11K_NSS_MAX_NUMBER_OF_PAGE 96 ++ ++#define NSS_TX_TID_MAX 8 ++ ++#define ATH11K_NSS_TXRX_NETDEV_STATS(txrx, vif, len, pkt_count) \ ++do { \ ++ struct wireless_dev *wdev = ieee80211_vif_to_wdev(vif); \ ++ struct pcpu_sw_netstats *tstats; \ ++ \ ++ if (!wdev) \ ++ break; \ ++ tstats = this_cpu_ptr(netdev_tstats(wdev->netdev)); \ ++ u64_stats_update_begin(&tstats->syncp); \ ++ u64_stats_add(&tstats->txrx ## _packets, pkt_count); \ ++ u64_stats_add(&tstats->txrx ## _bytes, len); \ ++ u64_stats_update_end(&tstats->syncp); \ ++} while (0) ++ ++enum ath11k_nss_opmode { ++ ATH11K_NSS_OPMODE_UNKNOWN, ++ ATH11K_NSS_OPMODE_AP, ++ ATH11K_NSS_OPMODE_IBSS, ++ ATH11K_NSS_OPMODE_STA, ++ ATH11K_NSS_OPMODE_MONITOR, ++}; ++ ++struct peer_stats { ++ u64 last_rx; ++ u64 last_ack; ++ u32 tx_packets; ++ u32 tx_bytes; ++ u32 tx_retries; ++ u32 tx_failed; ++ u32 rx_packets; ++ u32 rx_bytes; ++ u32 rx_dropped; ++ u32 last_rxdrop; ++ struct rate_info rxrate; ++}; ++ ++enum ath11k_nss_peer_sec_type { ++ PEER_SEC_TYPE_NONE, ++ PEER_SEC_TYPE_WEP128, ++ PEER_SEC_TYPE_WEP104, ++ PEER_SEC_TYPE_WEP40, ++ PEER_SEC_TYPE_TKIP, ++ PEER_SEC_TYPE_TKIP_NOMIC, ++ PEER_SEC_TYPE_AES_CCMP, ++ PEER_SEC_TYPE_WAPI, ++ PEER_SEC_TYPE_AES_CCMP_256, ++ PEER_SEC_TYPE_AES_GCMP, ++ PEER_SEC_TYPE_AES_GCMP_256, ++ PEER_SEC_TYPES_MAX ++}; ++ ++/* this holds the memory allocated for nss managed peer info */ ++struct ath11k_nss_peer { ++ uint32_t *vaddr; ++ dma_addr_t paddr; ++ struct peer_stats *nss_stats; ++ struct completion complete; ++}; ++ ++/* 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; ++ /* Used for completion status for vdev config nss messages */ ++ struct completion complete; ++ /* Keep the copy of encap type for nss */ ++ int encap; ++ /* Keep the copy of decap type for nss */ ++ int decap; ++ bool created; ++}; ++ ++/* Structure to hold the pdev/radio related info for nss offload support */ ++struct ath11k_nss { ++ /* dynamic ifnum allocated by nss driver for pdev */ ++ int if_num; ++ /* Radio/pdev Context obtained on pdev register */ ++ void* ctx; ++}; ++ ++/* Structure to hold the soc related info for nss offload support */ ++struct ath11k_soc_nss { ++ /* turn on/off nss offload support in ath11k */ ++ bool enabled; ++ /* turn on/off nss stats support in ath11k */ ++ bool stats_enabled; ++ /* soc nss ctx */ ++ void* ctx; ++ /* if_num to be used for soc related nss messages */ ++ int if_num; ++ /* debug mode to disable the regular mesh configuration from mac80211 */ ++ bool debug_mode; ++ /* Completion to nss message response */ ++ struct completion complete; ++ /* Response to nss messages are stored here on msg callback ++ * used only in contention free messages during init */ ++ int response; ++ /* Below is used for identifying allocated tx descriptors */ ++ dma_addr_t tx_desc_paddr[ATH11K_NSS_MAX_NUMBER_OF_PAGE]; ++ uint32_t * tx_desc_vaddr[ATH11K_NSS_MAX_NUMBER_OF_PAGE]; ++ uint32_t tx_desc_size[ATH11K_NSS_MAX_NUMBER_OF_PAGE]; ++}; ++ ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++int ath11k_nss_tx(struct ath11k_vif *arvif, struct sk_buff *skb); ++int ath11k_nss_vdev_set_cmd(struct ath11k_vif *arvif, int cmd, int val); ++int ath11k_nss_vdev_create(struct ath11k_vif *arvif); ++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); ++int ath11k_nss_peer_delete(struct ath11k_base *ab, const u8 *addr); ++int ath11k_nss_set_peer_authorize(struct ath11k *ar, u16 peer_id); ++int ath11k_nss_peer_create(struct ath11k_base *ab, struct ath11k_peer *peer); ++void ath11k_nss_peer_stats_enable(struct ath11k *ar); ++void ath11k_nss_peer_stats_disable(struct ath11k *ar); ++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, ++ struct ieee80211_sta *sta, ++ struct ath11k_sta *arsta); ++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); ++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); ++#else ++static inline int ath11k_nss_tx(struct ath11k_vif *arvif, struct sk_buff *skb) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_vdev_set_cmd(struct ath11k_vif *arvif, int cmd, int val) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_vdev_create(struct ath11k_vif *arvif) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_set_peer_authorize(struct ath11k *ar, u16 peer_id) ++{ ++ return 0; ++} ++ ++static inline void ath11k_nss_vdev_delete(struct ath11k_vif *arvif) ++{ ++} ++ ++static inline void ath11k_nss_update_sta_stats(struct station_info *sinfo, ++ struct ieee80211_sta *sta, ++ struct ath11k_sta *arsta) ++{ ++ return; ++} ++ ++static inline 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) ++{ ++ return; ++} ++ ++static inline int ath11k_nss_vdev_up(struct ath11k_vif *arvif) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_vdev_down(struct ath11k_vif *arvif) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_peer_delete(struct ath11k_base *ab, const u8 *addr) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_peer_create(struct ath11k_base *ab, struct ath11k_peer *peer) ++{ ++ return 0; ++} ++ ++static inline void ath11k_nss_peer_stats_enable(struct ath11k *ar) ++{ ++ return; ++} ++ ++static inline void ath11k_nss_peer_stats_disable(struct ath11k *ar) ++{ ++ return; ++} ++ ++static inline int ath11k_nss_set_peer_sec_type(struct ath11k *ar, struct ath11k_peer *peer, ++ struct ieee80211_key_conf *key_conf) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_setup(struct ath11k_base *ab) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_teardown(struct ath11k_base *ab) ++{ ++ return 0; ++} ++ ++static inline void ath11k_nss_ext_rx_stats(struct ath11k_base *ab, ++ struct htt_rx_ring_tlv_filter *tlv_filter) ++{ ++ return; ++} ++#endif /* CPTCFG_ATH11K_NSS_SUPPORT */ ++#endif +--- a/drivers/net/wireless/ath/ath11k/hif.h ++++ b/drivers/net/wireless/ath/ath11k/hif.h +@@ -30,6 +30,7 @@ struct ath11k_hif_ops { + void (*ce_irq_enable)(struct ath11k_base *ab); + void (*ce_irq_disable)(struct ath11k_base *ab); + void (*get_ce_msi_idx)(struct ath11k_base *ab, u32 ce_id, u32 *msi_idx); ++ u32 (*get_window_offset)(struct ath11k_base *ab, u32 offset); + }; + + static inline void ath11k_hif_ce_irq_enable(struct ath11k_base *ab) +@@ -136,6 +137,14 @@ static inline void ath11k_get_msi_addres + ab->hif.ops->get_msi_address(ab, msi_addr_lo, msi_addr_hi); + } + ++static inline u32 ath11k_hif_get_window_offset(struct ath11k_base *ab, u32 offset) ++{ ++ if (ab->hif.ops->get_window_offset) ++ return ab->hif.ops->get_window_offset(ab, offset); ++ ++ return offset; ++} ++ + static inline void ath11k_get_ce_msi_idx(struct ath11k_base *ab, u32 ce_id, + u32 *msi_data_idx) + { +--- a/drivers/net/wireless/ath/ath11k/pci.c ++++ b/drivers/net/wireless/ath/ath11k/pci.c +@@ -67,6 +67,20 @@ static u32 ath11k_pci_get_window_start(s + return ATH11K_PCI_WINDOW_START; + } + ++static inline u32 ath11k_pci_get_window_offset(struct ath11k_base *ab, ++ u32 offset) ++{ ++ u32 window_start; ++ ++ if (ab->hw_params.static_window_map) { ++ window_start = ath11k_pci_get_window_start(ab, offset); ++ ++ if (window_start) ++ offset = window_start + (offset & ATH11K_PCI_WINDOW_RANGE_MASK); ++ } ++ return offset; ++} ++ + 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 + .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, ++ .get_window_offset = ath11k_pci_get_window_offset, + .get_ce_msi_idx = ath11k_pcic_get_ce_msi_idx, + }; + +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -992,6 +992,29 @@ unlock_exit: + spin_unlock_bh(&ab->base_lock); + } + ++/* Sends WMI config to filter packets to route packets to WBM release ring */ ++int ath11k_dp_rx_pkt_type_filter(struct ath11k *ar, enum ath11k_routing_pkt_type pkt_type, u32 meta_data) ++{ ++ struct ath11k_wmi_pkt_route_param param; ++ int ret; ++ ++ /* Routing Eapol packets to CCE is only allowed now */ ++ if (pkt_type != ATH11K_PKT_TYPE_EAP) ++ return -EINVAL; ++ ++ param.opcode = ATH11K_WMI_PKTROUTE_ADD; ++ param.meta_data = meta_data; ++ param.dst_ring = ATH11K_ROUTE_WBM_RELEASE; ++ param.dst_ring_handler = ATH11K_WMI_PKTROUTE_USE_CCE; ++ param.route_type_bmap = 1 << pkt_type; ++ ++ ret = ath11k_wmi_send_pdev_pkt_route(ar, ¶m); ++ if (ret) ++ ath11k_warn(ar->ab, "failed to configure pkt route %d", ret); ++ ++ return ret; ++} ++ + 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) +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -1164,6 +1164,44 @@ int ath11k_wmi_send_pdev_set_regdomain(s + return ret; + } + ++int ath11k_wmi_send_pdev_pkt_route(struct ath11k *ar, struct ath11k_wmi_pkt_route_param *param) ++{ ++ struct ath11k_pdev_wmi *wmi = ar->wmi; ++ struct wmi_pdev_pkt_route_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_pkt_route_cmd *)skb->data; ++ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, ++ WMI_TAG_PDEV_UPDATE_PKT_ROUTING_CMD) | ++ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); ++ ++ cmd->pdev_id = ar->pdev->pdev_id; ++ cmd->opcode = param->opcode; ++ cmd->route_type_bmap = param->route_type_bmap; ++ cmd->dst_ring = param->dst_ring; ++ cmd->meta_data = param->meta_data; ++ cmd->dst_ring_handler = param->dst_ring_handler; ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, ++ "WMI pdev pkt route opcode %d route_bmap %d dst_ring %d meta_datan %d dst_ringg_handler %d\n", ++ param->opcode, param->route_type_bmap, ++ param->dst_ring, param->meta_data, param->dst_ring_handler); ++ ++ ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PDEV_UPDATE_PKT_ROUTING_CMDID); ++ if (ret) { ++ ath11k_warn(ar->ab, ++ "failed to send WMI_PDEV_UPDATE_PKT_ROUTING cmd\n"); ++ dev_kfree_skb(skb); ++ } ++ ++ return ret; ++} ++ + int ath11k_wmi_set_peer_param(struct ath11k *ar, const u8 *peer_addr, + u32 vdev_id, u32 param_id, u32 param_val) + { +--- a/drivers/net/wireless/ath/ath11k/wmi.h ++++ b/drivers/net/wireless/ath/ath11k/wmi.h +@@ -2873,6 +2873,27 @@ struct pdev_set_regdomain_params { + u32 pdev_id; + }; + ++ /* Defines various options for routing policy */ ++enum wmi_pdev_dest_ring_handler_type { ++ ATH11K_WMI_PKTROUTE_USE_CCE = 0, ++ ATH11K_WMI_PKTROUTE_USE_ASPT = 1, ++ ATH11K_WMI_PKTROUTE_USE_FSE = 2, ++ ATH11K_WMI_PKTROUTE_USE_CCE2 = 3, ++}; ++ ++enum ath11k_wmi_pkt_route_opcode { ++ ATH11K_WMI_PKTROUTE_ADD, ++ ATH11K_WMI_PKTROUTE_DEL, ++}; ++ ++struct ath11k_wmi_pkt_route_param { ++ enum ath11k_wmi_pkt_route_opcode opcode; ++ u32 route_type_bmap; ++ u32 dst_ring_handler; ++ u32 dst_ring; ++ u32 meta_data; ++}; ++ + struct rx_reorder_queue_remove_params { + u8 *peer_macaddr; + u16 vdev_id; +@@ -3121,6 +3142,16 @@ struct wmi_pdev_set_regdomain_cmd { + u32 dfs_domain; + } __packed; + ++struct wmi_pdev_pkt_route_cmd { ++ u32 tlv_header; ++ u32 pdev_id; ++ u32 opcode; ++ u32 route_type_bmap; ++ u32 dst_ring; ++ u32 meta_data; ++ u32 dst_ring_handler; ++} __packed; ++ + struct wmi_peer_set_param_cmd { + u32 tlv_header; + u32 vdev_id; +@@ -6362,6 +6393,8 @@ int ath11k_wmi_send_peer_create_cmd(stru + int ath11k_wmi_vdev_set_param_cmd(struct ath11k *ar, u32 vdev_id, + u32 param_id, u32 param_value); + ++int ath11k_wmi_send_pdev_pkt_route(struct ath11k *ar, ++ struct ath11k_wmi_pkt_route_param *param); + int ath11k_wmi_set_sta_ps_param(struct ath11k *ar, u32 vdev_id, + u32 param, u32 param_value); + int ath11k_wmi_force_fw_hang_cmd(struct ath11k *ar, u32 type, u32 delay_time_ms); +--- a/drivers/net/wireless/ath/ath11k/dp_rx.h ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.h +@@ -20,6 +20,34 @@ + #define DP_RX_MPDU_ERR_MPDU_LEN BIT(6) + #define DP_RX_MPDU_ERR_UNENCRYPTED_FRAME BIT(7) + ++/* different supported pkt types for routing */ ++enum ath11k_routing_pkt_type { ++ ATH11K_PKT_TYPE_ARP_IPV4, ++ ATH11K_PKT_TYPE_NS_IPV6, ++ ATH11K_PKT_TYPE_IGMP_IPV4, ++ ATH11K_PKT_TYPE_MLD_IPV6, ++ ATH11K_PKT_TYPE_DHCP_IPV4, ++ ATH11K_PKT_TYPE_DHCP_IPV6, ++ ATH11K_PKT_TYPE_DNS_TCP_IPV4, ++ ATH11K_PKT_TYPE_DNS_TCP_IPV6, ++ ATH11K_PKT_TYPE_DNS_UDP_IPV4, ++ ATH11K_PKT_TYPE_DNS_UDP_IPV6, ++ ATH11K_PKT_TYPE_ICMP_IPV4, ++ ATH11K_PKT_TYPE_ICMP_IPV6, ++ ATH11K_PKT_TYPE_TCP_IPV4, ++ ATH11K_PKT_TYPE_TCP_IPV6, ++ ATH11K_PKT_TYPE_UDP_IPV4, ++ ATH11K_PKT_TYPE_UDP_IPV6, ++ ATH11K_PKT_TYPE_IPV4, ++ ATH11K_PKT_TYPE_IPV6, ++ ATH11K_PKT_TYPE_EAP, ++ ATH11K_PKT_TYPE_MAX ++}; ++ ++#define ATH11K_RX_PROTOCOL_TAG_START_OFFSET 128 ++#define ATH11K_ROUTE_WBM_RELEASE 5 ++#define ATH11K_ROUTE_EAP_METADATA (ATH11K_RX_PROTOCOL_TAG_START_OFFSET + ATH11K_PKT_TYPE_EAP) ++ + 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 + 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); ++int ath11k_dp_rx_pkt_type_filter(struct ath11k *ar, ++ enum ath11k_routing_pkt_type pkt_type, ++ u32 meta_data); + void ath11k_dp_htt_htc_t2h_msg_handler(struct ath11k_base *ab, + struct sk_buff *skb); + int ath11k_dp_pdev_reo_setup(struct ath11k_base *ab); +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -6367,6 +6367,16 @@ static int ath11k_mac_op_start(struct ie + goto err; + } + ++ /* nss offload requires eapol packets to be routed to wbm release ring */ ++ if (ab->nss.enabled) { ++ ret = ath11k_dp_rx_pkt_type_filter(ar, ATH11K_PKT_TYPE_EAP, ++ ATH11K_ROUTE_EAP_METADATA); ++ if (ret) { ++ ath11k_err(ar->ab, "failed to configure EAP pkt route: %d\n", ret); ++ goto err; ++ } ++ } ++ + __ath11k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask); + + /* 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 { + struct list_head peers; + wait_queue_head_t peer_mapping_wq; + u8 mac_addr[ETH_ALEN]; ++ int userpd_id; + int irq_num[ATH11K_IRQ_NUM_MAX]; + struct ath11k_ext_irq_grp ext_irq_grp[ATH11K_EXT_IRQ_GRP_NUM_MAX]; + struct ath11k_targ_cap target_caps; diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch b/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch new file mode 100644 index 00000000000000..cfe11083939837 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch @@ -0,0 +1,1283 @@ +From 65c511e3aeb9afb84a3c6c8ac34353af91b880e9 Mon Sep 17 00:00:00 2001 +From: Sriram R +Date: Fri, 10 Jul 2020 12:50:21 +0530 +Subject: [PATCH 3/3] ath11k: add nss support + + Add NSS Offload support for ath11k driver. + +Signed-off-by: Sriram R +--- + drivers/net/wireless/ath/ath11k/ahb.c | 18 ++++++-- + drivers/net/wireless/ath/ath11k/core.c | 24 ++++++++++ + drivers/net/wireless/ath/ath11k/core.h | 14 +++++- + drivers/net/wireless/ath/ath11k/dp.c | 21 ++++++--- + drivers/net/wireless/ath/ath11k/dp.h | 1 + + drivers/net/wireless/ath/ath11k/dp_rx.c | 17 +++++-- + drivers/net/wireless/ath/ath11k/dp_rx.h | 6 +++ + drivers/net/wireless/ath/ath11k/hal.h | 2 + + drivers/net/wireless/ath/ath11k/hal_rx.c | 10 +++- + drivers/net/wireless/ath/ath11k/mac.c | 78 +++++++++++++++++++++++++++++++- + drivers/net/wireless/ath/ath11k/peer.c | 9 +++- + drivers/net/wireless/ath/ath11k/peer.h | 6 ++- + local-symbols | 1 + + 13 files changed, 186 insertions(+), 21 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/ahb.c ++++ b/drivers/net/wireless/ath/ath11k/ahb.c +@@ -525,6 +525,12 @@ static int ath11k_ahb_config_ext_irq(str + int i, j; + int irq; + int ret; ++ bool nss_offload; ++ ++ /* TCL Completion, REO Dest, ERR, Exception and h2rxdma rings are offloaded ++ * to nss when its enabled, hence don't enable these interrupts ++ */ ++ nss_offload = ab->nss.enabled; + + for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { + struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; +@@ -537,20 +543,20 @@ static int ath11k_ahb_config_ext_irq(str + ath11k_ahb_ext_grp_napi_poll); + + for (j = 0; j < ATH11K_EXT_IRQ_NUM_MAX; j++) { +- if (ab->hw_params.ring_mask->tx[i] & BIT(j)) { ++ if (!nss_offload && ab->hw_params.ring_mask->tx[i] & BIT(j)) { + irq_grp->irqs[num_irq++] = + wbm2host_tx_completions_ring1 - j; + } + +- if (ab->hw_params.ring_mask->rx[i] & BIT(j)) { ++ if (!nss_offload && ab->hw_params.ring_mask->rx[i] & BIT(j)) { + irq_grp->irqs[num_irq++] = + reo2host_destination_ring1 - j; + } + +- if (ab->hw_params.ring_mask->rx_err[i] & BIT(j)) ++ if (!nss_offload && ab->hw_params.ring_mask->rx_err[i] & BIT(j)) + irq_grp->irqs[num_irq++] = reo2host_exception; + +- if (ab->hw_params.ring_mask->rx_wbm_rel[i] & BIT(j)) ++ if (!nss_offload && ab->hw_params.ring_mask->rx_wbm_rel[i] & BIT(j)) + irq_grp->irqs[num_irq++] = wbm2host_rx_release; + + if (ab->hw_params.ring_mask->reo_status[i] & BIT(j)) +@@ -563,7 +569,7 @@ static int ath11k_ahb_config_ext_irq(str + ath11k_hw_get_mac_from_pdev_id(hw, j); + } + +- if (ab->hw_params.ring_mask->host2rxdma[i] & BIT(j)) { ++ if (!nss_offload && ab->hw_params.ring_mask->host2rxdma[i] & BIT(j)) { + irq_grp->irqs[num_irq++] = + host2rxdma_host_buf_ring_mac1 - + ath11k_hw_get_mac_from_pdev_id(hw, j); +@@ -904,6 +910,7 @@ static int ath11k_ahb_setup_resources(st + } + + ab->mem = mem; ++ ab->mem_pa = mem_res->start; + ab->mem_len = resource_size(mem_res); + + return 0; +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -17,6 +17,12 @@ + #include "hif.h" + #include "wow.h" + ++unsigned int nss_offload; ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++module_param_named(nss_offload, nss_offload, uint, 0644); ++MODULE_PARM_DESC(nss_offload, "Enable NSS Offload support"); ++#endif ++ + unsigned int ath11k_debug_mask; + EXPORT_SYMBOL(ath11k_debug_mask); + module_param_named(debug_mask, ath11k_debug_mask, uint, 0644); +@@ -1528,10 +1534,16 @@ static int ath11k_core_pdev_create(struc + goto err_pdev_debug; + } + ++ ret = ath11k_nss_setup(ab); ++ if (ret) { ++ ath11k_err(ab, "failed to setup nss driver interface%d", ret); ++ goto err_dp_pdev_free; ++ } ++ + ret = ath11k_mac_register(ab); + if (ret) { + ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret); +- goto err_dp_pdev_free; ++ goto err_nss_tear; + } + + ret = ath11k_thermal_register(ab); +@@ -1553,6 +1565,8 @@ err_thermal_unregister: + ath11k_thermal_unregister(ab); + err_mac_unregister: + ath11k_mac_unregister(ab); ++err_nss_tear: ++ ath11k_nss_teardown(ab); + err_dp_pdev_free: + ath11k_dp_pdev_free(ab); + err_pdev_debug: +@@ -1566,6 +1580,10 @@ static void ath11k_core_pdev_destroy(str + ath11k_spectral_deinit(ab); + ath11k_thermal_unregister(ab); + ath11k_mac_unregister(ab); ++ ++ ath11k_nss_teardown(ab); ++ ab->nss.enabled = false; ++ + ath11k_hif_irq_disable(ab); + ath11k_dp_pdev_free(ab); + ath11k_debugfs_pdev_destroy(ab); +@@ -1772,6 +1790,10 @@ static int ath11k_core_reconfigure_on_cr + int ret; + + mutex_lock(&ab->core_lock); ++ ++ ath11k_nss_teardown(ab); ++ ab->nss.enabled = false; ++ + ath11k_thermal_unregister(ab); + ath11k_hif_irq_disable(ab); + ath11k_dp_pdev_free(ab); +@@ -2095,6 +2117,10 @@ int ath11k_core_pre_init(struct ath11k_b + ath11k_err(ab, "failed to get hw params: %d\n", ret); + return ret; + } ++ ab->nss.enabled = nss_offload; ++ ++ if (nss_offload) ++ ab->nss.stats_enabled = 1; + + return 0; + } +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -29,6 +29,7 @@ + #include "dbring.h" + #include "spectral.h" + #include "wow.h" ++#include "nss.h" + + #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) + +@@ -381,6 +382,9 @@ struct ath11k_vif { + #endif /* CPTCFG_ATH11K_DEBUGFS */ + + struct ath11k_mgmt_frame_stats mgmt_stats; ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ struct arvif_nss nss; ++#endif + }; + + struct ath11k_vif_iter { +@@ -520,6 +524,9 @@ struct ath11k_sta { + #endif + + bool use_4addr_set; ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ struct ath11k_nss_sta_stats *nss_stats; ++#endif + u16 tcl_metadata; + + /* Protected with ar->data_lock */ +@@ -610,6 +617,9 @@ struct ath11k { + struct ieee80211_hw *hw; + struct ieee80211_ops *ops; + struct ath11k_pdev_wmi *wmi; ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ struct ath11k_nss nss; ++#endif + 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 { + struct ath11k_htc htc; + + struct ath11k_dp dp; ++ struct ath11k_soc_nss nss; + + void __iomem *mem; + void __iomem *mem_ce; ++ dma_addr_t mem_pa; + unsigned long mem_len; + + struct { +--- a/drivers/net/wireless/ath/ath11k/dp.c ++++ b/drivers/net/wireless/ath/ath11k/dp.c +@@ -47,12 +47,17 @@ int ath11k_dp_peer_setup(struct ath11k * + struct ath11k_peer *peer; + u32 reo_dest; + int ret = 0, tid; ++ bool rx_hash_enable = DP_RX_HASH_ENABLE; ++ ++ /* RX Hash based steering is disabled for NSS Offload */ ++ if (ar->ab->nss.enabled) ++ rx_hash_enable = DP_RX_HASH_DISABLE; + + /* NOTE: reo_dest ring id starts from 1 unlike mac_id which starts from 0 */ + reo_dest = ar->dp.mac_id + 1; + ret = ath11k_wmi_set_peer_param(ar, addr, vdev_id, + WMI_PEER_SET_DEFAULT_ROUTING, +- DP_RX_HASH_ENABLE | (reo_dest << 1)); ++ rx_hash_enable | (reo_dest << 1)); + + if (ret) { + ath11k_warn(ab, "failed to set default routing %d peer :%pM vdev_id :%d\n", +@@ -132,6 +137,18 @@ static int ath11k_dp_srng_calculate_msi_ + { + const u8 *grp_mask; + ++ if (ab->nss.enabled) { ++ switch (type) { ++ case HAL_REO_STATUS: ++ case HAL_RXDMA_MONITOR_STATUS: ++ case HAL_RXDMA_MONITOR_DST: ++ case HAL_RXDMA_MONITOR_BUF: ++ break; ++ default: ++ return -ENOENT; ++ } ++ } ++ + switch (type) { + case HAL_WBM2SW_RELEASE: + if (ring_num == DP_RX_RELEASE_RING_NUM) { +@@ -778,14 +795,16 @@ int ath11k_dp_service_srng(struct ath11k + int work_done = 0; + int i, j; + int tot_work_done = 0; ++ bool nss_offload; + +- for (i = 0; i < ab->hw_params.max_tx_ring; i++) { +- if (BIT(ab->hw_params.hal_params->tcl2wbm_rbm_map[i].wbm_ring_num) & +- ab->hw_params.ring_mask->tx[grp_id]) +- ath11k_dp_tx_completion_handler(ab, i); ++ nss_offload = ab->nss.enabled; ++ ++ if (!nss_offload && ab->hw_params.ring_mask->tx[grp_id]) { ++ i = __fls(ab->hw_params.ring_mask->tx[grp_id]); ++ ath11k_dp_tx_completion_handler(ab, i); + } + +- if (ab->hw_params.ring_mask->rx_err[grp_id]) { ++ if (!nss_offload && ab->hw_params.ring_mask->rx_err[grp_id]) { + work_done = ath11k_dp_process_rx_err(ab, napi, budget); + budget -= work_done; + tot_work_done += work_done; +@@ -793,7 +812,7 @@ int ath11k_dp_service_srng(struct ath11k + goto done; + } + +- if (ab->hw_params.ring_mask->rx_wbm_rel[grp_id]) { ++ if (!nss_offload && ab->hw_params.ring_mask->rx_wbm_rel[grp_id]) { + work_done = ath11k_dp_rx_process_wbm_err(ab, + napi, + budget); +@@ -804,7 +823,7 @@ int ath11k_dp_service_srng(struct ath11k + goto done; + } + +- if (ab->hw_params.ring_mask->rx[grp_id]) { ++ if (!nss_offload && ab->hw_params.ring_mask->rx[grp_id]) { + i = fls(ab->hw_params.ring_mask->rx[grp_id]) - 1; + work_done = ath11k_dp_process_rx(ab, i, napi, + budget); +@@ -838,7 +857,7 @@ int ath11k_dp_service_srng(struct ath11k + if (ab->hw_params.ring_mask->reo_status[grp_id]) + ath11k_dp_process_reo_status(ab); + +- for (i = 0; i < ab->num_radios; i++) { ++ for (i = 0; !nss_offload && i < ab->num_radios; i++) { + for (j = 0; j < ab->hw_params.num_rxmda_per_pdev; j++) { + int id = i * ab->hw_params.num_rxmda_per_pdev + j; + +--- a/drivers/net/wireless/ath/ath11k/dp.h ++++ b/drivers/net/wireless/ath/ath11k/dp.h +@@ -194,6 +194,7 @@ struct ath11k_pdev_dp { + #define DP_AVG_MSDUS_PER_MPDU 4 + + #define DP_RX_HASH_ENABLE 1 /* Enable hash based Rx steering */ ++#define DP_RX_HASH_DISABLE 0 /* Disable hash based Rx steering */ + + #define DP_BA_WIN_SZ_MAX 256 + +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -17,6 +17,7 @@ + #include "hal_rx.h" + #include "dp_tx.h" + #include "peer.h" ++#include "nss.h" + + #define ATH11K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ) + +@@ -213,8 +214,8 @@ static inline u8 ath11k_dp_rx_h_mpdu_sta + return ab->hw_params.hw_ops->rx_desc_get_mpdu_tid(desc); + } + +-static inline u16 ath11k_dp_rx_h_mpdu_start_peer_id(struct ath11k_base *ab, +- struct hal_rx_desc *desc) ++u16 ath11k_dp_rx_h_mpdu_start_peer_id(struct ath11k_base *ab, ++ struct hal_rx_desc *desc) + { + return ab->hw_params.hw_ops->rx_desc_get_mpdu_peer_id(desc); + } +@@ -225,8 +226,8 @@ static inline u8 ath11k_dp_rx_h_msdu_end + return ab->hw_params.hw_ops->rx_desc_get_l3_pad_bytes(desc); + } + +-static inline bool ath11k_dp_rx_h_msdu_end_first_msdu(struct ath11k_base *ab, +- struct hal_rx_desc *desc) ++bool ath11k_dp_rx_h_msdu_end_first_msdu(struct ath11k_base *ab, ++ struct hal_rx_desc *desc) + { + return ab->hw_params.hw_ops->rx_desc_get_first_msdu(desc); + } +@@ -283,7 +284,7 @@ static inline void ath11k_dp_rxdesc_set_ + ab->hw_params.hw_ops->rx_desc_set_msdu_len(desc, len); + } + +-static bool ath11k_dp_rx_h_attn_is_mcbc(struct ath11k_base *ab, ++bool ath11k_dp_rx_h_attn_is_mcbc(struct ath11k_base *ab, + struct hal_rx_desc *desc) + { + struct rx_attention *attn = ath11k_dp_rx_get_attention(ab, desc); +@@ -498,7 +499,9 @@ static int ath11k_dp_rxdma_pdev_buf_setu + struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; + int i; + +- ath11k_dp_rxdma_ring_buf_setup(ar, rx_ring, HAL_RXDMA_BUF); ++ /* RXDMA BUF ring is offloaded to NSS */ ++ if (!ar->ab->nss.enabled) ++ ath11k_dp_rxdma_ring_buf_setup(ar, rx_ring, HAL_RXDMA_BUF); + + 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( + CHECKSUM_NONE : CHECKSUM_UNNECESSARY; + } + +-static int ath11k_dp_rx_crypto_mic_len(struct ath11k *ar, ++int ath11k_dp_rx_crypto_mic_len(struct ath11k *ar, + enum hal_encrypt_type enctype) + { + switch (enctype) { +@@ -1920,7 +1923,7 @@ static int ath11k_dp_rx_crypto_mic_len(s + return 0; + } + +-static int ath11k_dp_rx_crypto_param_len(struct ath11k *ar, ++int ath11k_dp_rx_crypto_param_len(struct ath11k *ar, + enum hal_encrypt_type enctype) + { + switch (enctype) { +@@ -1948,7 +1951,7 @@ static int ath11k_dp_rx_crypto_param_len + return 0; + } + +-static int ath11k_dp_rx_crypto_icv_len(struct ath11k *ar, ++int ath11k_dp_rx_crypto_icv_len(struct ath11k *ar, + enum hal_encrypt_type enctype) + { + switch (enctype) { +@@ -5239,7 +5242,7 @@ int ath11k_dp_rx_process_mon_status(stru + struct sk_buff *skb; + struct sk_buff_head skb_list; + struct ath11k_peer *peer; +- struct ath11k_sta *arsta; ++ struct ath11k_sta *arsta = NULL; + int num_buffs_reaped = 0; + u32 rx_buf_sz; + u16 log_type; +--- 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 + int ath11k_dp_rx_pktlog_start(struct ath11k_base *ab); + int ath11k_dp_rx_pktlog_stop(struct ath11k_base *ab, bool stop_timer); + ++int ath11k_dp_rx_crypto_mic_len(struct ath11k *ar, ++ enum hal_encrypt_type enctype); ++int ath11k_dp_rx_crypto_param_len(struct ath11k *ar, ++ enum hal_encrypt_type enctype); ++int ath11k_dp_rx_crypto_icv_len(struct ath11k *ar, ++ enum hal_encrypt_type enctype); ++bool ath11k_dp_rx_h_msdu_end_first_msdu(struct ath11k_base *ab, ++ struct hal_rx_desc *desc); ++bool ath11k_dp_rx_h_attn_is_mcbc(struct ath11k_base *ab, ++ struct hal_rx_desc *desc); ++u16 ath11k_dp_rx_h_mpdu_start_peer_id(struct ath11k_base *ab, ++ struct hal_rx_desc *desc); + #endif /* ATH11K_DP_RX_H */ +--- a/drivers/net/wireless/ath/ath11k/hal.h ++++ b/drivers/net/wireless/ath/ath11k/hal.h +@@ -424,6 +424,8 @@ enum hal_srng_ring_id { + #define HAL_SRNG_RING_ID_MAX (HAL_SRNG_RING_ID_UMAC_ID_END + \ + HAL_SRNG_NUM_LMAC_RINGS) + ++#define HAL_SRNG_REO_ALTERNATE_SELECT 0x7 ++ + enum hal_ring_type { + HAL_REO_DST, + HAL_REO_EXCEPTION, +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -24,6 +24,7 @@ + #include "debugfs_sta.h" + #include "hif.h" + #include "wow.h" ++#include "nss.h" + + #define CHAN2G(_channel, _freq, _flags) { \ + .band = NL80211_BAND_2GHZ, \ +@@ -1603,6 +1604,11 @@ static void ath11k_control_beaconing(str + lockdep_assert_held(&arvif->ar->conf_mutex); + + if (!info->enable_beacon) { ++ ++ ret = ath11k_nss_vdev_down(arvif); ++ if(ret) ++ ath11k_warn(ar->ab, "failure in nss vdev down %d\r\n",ret); ++ + ret = ath11k_wmi_vdev_down(ar, arvif->vdev_id); + if (ret) + ath11k_warn(ar->ab, "failed to down vdev_id %i: %d\n", +@@ -1642,6 +1648,12 @@ static void ath11k_control_beaconing(str + + arvif->is_up = true; + ++ ret = ath11k_nss_vdev_up(arvif); ++ if(ret) { ++ ath11k_warn(ar->ab, "failure in nss vdev up %d\r\n",ret); ++ return; ++ } ++ + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "vdev %d up\n", arvif->vdev_id); + } + +@@ -3075,6 +3087,12 @@ static void ath11k_bss_assoc(struct ieee + "vdev %d up (associated) bssid %pM aid %d\n", + arvif->vdev_id, bss_conf->bssid, vif->cfg.aid); + ++ ret = ath11k_nss_vdev_up(arvif); ++ if(ret) { ++ ath11k_warn(ar->ab, "failure in nss vdev up %d\r\n",ret); ++ return; ++ } ++ + spin_lock_bh(&ar->ab->base_lock); + + peer = ath11k_peer_find(ar->ab, arvif->vdev_id, arvif->bssid); +@@ -3117,6 +3135,10 @@ static void ath11k_bss_disassoc(struct i + + lockdep_assert_held(&ar->conf_mutex); + ++ ret = ath11k_nss_vdev_down(arvif); ++ if(ret) ++ ath11k_warn(ar->ab, "failure in nss vdev down %d\r\n",ret); ++ + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "vdev %i disassoc bssid %pM\n", + arvif->vdev_id, arvif->bssid); + +@@ -3397,6 +3419,28 @@ static int ath11k_mac_config_obss_pd(str + return 0; + } + ++static void ath11k_mac_op_nss_bss_info_changed(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ u32 changed) ++{ ++ struct ath11k *ar = hw->priv; ++ struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); ++ int ret = 0; ++ ++ mutex_lock(&ar->conf_mutex); ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "Setting ap_isolate %d to NSS\n", ++ arvif->vif->bss_conf.nss_ap_isolate); ++ if (changed & BSS_CHANGED_NSS_AP_ISOLATE) { ++ ret = ath11k_nss_vdev_set_cmd(arvif, ATH11K_NSS_WIFI_VDEV_CFG_AP_BRIDGE_CMD, ++ !arvif->vif->bss_conf.nss_ap_isolate); ++ if(ret) ++ ath11k_warn(ar->ab, "failed to set ap_isolate in nss %d\n", ret); ++ } ++ ++ mutex_unlock(&ar->conf_mutex); ++} ++ + static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info, +@@ -4295,6 +4339,26 @@ static int ath11k_mac_op_set_key(struct + + spin_lock_bh(&ab->base_lock); + peer = ath11k_peer_find(ab, arvif->vdev_id, peer_addr); ++ ++ /* TODO: Check if vdev specific security cfg is mandatory */ ++ ret = ath11k_nss_vdev_set_cmd(arvif, ATH11K_NSS_WIFI_VDEV_SECURITY_TYPE_CMD, key->cipher); ++ if (ret) { ++ ath11k_warn(ab, "failure to set vdev security type in nss"); ++ goto unlock; ++ } ++ ++ ret = ath11k_nss_set_peer_sec_type(ar, peer, key); ++ if (ret) { ++ ath11k_warn(ab, "failure to set peer security type in nss"); ++ goto unlock; ++ } ++ ++ ret = ath11k_nss_set_peer_authorize(ar, peer->peer_id); ++ if (ret) { ++ ath11k_warn(ab, "failure to authorize peer in nss"); ++ goto unlock; ++ } ++ + if (peer && cmd == SET_KEY) { + peer->keys[key->keyidx] = key; + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { +@@ -4333,9 +4397,8 @@ static int ath11k_mac_op_set_key(struct + break; + } + } +- ++unlock: + spin_unlock_bh(&ab->base_lock); +- + exit: + mutex_unlock(&ar->conf_mutex); + return ret; +@@ -6216,10 +6279,16 @@ static void ath11k_mac_op_tx(struct ieee + if (control->sta) + arsta = ath11k_sta_to_arsta(control->sta); + +- ret = ath11k_dp_tx(ar, arvif, arsta, skb); ++ if (ar->ab->nss.enabled) { ++ arvif->ar->ab->nss.debug_mode = true; ++ ret = ath11k_nss_tx(arvif, skb); ++ } ++ else ++ ret = ath11k_dp_tx(ar, arvif, arsta, skb); + if (unlikely(ret)) { + ath11k_warn(ar->ab, "failed to transmit frame %d\n", ret); + ieee80211_free_txskb(ar->hw, skb); ++ return; + } + } + +@@ -6241,6 +6310,8 @@ static int ath11k_mac_config_mon_status_ + + if (enable) { + tlv_filter = ath11k_mac_mon_status_filter_default; ++ ath11k_nss_ext_rx_stats(ar->ab, &tlv_filter); ++ + 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_ + return 0; + } + +-static void ath11k_mac_op_update_vif_offload(struct ieee80211_hw *hw, ++static int ath11k_mac_op_update_vif_offload(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) + { + struct ath11k *ar = hw->priv; +@@ -6585,6 +6656,8 @@ static void ath11k_mac_op_update_vif_off + arvif->vdev_id, ret); + vif->offload_flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED; + } ++ ++ return ret; + } + + static bool ath11k_mac_vif_ap_active_any(struct ath11k_base *ab) +@@ -6715,6 +6788,8 @@ static int ath11k_mac_vdev_delete(struct + + reinit_completion(&ar->vdev_delete_done); + ++ ath11k_nss_vdev_delete(arvif); ++ + 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 + list_add(&arvif->list, &ar->arvifs); + spin_unlock_bh(&ar->data_lock); + +- ath11k_mac_op_update_vif_offload(hw, vif); ++ ret = ath11k_nss_vdev_create(arvif); ++ if(ret) { ++ ath11k_warn(ab, "failed to create nss vdev %d\n", ret); ++ goto err_vdev_del; ++ } ++ ++ if (ath11k_mac_op_update_vif_offload(hw, vif)) ++ goto err_vdev_del; ++ ++ if (vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) ++ param_value = ATH11K_HW_TXRX_ETHERNET; ++ else if (test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) ++ param_value = ATH11K_HW_TXRX_RAW; ++ else ++ param_value = ATH11K_HW_TXRX_NATIVE_WIFI; ++ ++ ret = ath11k_nss_vdev_set_cmd(arvif, ATH11K_NSS_WIFI_VDEV_ENCAP_TYPE_CMD, param_value); ++ ++ if(ret) { ++ ath11k_warn(ab, "failed to set encap type in nss %d\n", ret); ++ goto err_vdev_del; ++ } ++ ++ ret = ath11k_nss_vdev_set_cmd(arvif, ATH11K_NSS_WIFI_VDEV_DECAP_TYPE_CMD, param_value); ++ if(ret) { ++ ath11k_warn(ab, "failed to set decap type in nss %d\n", ret); ++ goto err_vdev_del; ++ } + + 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: + } + + err_vdev_del: ++ ath11k_nss_vdev_delete(arvif); + 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 + arvif->vdev_id, ret); + continue; + } ++ ++ ret = ath11k_nss_vdev_up(arvif); ++ if(ret) ++ ath11k_warn(ar->ab, "failure in nss vdev up %d\r\n",ret); + } + + /* Restart the internal monitor vdev on new channel */ +@@ -8717,6 +8824,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); ++ ++ ath11k_nss_update_sta_stats(sinfo, sta, arsta); + } + + #if IS_ENABLED(CONFIG_IPV6) +@@ -9136,6 +9245,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, ++ .nss_bss_info_changed = ath11k_mac_op_nss_bss_info_changed, + .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 + 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); +- ieee80211_hw_set(ar->hw, USES_RSS); ++ if(!ab->nss.enabled) ++ ieee80211_hw_set(ar->hw, USES_RSS); + } + + ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; +@@ -9636,6 +9747,9 @@ static int __ath11k_mac_register(struct + ab->hw_params.bios_sar_capa) + ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa; + ++ if (ab->nss.enabled) ++ ieee80211_hw_set(ar->hw, SUPPORTS_NSS_OFFLOAD); ++ + ret = ieee80211_register_hw(ar->hw); + if (ret) { + ath11k_err(ar->ab, "ieee80211 registration failed: %d\n", ret); +--- a/drivers/net/wireless/ath/ath11k/peer.c ++++ b/drivers/net/wireless/ath/ath11k/peer.c +@@ -7,6 +7,7 @@ + #include "core.h" + #include "peer.h" + #include "debug.h" ++#include "nss.h" + + 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 + ether_addr_copy(peer->addr, mac_addr); + list_add(&peer->list, &ab->peers); + wake_up(&ab->peer_mapping_wq); ++ if (ab->nss.enabled) ++ ath11k_nss_peer_create(ab, peer); + } + + 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 + + lockdep_assert_held(&ar->conf_mutex); + ++ reinit_completion(&ar->peer_delete_done); ++ ath11k_nss_peer_delete(ar->ab, addr); ++ + mutex_lock(&ab->tbl_mtx_lock); + spin_lock_bh(&ab->base_lock); + + peer = ath11k_peer_find_by_addr(ab, addr); +- /* Check if the found peer is what we want to remove. +- * While the sta is transitioning to another band we may +- * have 2 peer with the same addr assigned to different +- * vdev_id. Make sure we are deleting the correct peer. +- */ +- if (peer && peer->vdev_id == vdev_id) +- ath11k_peer_rhash_delete(ab, peer); + + /* 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 + return -EINVAL; + } + ++ /* Check if the found peer is what we want to remove. ++ * While the sta is transitioning to another band we may ++ * have 2 peer with the same addr assigned to different ++ * vdev_id. Make sure we are deleting the correct peer. ++ */ ++ if (peer && peer->vdev_id == vdev_id) ++ ath11k_peer_rhash_delete(ab, peer); ++ + spin_unlock_bh(&ab->base_lock); + mutex_unlock(&ab->tbl_mtx_lock); + +- reinit_completion(&ar->peer_delete_done); + + 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 { + u16 ast_hash; + u8 pdev_idx; + u16 hw_peer_id; ++ struct ath11k_nss_peer nss; + + /* protected by ab->data_lock */ + struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; +--- a/drivers/net/wireless/ath/ath11k/pci.c ++++ b/drivers/net/wireless/ath/ath11k/pci.c +@@ -570,6 +570,7 @@ static int ath11k_pci_claim(struct ath11 + } + + ab->mem_ce = ab->mem; ++ ab->mem_pa = pci_resource_start(pdev, ATH11K_PCI_BAR_NUM); + + ath11k_dbg(ab, ATH11K_DBG_BOOT, "pci_mem 0x%p\n", ab->mem); + return 0; +--- a/drivers/net/wireless/ath/ath11k/debugfs.c ++++ b/drivers/net/wireless/ath/ath11k/debugfs.c +@@ -10,11 +10,10 @@ + #include "core.h" + #include "debug.h" + #include "wmi.h" +-#include "hal_rx.h" + #include "dp_tx.h" + #include "debugfs_htt_stats.h" +-#include "peer.h" + #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 + HTT_RX_FP_DATA_FILTER_FLASG3; + } else { + tlv_filter = ath11k_mac_mon_status_filter_default; ++ ath11k_nss_ext_rx_stats(ar->ab, &tlv_filter); + } + + 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 + .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; ++ int ret; ++ ++ if (!ab->nss.enabled) { ++ ath11k_warn(ab, "nss offload not enabled\n"); ++ return -EINVAL; ++ } ++ ++ if (kstrtouint_from_user(ubuf, count, 0, &nss_stats)) ++ return -EINVAL; ++ ++ mutex_lock(&ar->conf_mutex); ++ ++ if (ar->state != ATH11K_STATE_ON) { ++ ret = -ENETDOWN; ++ goto out; ++ } ++ ++ if (nss_stats == ab->nss.stats_enabled) { ++ ret = count; ++ goto out; ++ } ++ ++ if (nss_stats > 0) { ++ ab->nss.stats_enabled = 1; ++ ath11k_nss_peer_stats_enable(ar); ++ } else { ++ ab->nss.stats_enabled = 0; ++ ath11k_nss_peer_stats_disable(ar); ++ } ++ ++ ret = count; ++out: ++ mutex_unlock(&ar->conf_mutex); ++ return ret; ++} ++ ++static ssize_t ath11k_read_nss_stats(struct file *file, ++ char __user *ubuf, ++ size_t count, loff_t *ppos) ++ ++{ ++ char buf[32] = {0}; ++ struct ath11k *ar = file->private_data; ++ struct ath11k_base *ab = ar->ab; ++ int len = 0; ++ ++ mutex_lock(&ar->conf_mutex); ++ len = scnprintf(buf, sizeof(buf) - len, "%08x\n", ++ ab->nss.stats_enabled); ++ mutex_unlock(&ar->conf_mutex); ++ ++ return simple_read_from_buffer(ubuf, count, ppos, buf, len); ++} ++ ++static const struct file_operations fops_nss_stats = { ++ .read = ath11k_read_nss_stats, ++ .write = ath11k_write_nss_stats, ++ .open = simple_open, ++ .owner = THIS_MODULE, ++ .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); ++ } ++ ++ if (ab->nss.enabled) ++ debugfs_create_file("nss_peer_stats_config", 0644, ++ 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; +--- a/drivers/net/wireless/ath/ath11k/dp_tx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_tx.c +@@ -12,7 +12,7 @@ + #include "peer.h" + #include "mac.h" + +-static enum hal_tcl_encap_type ++enum hal_tcl_encap_type + ath11k_dp_tx_get_encap_type(struct ath11k_vif *arvif, struct sk_buff *skb) + { + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); +--- a/drivers/net/wireless/ath/ath11k/dp_tx.h ++++ b/drivers/net/wireless/ath/ath11k/dp_tx.h +@@ -38,6 +38,8 @@ int ath11k_dp_tx_htt_rx_filter_setup(str + int mac_id, enum hal_ring_type ring_type, + int rx_buf_size, + struct htt_rx_ring_tlv_filter *tlv_filter); ++enum hal_tcl_encap_type ++ath11k_dp_tx_get_encap_type(struct ath11k_vif *arvif, struct sk_buff *skb); + + int ath11k_dp_tx_htt_rx_full_mon_setup(struct ath11k_base *ab, int mac_id, + bool config); +--- a/drivers/net/wireless/ath/ath11k/nss.c ++++ b/drivers/net/wireless/ath/ath11k/nss.c +@@ -8,6 +8,8 @@ + #include "nss.h" + #include "core.h" + #include "peer.h" ++#include "dp_rx.h" ++#include "dp_tx.h" + #include "hif.h" + #include "wmi.h" + #include "../../../../../net/mac80211/sta_info.h" +@@ -465,7 +467,7 @@ deliver_amsdu: + + /* create list containing all the subframes */ + ieee80211_amsdu_to_8023s(skb, &subframe_list, NULL, +- vif->type, 0, NULL, NULL); ++ vif->type, 0, NULL, NULL, false); + + /* This shouldn't happen, indicating error during defragmentation */ + if (skb_queue_empty(&subframe_list)) +@@ -657,12 +659,14 @@ drop: + return -EINVAL; + } + +-int ath11k_nss_vdev_set_cmd(struct ath11k_vif *arvif, int cmd, int val) ++int ath11k_nss_vdev_set_cmd(struct ath11k_vif *arvif, enum ath11k_nss_vdev_cmd nss_cmd, ++ int val) + { + struct nss_wifi_vdev_msg *vdev_msg = NULL; + struct nss_wifi_vdev_cmd_msg *vdev_cmd; + struct ath11k *ar = arvif->ar; + nss_tx_status_t status; ++ int cmd; + + if (!ar->ab->nss.enabled) + return 0; +@@ -675,6 +679,22 @@ int ath11k_nss_vdev_set_cmd(struct ath11 + if (!vdev_msg) + return -ENOMEM; + ++ switch(nss_cmd) { ++ case ATH11K_NSS_WIFI_VDEV_CFG_AP_BRIDGE_CMD: ++ cmd = NSS_WIFI_VDEV_CFG_AP_BRIDGE_CMD; ++ break; ++ case ATH11K_NSS_WIFI_VDEV_SECURITY_TYPE_CMD: ++ cmd = NSS_WIFI_VDEV_SECURITY_TYPE_CMD; ++ break; ++ case ATH11K_NSS_WIFI_VDEV_ENCAP_TYPE_CMD: ++ cmd = NSS_WIFI_VDEV_ENCAP_TYPE_CMD; ++ break; ++ case ATH11K_NSS_WIFI_VDEV_DECAP_TYPE_CMD: ++ cmd = NSS_WIFI_VDEV_DECAP_TYPE_CMD; ++ break; ++ default: ++ return -EINVAL; ++ } + /* TODO: Convert to function for conversion in case of many + * such commands + */ +@@ -1136,7 +1156,6 @@ void ath11k_nss_update_sta_stats(struct + { + struct sta_info *stainfo; + struct ath11k_peer *peer; +- int tid_idx; + struct ath11k *ar = arsta->arvif->ar; + struct ath11k_base *ab = ar->ab; + +@@ -1230,6 +1249,9 @@ void ath11k_nss_update_sta_rxrate(struct + if (!ab->nss.enabled) + return; + ++ if (!ieee80211_is_data(__cpu_to_le16(ppdu_info->frame_control))) ++ return; ++ + if (!peer->nss.nss_stats) + return; + +@@ -1289,7 +1311,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; +- peer->nss.nss_stats->rxrate.he_gi = ath11k_he_gi_to_nl80211_he_gi(ppdu_info->gi); ++ peer->nss.nss_stats->rxrate.he_gi = ath11k_mac_he_gi_to_nl80211_he_gi(ppdu_info->gi); + peer->nss.nss_stats->rxrate.he_ru_alloc = ppdu_info->ru_alloc; + break; + } +--- a/drivers/net/wireless/ath/ath11k/nss.h ++++ b/drivers/net/wireless/ath/ath11k/nss.h +@@ -101,6 +101,13 @@ do { \ + u64_stats_update_end(&tstats->syncp); \ + } while (0) + ++enum ath11k_nss_vdev_cmd { ++ ATH11K_NSS_WIFI_VDEV_CFG_AP_BRIDGE_CMD, ++ ATH11K_NSS_WIFI_VDEV_SECURITY_TYPE_CMD, ++ ATH11K_NSS_WIFI_VDEV_ENCAP_TYPE_CMD, ++ ATH11K_NSS_WIFI_VDEV_DECAP_TYPE_CMD, ++}; ++ + enum ath11k_nss_opmode { + ATH11K_NSS_OPMODE_UNKNOWN, + ATH11K_NSS_OPMODE_AP, +@@ -192,7 +199,8 @@ struct ath11k_soc_nss { + + #ifdef CPTCFG_ATH11K_NSS_SUPPORT + int ath11k_nss_tx(struct ath11k_vif *arvif, struct sk_buff *skb); +-int ath11k_nss_vdev_set_cmd(struct ath11k_vif *arvif, int cmd, int val); ++int ath11k_nss_vdev_set_cmd(struct ath11k_vif *arvif, enum ath11k_nss_vdev_cmd cmd, ++ int val); + int ath11k_nss_vdev_create(struct ath11k_vif *arvif); + void ath11k_nss_vdev_delete(struct ath11k_vif *arvif); + int ath11k_nss_vdev_up(struct ath11k_vif *arvif); +@@ -219,7 +227,8 @@ static inline int ath11k_nss_tx(struct a + return 0; + } + +-static inline int ath11k_nss_vdev_set_cmd(struct ath11k_vif *arvif, int cmd, int val) ++static inline int ath11k_nss_vdev_set_cmd(struct ath11k_vif *arvif, enum ath11k_nss_vdev_cmd cmd, ++ int val) + { + return 0; + } +--- a/drivers/net/wireless/ath/ath11k/hw.c ++++ b/drivers/net/wireless/ath/ath11k/hw.c +@@ -104,8 +104,10 @@ static void ath11k_init_wmi_config_qca63 + + static void ath11k_hw_ipq8074_reo_setup(struct ath11k_base *ab) + { ++ u8 frag_dest_ring = HAL_SRNG_RING_ID_REO2SW1; + u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; + u32 val; ++ + /* Each hash entry uses three bits to map to a particular ring. */ + u32 ring_hash_map = HAL_HASH_ROUTING_RING_SW1 << 0 | + HAL_HASH_ROUTING_RING_SW2 << 3 | +@@ -116,11 +118,14 @@ static void ath11k_hw_ipq8074_reo_setup( + HAL_HASH_ROUTING_RING_SW3 << 18 | + HAL_HASH_ROUTING_RING_SW4 << 21; + ++ if (ab->nss.enabled) ++ frag_dest_ring = HAL_SRNG_REO_ALTERNATE_SELECT; ++ + val = ath11k_hif_read32(ab, reo_base + HAL_REO1_GEN_ENABLE); + + val &= ~HAL_REO1_GEN_ENABLE_FRAG_DST_RING; + val |= FIELD_PREP(HAL_REO1_GEN_ENABLE_FRAG_DST_RING, +- HAL_SRNG_RING_ID_REO2SW1) | ++ frag_dest_ring) | + FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_LIST_ENABLE, 1) | + FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_FLUSH_ENABLE, 1); + ath11k_hif_write32(ab, reo_base + HAL_REO1_GEN_ENABLE, val); +@@ -134,6 +139,10 @@ static void ath11k_hw_ipq8074_reo_setup( + ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_3(ab), + HAL_DEFAULT_REO_TIMEOUT_USEC); + ++ /* REO Dest ring setup is not required in NSS offload case */ ++ 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)); +@@ -758,8 +767,10 @@ static u8 *ath11k_hw_wcn6855_rx_desc_mpd + + static void ath11k_hw_wcn6855_reo_setup(struct ath11k_base *ab) + { ++ u8 frag_dest_ring = HAL_SRNG_RING_ID_REO2SW1; + u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; + u32 val; ++ + /* Each hash entry uses four bits to map to a particular ring. */ + u32 ring_hash_map = HAL_HASH_ROUTING_RING_SW1 << 0 | + HAL_HASH_ROUTING_RING_SW2 << 4 | +@@ -770,6 +781,9 @@ static void ath11k_hw_wcn6855_reo_setup( + HAL_HASH_ROUTING_RING_SW3 << 24 | + HAL_HASH_ROUTING_RING_SW4 << 28; + ++ if (ab->nss.enabled) ++ frag_dest_ring = HAL_SRNG_REO_ALTERNATE_SELECT; ++ + val = ath11k_hif_read32(ab, reo_base + HAL_REO1_GEN_ENABLE); + val |= FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_LIST_ENABLE, 1) | + FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_FLUSH_ENABLE, 1); +@@ -777,7 +791,7 @@ static void ath11k_hw_wcn6855_reo_setup( + + val = ath11k_hif_read32(ab, reo_base + HAL_REO1_MISC_CTL(ab)); + val &= ~HAL_REO1_MISC_CTL_FRAGMENT_DST_RING; +- val |= FIELD_PREP(HAL_REO1_MISC_CTL_FRAGMENT_DST_RING, HAL_SRNG_RING_ID_REO2SW1); ++ val |= FIELD_PREP(HAL_REO1_MISC_CTL_FRAGMENT_DST_RING, frag_dest_ring); + ath11k_hif_write32(ab, reo_base + HAL_REO1_MISC_CTL(ab), val); + + ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_0(ab), +@@ -789,6 +803,10 @@ static void ath11k_hw_wcn6855_reo_setup( + ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_3(ab), + HAL_DEFAULT_REO_TIMEOUT_USEC); + ++ /* REO Dest ring setup is not required in NSS offload case */ ++ 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, +--- a/drivers/net/wireless/ath/ath11k/pcic.c ++++ b/drivers/net/wireless/ath/ath11k/pcic.c +@@ -571,6 +571,12 @@ static int ath11k_pcic_ext_irq_config(st + netif_napi_add(&irq_grp->napi_ndev, &irq_grp->napi, + ath11k_pcic_ext_grp_napi_poll); + ++ /* tcl, reo, rx_err, wbm release, rxdma rings are offloaded to nss. */ ++ if (ab->nss.enabled && ++ !(ab->hw_params.ring_mask->reo_status[i] || ++ ab->hw_params.ring_mask->rx_mon_status[i])) ++ continue; ++ + if (ab->hw_params.ring_mask->tx[i] || + ab->hw_params.ring_mask->rx[i] || + ab->hw_params.ring_mask->rx_err[i] || +--- a/local-symbols ++++ b/local-symbols +@@ -170,6 +170,7 @@ WCN36XX_DEBUGFS= + ATH11K= + ATH11K_AHB= + ATH11K_PCI= ++ATH11K_NSS_SUPPORT= + ATH11K_DEBUG= + ATH11K_DEBUGFS= + ATH11K_TRACING= 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/ath11k_nss/199-mac80211-fix-xmit-callback-when-hwencap-enable-in-st.patch new file mode 100644 index 00000000000000..87c2a52b676f21 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/199-mac80211-fix-xmit-callback-when-hwencap-enable-in-st.patch @@ -0,0 +1,35 @@ +From c3389f87ea09dea804cda2483922e03ad3eb6c79 Mon Sep 17 00:00:00 2001 +From: P Praneesh +Date: Thu, 18 Jun 2020 00:07:15 +0530 +Subject: [PATCH] mac80211: fix xmit callback when hwencap enable in sta + +Since transmit control port uses same callback for both +(ieee80211_subif_start_xmit) ethernet mode and native +wifi mode, which cause regression in ethernet mode +when we use DUT as a STA with encryption(psk2+ccmp). + +Added hardware encap check to filter out ethernet mode +packets to follow ieee80211_subif_start_xmit_8023 callback. + +Signed-off-by: P Praneesh +--- + net/mac80211/tx.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -6213,7 +6213,13 @@ start_xmit: + mutex_lock(&local->mtx); + + local_bh_disable(); +- __ieee80211_subif_start_xmit(skb, skb->dev, flags, ctrl_flags, cookie); ++ ++ /* 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); ++ + local_bh_enable(); + + mutex_unlock(&local->mtx); diff --git a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch new file mode 100644 index 00000000000000..af46c8f0bfa05e --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch @@ -0,0 +1,60 @@ +From f013e1e9829ec346fa0a215552eef51953b46bf0 Mon Sep 17 00:00:00 2001 +From: Seevalamuthu Mariappan +Date: Fri, 7 Aug 2020 18:24:32 +0530 +Subject: [PATCH] ath11k: Add support for dynamic vlan + +This patch adds support for dynamic vlan. VLAN group traffics +are encrypted in software. vlan unicast packets shall be taking +8023 xmit path if encap offload is enabled and mcast/bcast will +be using 80211 xmit path. + +Metadata info in dp_tx added to notify firmware that the +multicast/broadcast packets are encrypted in sw. + +Signed-off-by: Seevalamuthu Mariappan +Signed-off-by: Gautham Kumar Senthilkumaran +--- + net/mac80211/tx.c | 14 +++ + 1 files changed, 14 insertions(+) + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -37,6 +37,9 @@ + #include "wme.h" + #include "rate.h" + ++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); + /* misc utils */ + + static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, +@@ -4268,6 +4271,8 @@ void __ieee80211_subif_start_xmit(struct + struct sta_info *sta; + struct sk_buff *next; + int len = skb->len; ++ struct ieee80211_key *key = NULL; ++ struct ieee80211_sub_if_data *ap_sdata; + + if (unlikely(!ieee80211_sdata_running(sdata) || skb->len < ETH_HLEN)) { + kfree_skb(skb); +@@ -4289,6 +4294,19 @@ void __ieee80211_subif_start_xmit(struct + if (IS_ERR(sta)) + sta = NULL; + ++ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { ++ ap_sdata = container_of(sdata->bss, ++ struct ieee80211_sub_if_data, u.ap); ++ if (ap_sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED && ++ !is_multicast_ether_addr(skb->data)) { ++ if (sta) ++ key = rcu_dereference(sta->ptk[sta->ptk_idx]); ++ ieee80211_8023_xmit(sdata, dev, sta, key, skb); ++ rcu_read_unlock(); ++ return; ++ } ++ } ++ + skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb)); + ieee80211_aggr_check(sdata, sta, skb); + diff --git a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-512MB-profile-in-ath11k.patch b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-512MB-profile-in-ath11k.patch new file mode 100644 index 00000000000000..0e7ddb8539a207 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-512MB-profile-in-ath11k.patch @@ -0,0 +1,332 @@ +From 1b402e444ff99efe84d09a084b96c39826783a8e Mon Sep 17 00:00:00 2001 +From: Ramya Gnanasekar +Date: Thu, 10 Sep 2020 13:33:55 +0530 +Subject: [PATCH] ath11k: Enable 512MB profile in ath11k + +Below changes are made to enable 512MB mem mode in ath11k + * Makefile changes to implement compilation flag when + 512MB mem profile is configured. + * Enabling 512MB mem profile by default from Makefile + for IPQ5018. This can be removed later once + 512MB profile config is supported. + * Update target_mem_mode, number of stations, peer and vap + during compile time + +Signed-off-by: Ramya Gnanasekar +--- + drivers/net/wireless/ath/ath11k/Kconfig | 7 +++++++ + drivers/net/wireless/ath/ath11k/hw.h | 14 +++++++++++--- + drivers/net/wireless/ath/ath11k/qmi.c | 2 +- + drivers/net/wireless/ath/ath11k/qmi.h | 6 +++++- + 4 files changed, 24 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/Kconfig ++++ b/drivers/net/wireless/ath/ath11k/Kconfig +@@ -23,6 +23,13 @@ config ATH11K_NSS_SUPPORT + + If unsure, say Y to enable NSS offload support. + ++config ATH11K_MEM_PROFILE_512M ++ bool "ath11k enable 512MB memory profile" ++ depends on ATH11K ++ default n ++ ---help--- ++ Enables 512MB memory profile for ath11k ++ + config ATH11K_AHB + tristate "Atheros ath11k AHB support" + depends on m +--- a/drivers/net/wireless/ath/ath11k/hw.h ++++ b/drivers/net/wireless/ath/ath11k/hw.h +@@ -11,11 +11,30 @@ + #include "wmi.h" + + /* Target configuration defines */ ++#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_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) + + #define TARGET_NUM_PEERS_PDEV(ab) (ab->hw_params.num_peers + TARGET_NUM_VDEVS(ab)) ++/* Max num of stations (per radio) */ ++#define TARGET_NUM_STATIONS(ab) (ab->hw_params.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_MON_STATUS_RING_SIZE 1024 ++#define ATH11K_DP_RXDMA_MONITOR_BUF_RING_SIZE 4096 ++#define ATH11K_DP_RXDMA_MONITOR_DST_RING_SIZE 2048 ++#endif + + /* Num of peers for Single Radio mode */ + #define TARGET_NUM_PEERS_SINGLE(ab) (TARGET_NUM_PEERS_PDEV(ab)) +@@ -26,9 +45,6 @@ + /* Num of peers for DBS_SBS */ + #define TARGET_NUM_PEERS_DBS_SBS(ab) (3 * TARGET_NUM_PEERS_PDEV(ab)) + +-/* Max num of stations (per radio) */ +-#define TARGET_NUM_STATIONS(ab) (ab->hw_params.num_peers) +- + #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) + \ +--- a/drivers/net/wireless/ath/ath11k/qmi.h ++++ b/drivers/net/wireless/ath/ath11k/qmi.h +@@ -29,6 +29,12 @@ + #define ATH11K_QMI_BDF_EXT_STR_LENGTH 0x20 + #define ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT 5 + ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M ++#define ATH11K_QMI_IPQ8074_M3_DUMP_ADDRESS 0x4E800000 ++#else ++#define ATH11K_QMI_IPQ8074_M3_DUMP_ADDRESS 0x51000000 ++#endif ++ + #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); + ++enum ath11k_target_mem_mode { ++ ATH11K_QMI_TARGET_MEM_MODE_DEFAULT = 0, ++ ATH11K_QMI_TARGET_MEM_MODE_512M, ++ ATH11K_QMI_TARGET_MEM_MODE_256M, ++}; ++ + #endif +--- a/local-symbols ++++ b/local-symbols +@@ -171,6 +171,7 @@ ATH11K= + ATH11K_AHB= + ATH11K_PCI= + ATH11K_NSS_SUPPORT= ++ATH11K_MEM_PROFILE_512M= + ATH11K_DEBUG= + ATH11K_DEBUGFS= + 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 { + u16 hw_rev; + }; + ++struct ath11k_num_vdevs_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 + ++ atomic_t num_max_allowed; ++ struct ath11k_num_vdevs_peers *num_vdevs_peers; ++ + /* 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 +@@ -206,8 +206,9 @@ struct ath11k_pdev_dp { + #define DP_WBM_RELEASE_RING_SIZE 64 + #define DP_TCL_DATA_RING_SIZE 512 + #define DP_TCL_DATA_RING_SIZE_WCN6750 2048 +-#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_TCL_CMD_RING_SIZE 32 + #define DP_TCL_STATUS_RING_SIZE 32 + #define DP_REO_DST_RING_MAX 4 +@@ -220,9 +221,9 @@ struct ath11k_pdev_dp { + #define DP_RXDMA_BUF_RING_SIZE 4096 + #define DP_RXDMA_REFILL_RING_SIZE 2048 + #define DP_RXDMA_ERR_DST_RING_SIZE 1024 +-#define DP_RXDMA_MON_STATUS_RING_SIZE 1024 +-#define DP_RXDMA_MONITOR_BUF_RING_SIZE 4096 +-#define DP_RXDMA_MONITOR_DST_RING_SIZE 2048 ++#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 ++#define DP_RXDMA_MONITOR_DST_RING_SIZE ATH11K_DP_RXDMA_MONITOR_BUF_RING_SIZE + #define DP_RXDMA_MONITOR_DESC_RING_SIZE 4096 + + #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: + skb->data, skb->len); + + atomic_inc(&ar->dp.num_tx_pending); ++ atomic_inc(&ab->num_max_allowed); + + return 0; + +@@ -309,6 +310,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); ++ atomic_dec(&ab->num_max_allowed); + } + + static void +@@ -342,6 +344,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); ++ atomic_dec(&ab->num_max_allowed); + + dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); + +@@ -769,6 +772,7 @@ void ath11k_dp_tx_completion_handler(str + wake_up(&ar->dp.tx_empty_waitq); + + ath11k_dp_tx_complete_msdu(ar, msdu, &ts); ++ atomic_dec(&ab->num_max_allowed); + } + } + +--- 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; + module_param_named(ftm_mode, ath11k_ftm_mode, bool, 0444); + MODULE_PARM_DESC(ftm_mode, "Boots up in factory test mode"); + ++static const struct ath11k_num_vdevs_peers ath11k_vdevs_peers[]; ++ + static struct ath11k_hw_params ath11k_hw_params[] = { + { + .hw_rev = ATH11K_HW_IPQ8074, +@@ -100,6 +104,7 @@ static struct ath11k_hw_params ath11k_hw + .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, +@@ -177,7 +182,7 @@ static struct ath11k_hw_params ath11k_hw + .coldboot_cal_mm = true, + .coldboot_cal_ftm = true, + .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 +264,7 @@ static struct ath11k_hw_params ath11k_hw + .coldboot_cal_mm = false, + .coldboot_cal_ftm = false, + .cbcal_restart_fw = false, +- .fw_mem_mode = 0, ++ .fw_mem_mode = ATH11K_QMI_TARGET_MEM_MODE, + .num_vdevs = 16 + 1, + .num_peers = 512, + .supports_suspend = true, +@@ -426,7 +431,7 @@ static struct ath11k_hw_params ath11k_hw + .coldboot_cal_mm = false, + .coldboot_cal_ftm = false, + .cbcal_restart_fw = false, +- .fw_mem_mode = 0, ++ .fw_mem_mode = ATH11K_QMI_TARGET_MEM_MODE, + .num_vdevs = 16 + 1, + .num_peers = 512, + .supports_suspend = true, +@@ -509,7 +514,7 @@ static struct ath11k_hw_params ath11k_hw + .coldboot_cal_mm = false, + .coldboot_cal_ftm = false, + .cbcal_restart_fw = false, +- .fw_mem_mode = 0, ++ .fw_mem_mode = ATH11K_QMI_TARGET_MEM_MODE, + .num_vdevs = 16 + 1, + .num_peers = 512, + .supports_suspend = true, +@@ -593,7 +598,7 @@ static struct ath11k_hw_params ath11k_hw + .coldboot_cal_mm = true, + .coldboot_cal_ftm = true, + .cbcal_restart_fw = false, +- .fw_mem_mode = 0, ++ .fw_mem_mode = ATH11K_QMI_TARGET_MEM_MODE, + .num_vdevs = 16 + 1, + .num_peers = 512, + .supports_suspend = false, +@@ -672,7 +677,7 @@ static struct ath11k_hw_params ath11k_hw + .supports_monitor = false, + .supports_sta_ps = false, + .supports_shadow_regs = false, +- .fw_mem_mode = 0, ++ .fw_mem_mode = ATH11K_QMI_TARGET_MEM_MODE, + .num_vdevs = 16 + 1, + .num_peers = 512, + .supports_regdb = false, +@@ -710,7 +715,23 @@ static struct ath11k_hw_params ath11k_hw + }, + }; + +-static inline struct ath11k_pdev *ath11k_core_get_single_pdev(struct ath11k_base *ab) ++static const struct ath11k_num_vdevs_peers ath11k_vdevs_peers[] = { ++ { ++ .num_vdevs = (16 + 1), ++ .num_peers = 512, ++ }, ++ { ++ .num_vdevs = (8 + 1), ++ .num_peers = 128, ++ }, ++ { ++ .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 +@@ -1592,10 +1592,13 @@ static ssize_t ath11k_dump_mgmt_stats(st + size_t count, loff_t *ppos) + { + struct ath11k *ar = file->private_data; ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M ++ struct ath11k_base *ab = ar->ab; ++#endif + 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/207-mac80211-add-nss-redirect-support.patch b/package/kernel/mac80211/patches/ath11k_nss/207-mac80211-add-nss-redirect-support.patch new file mode 100644 index 00000000000000..c9a12d5f127cbe --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/207-mac80211-add-nss-redirect-support.patch @@ -0,0 +1,268 @@ +From 3acca4ecfe25a7d97e7cb820fd8c7c6324a1f318 Mon Sep 17 00:00:00 2001 +From: Sowmiya Sree Elavalagan +Date: Tue, 18 Aug 2020 16:17:25 +0530 +Subject: [PATCH] ath11k : Add NSS redirect support + +Add NSS Redirect support for ath11k. Tested on ipq8074 +Most of the changes are similar to the one done for ath10k with +minor changes to send to nss with eth header + +Redirect can be enabled by setting nss_redirect module param during +mac80211 insmod followed by ecm start +insmod mac80211.ko nss_redirect=1 +/etc/init.d/qca-nss-ecm start + +Check for ipv4_hash_hits counts in ipv4 stats and eth_rx +in qca-nss-drv to check whether packets are redirected or not. + +Verified both in nwifi and ethernet mode by running tcp and udp +traffic. + +Co-developed by: Sriram R +Signed-off-by: Sriram R +Signed-off-by: Sowmiya Sree Elavalagan +--- + net/mac80211/ieee80211_i.h | 2 ++ + net/mac80211/iface.c | 43 ++++++++++++++++++++++++++++++++ + net/mac80211/rx.c | 61 +++++++++++++++++++++++++++++++++++++--------- + net/mac80211/tx.c | 32 ++++++++++++++++++++++++ + 4 files changed, 126 insertions(+), 12 deletions(-) + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -34,6 +34,9 @@ + #include "sta_info.h" + #include "debug.h" + #include "drop.h" ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++#include ++#endif + + extern const struct cfg80211_ops mac80211_config_ops; + +@@ -1120,6 +1123,9 @@ struct ieee80211_sub_if_data { + struct dentry *default_beacon_key; + } debugfs; + #endif ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++ struct nss_virt_if_handle *nssctx; ++#endif + + /* must be last, dynamically sized area in this! */ + struct ieee80211_vif vif; +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -27,6 +27,12 @@ + #include "wme.h" + #include "rate.h" + ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++bool nss_redirect = false; ++module_param(nss_redirect, bool, 0644); ++MODULE_PARM_DESC(nss_redirect, "module param to enable NSS Redirect; 1-enable, 0-disable"); ++#endif ++ + /** + * DOC: Interface list locking + * +@@ -752,6 +758,13 @@ static int ieee80211_stop(struct net_dev + + cancel_work_sync(&sdata->activate_links_work); + ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++ if (sdata->nssctx) { ++ nss_virt_if_destroy_sync(sdata->nssctx); ++ sdata_info(sdata, "Destroyed NSS virtual interface\n"); ++ } ++#endif ++ + wiphy_lock(sdata->local->hw.wiphy); + ieee80211_do_stop(sdata, true); + wiphy_unlock(sdata->local->hw.wiphy); +@@ -1219,6 +1232,34 @@ void ieee80211_del_virtual_monitor(struc + kfree(sdata); + } + ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++/* This callback is registered for nss redirect to receive packet exceptioned from nss in Rx path. ++ * When packet does not match any of the ecm rules is redirected back here. ++ */ ++void receive_from_nss(struct net_device *dev, struct sk_buff *sk_buff, struct napi_struct *napi) ++{ ++ struct net_device *netdev; ++ struct sk_buff *skb; ++ struct ieee80211_sub_if_data *sdata; ++ ++ if (!dev) { ++ kfree(sk_buff); ++ return; ++ } ++ ++ netdev = (struct net_device *)dev; ++ sdata = netdev_priv(netdev); ++ if (sdata->dev != dev) { ++ kfree(sk_buff); ++ return; ++ } ++ skb = (struct sk_buff *)sk_buff; ++ skb->dev = netdev; ++ skb->protocol = eth_type_trans(skb, netdev); ++ napi_gro_receive(napi, skb); ++} ++#endif ++ + /* + * NOTE: Be very careful when changing this function, it must NOT return + * an error on interface type changes that have been pre-checked, so most +@@ -1450,6 +1491,19 @@ int ieee80211_do_open(struct wireless_de + + ieee80211_recalc_ps(local); + ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++ sdata->nssctx = NULL; ++ if (nss_redirect) { ++ sdata->nssctx = nss_virt_if_create_sync(dev); ++ if (sdata->nssctx) { ++ sdata_info(sdata, "Created a NSS virtual interface\n"); ++ nss_virt_if_register(sdata->nssctx, receive_from_nss, sdata->dev); ++ } else { ++ sdata_info(sdata, "Failed to create a NSS virtual interface\n"); ++ } ++ } ++#endif ++ + set_bit(SDATA_STATE_RUNNING, &sdata->state); + + return 0; +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -2570,6 +2570,54 @@ static bool ieee80211_frame_allowed(stru + return true; + } + ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++#define case_rtn_string(val) case val: return #val ++ ++static const char *nss_tx_status_str(nss_tx_status_t status) ++{ ++ switch (status) { ++ case_rtn_string(NSS_TX_SUCCESS); ++ case_rtn_string(NSS_TX_FAILURE); ++ case_rtn_string(NSS_TX_FAILURE_QUEUE); ++ case_rtn_string(NSS_TX_FAILURE_NOT_READY); ++ case_rtn_string(NSS_TX_FAILURE_TOO_LARGE); ++ case_rtn_string(NSS_TX_FAILURE_TOO_SHORT); ++ case_rtn_string(NSS_TX_FAILURE_NOT_SUPPORTED); ++ case_rtn_string(NSS_TX_FAILURE_BAD_PARAM); ++ default: ++ return "Unknown NSS TX status"; ++ } ++} ++ ++static void netif_rx_nss(struct ieee80211_rx_data *rx, ++ struct sk_buff *skb) ++{ ++ struct ieee80211_sub_if_data *sdata = rx->sdata; ++ int ret; ++ ++ if (!sdata->nssctx) ++ goto out; ++ ++ /* NSS expects ethernet header in skb data so resetting here */ ++ skb_push(skb, ETH_HLEN); ++ ret = nss_virt_if_tx_buf(sdata->nssctx, skb); ++ if (ret) { ++ if (net_ratelimit()) { ++ sdata_err(sdata, "NSS TX failed with error: %s\n", ++ nss_tx_status_str(ret)); ++ } ++ goto out; ++ } ++ ++ return; ++out: ++ if (rx->napi) ++ napi_gro_receive(rx->napi, skb); ++ else ++ netif_receive_skb(skb); ++} ++#endif ++ + 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 + !ether_addr_equal(ehdr->h_dest, sdata->vif.addr))) + ether_addr_copy(ehdr->h_dest, sdata->vif.addr); + ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++ netif_rx_nss(rx, skb); ++#else + /* deliver to local stack */ + if (rx->list) + list_add_tail(&skb->list, rx->list); + else + netif_receive_skb(skb); ++#endif + } + } + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -4501,6 +4501,35 @@ static void ieee80211_mlo_multicast_tx(s + kfree_skb(skb); + } + ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++void ieee80211_xmit_nss_fixup(struct sk_buff *skb, ++ struct net_device *dev) ++{ ++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); ++ ++ /* Packets from NSS does not have valid protocol, priority and other ++ * network stack values. Derive required parameters (priority ++ * and network_header) from payload for QoS header. ++ * XXX: Here the assumption is that packet are in 802.3 format. ++ * As of now priority is handled only for IPv4 and IPv6. ++ */ ++ ++ if (sdata->nssctx && likely(!skb->protocol)) { ++ skb_set_network_header(skb, 14); ++ switch (((struct ethhdr *)skb->data)->h_proto) { ++ case htons(ETH_P_IP): ++ skb->priority = (ipv4_get_dsfield(ip_hdr(skb)) & ++ 0xfc) >> 5; ++ break; ++ case htons(ETH_P_IPV6): ++ skb->priority = (ipv6_get_dsfield(ipv6_hdr(skb)) & ++ 0xfc) >> 5; ++ break; ++ } ++ } ++} ++#endif ++ + /** + * 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 + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + const struct ethhdr *eth = (void *)skb->data; + ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++ ieee80211_xmit_nss_fixup(skb, dev); ++#endif ++ + if (likely(!is_multicast_ether_addr(eth->h_dest))) + goto normal; + +@@ -4700,6 +4733,9 @@ netdev_tx_t ieee80211_subif_start_xmit_8 + struct ieee80211_key *key; + struct sta_info *sta; + ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++ ieee80211_xmit_nss_fixup(skb, dev); ++#endif + if (unlikely(!ieee80211_sdata_running(sdata) || skb->len < ETH_HLEN)) { + kfree_skb(skb); + return NETDEV_TX_OK; 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 new file mode 100644 index 00000000000000..ddae9fcbc50e7d --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/211-ath11k-add-obss-pd-support.patch @@ -0,0 +1,56 @@ +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/214-ath11k-qos-null-frame-tx-over-wmi.patch b/package/kernel/mac80211/patches/ath11k_nss/214-ath11k-qos-null-frame-tx-over-wmi.patch new file mode 100644 index 00000000000000..a69c5b2af244f8 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/214-ath11k-qos-null-frame-tx-over-wmi.patch @@ -0,0 +1,519 @@ +From 0e29b669153f100b60107d5f6b3fe407b71ba79a Mon Sep 17 00:00:00 2001 +From: Sowmiya Sree Elavalagan +Date: Wed, 30 Sep 2020 22:33:42 +0530 +Subject: [PATCH] ath11k: QOS null frame tx over wmi + +Added support to send qos null frame through FW. +NSS driver does not support QOS null frame tx. +Hence this is brought for nss offload case to send +qos null frame. QOS null packet queued from mac80211 +is sent to FW through wmi interface. This happens only if FW supports +qos null tx, this is based on service bit received in ext2 service +event from FW. On successful transmission of QOS null frame status +is set 0 in the event received for this wmi message. This is status +is sent to mac80211 for further handling. + +Signed-off-by: Sowmiya Sree Elavalagan +--- + drivers/net/wireless/ath/ath11k/mac.c | 28 ++++- + drivers/net/wireless/ath/ath11k/wmi.c | 200 ++++++++++++++++++++++++++-------- + drivers/net/wireless/ath/ath11k/wmi.h | 46 +++++++- + 3 files changed, 220 insertions(+), 54 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -6129,6 +6129,16 @@ static int ath11k_mac_mgmt_tx_wmi(struct + + ATH11K_SKB_CB(skb)->paddr = paddr; + ++ if (ieee80211_is_qos_nullfunc(hdr->frame_control)) { ++ ret = ath11k_wmi_qos_null_send(ar, arvif->vdev_id, buf_id, skb); ++ if (ret) { ++ ath11k_warn(ar->ab, "failed to send qos null frame over wmi: %d\n", ret); ++ goto err_unmap_buf; ++ } ++ ++ return 0; ++ } ++ + ret = ath11k_wmi_mgmt_send(ar, arvif->vdev_id, buf_id, skb); + if (ret) { + ath11k_warn(ar->ab, "failed to send mgmt frame: %d\n", ret); +@@ -6196,8 +6206,8 @@ static void ath11k_mgmt_over_wmi_tx_work + } + } + +-static int ath11k_mac_mgmt_tx(struct ath11k *ar, struct sk_buff *skb, +- bool is_prb_rsp) ++static int ath11k_mac_tx_over_wmi(struct ath11k *ar, struct sk_buff *skb, ++ bool is_prb_rsp) + { + struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue; + +@@ -6259,7 +6269,7 @@ static void ath11k_mac_op_tx(struct ieee + } else if (ieee80211_is_mgmt(hdr->frame_control)) { + frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, hdr->frame_control); + is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control); +- ret = ath11k_mac_mgmt_tx(ar, skb, is_prb_rsp); ++ ret = ath11k_mac_tx_over_wmi(ar, skb, is_prb_rsp); + if (ret) { + if (ret != -EBUSY) + ath11k_warn(ar->ab, "failed to queue management frame %d\n", +@@ -6274,6 +6284,20 @@ static void ath11k_mac_op_tx(struct ieee + spin_unlock_bh(&ar->data_lock); + } + return; ++ } else if (ar->ab->nss.enabled && ++ ieee80211_is_qos_nullfunc(hdr->frame_control) && ++ test_bit(WMI_TLV_SERVICE_QOS_NULL_FRAME_TX_OVER_WMI, ++ ar->ab->wmi_ab.svc_map)) { ++ /* NSS driver does not support tx qos null pkt hence it is offload ++ * to fw via wmi path similar to mgmt frames ++ */ ++ ret = ath11k_mac_tx_over_wmi(ar, skb, false); ++ if (ret) { ++ ath11k_warn(ar->ab, "failed to queue qos null frame %d\n", ++ ret); ++ ieee80211_free_txskb(ar->hw, skb); ++ } ++ return; + } + + 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" }, + [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" }, + [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" }, + [WMI_TAG_SCAN_EVENT] +- = { .min_len = sizeof(struct wmi_scan_event) }, ++ = { .min_len = sizeof(struct wmi_scan_event), .policy = "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 * + return ret; + } + ++int ath11k_wmi_qos_null_send(struct ath11k *ar, u32 vdev_id, u32 buf_id, ++ struct sk_buff *frame) ++{ ++ struct ath11k_pdev_wmi *wmi = ar->wmi; ++ struct wmi_qos_null_tx_cmd *cmd; ++ struct wmi_tlv *frame_tlv; ++ struct sk_buff *skb; ++ u32 buf_len; ++ int len, ret = 0; ++ ++ buf_len = frame->len < WMI_QOS_NULL_SEND_BUF_LEN ? ++ frame->len : WMI_QOS_NULL_SEND_BUF_LEN; ++ ++ len = sizeof(*cmd) + sizeof(*frame_tlv) + roundup(buf_len, 4); ++ ++ skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); ++ if (!skb) ++ return -ENOMEM; ++ ++ cmd = (struct wmi_qos_null_tx_cmd *)skb->data; ++ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_QOS_NULL_FRAME_TX_SEND) | ++ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); ++ cmd->vdev_id = vdev_id; ++ cmd->desc_id = buf_id; ++ cmd->paddr_lo = lower_32_bits(ATH11K_SKB_CB(frame)->paddr); ++ cmd->paddr_hi = upper_32_bits(ATH11K_SKB_CB(frame)->paddr); ++ cmd->frame_len = frame->len; ++ cmd->buf_len = buf_len; ++ ++ frame_tlv = (struct wmi_tlv *)(skb->data + sizeof(*cmd)); ++ frame_tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) | ++ FIELD_PREP(WMI_TLV_LEN, buf_len); ++ ++ memcpy(frame_tlv->value, frame->data, buf_len); ++ ++ ath11k_ce_byte_swap(frame_tlv->value, buf_len); ++ ++ ret = ath11k_wmi_cmd_send(wmi, skb, WMI_QOS_NULL_FRAME_TX_SEND_CMDID); ++ if (ret) { ++ ath11k_warn(ar->ab, ++ "failed to submit WMI_QOS_NULL_FRAME_TX_SEND_CMDID cmd\n"); ++ dev_kfree_skb(skb); ++ } ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, ++ "wmi QOS null tx send cmd sent successfully\n"); ++ return ret; ++} ++ + 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 + return 0; + } + +-static int wmi_process_mgmt_tx_comp(struct ath11k *ar, +- struct wmi_mgmt_tx_compl_event *tx_compl_param) ++static int wmi_process_tx_comp(struct ath11k *ar, ++ struct wmi_tx_compl_event *tx_compl_param) + { + struct sk_buff *msdu; + struct ieee80211_tx_info *info; +@@ -5895,6 +5944,11 @@ static int wmi_process_mgmt_tx_comp(stru + info->status.ack_signal = tx_compl_param->ack_rssi; + } + ++ /* dont update rates in this path, qos null data tx completions also can ++ * take this path in case of nss offload and can update invalid rates. ++ */ ++ info->status.rates[0].idx = -1; ++ + 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 + 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]++; ++ 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: +@@ -5938,12 +5995,13 @@ skip_mgmt_stats: + return 0; + } + +-static int ath11k_pull_mgmt_tx_compl_param_tlv(struct ath11k_base *ab, +- struct sk_buff *skb, +- struct wmi_mgmt_tx_compl_event *param) ++static int ath11k_pull_tx_compl_param_tlv(struct ath11k_base *ab, ++ struct sk_buff *skb, ++ struct wmi_tx_compl_event *param, ++ int event_id) + { + const void **tb; +- const struct wmi_mgmt_tx_compl_event *ev; ++ const struct wmi_tx_compl_event *ev; + 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 + return ret; + } + +- ev = tb[WMI_TAG_MGMT_TX_COMPL_EVENT]; ++ ev = tb[event_id]; + if (!ev) { + ath11k_warn(ab, "failed to fetch mgmt tx compl ev"); + kfree(tb); +@@ -7730,10 +7788,11 @@ exit: + + static void ath11k_mgmt_tx_compl_event(struct ath11k_base *ab, struct sk_buff *skb) + { +- struct wmi_mgmt_tx_compl_event tx_compl_param = {0}; ++ struct wmi_tx_compl_event tx_compl_param = {0}; + struct ath11k *ar; + +- if (ath11k_pull_mgmt_tx_compl_param_tlv(ab, skb, &tx_compl_param) != 0) { ++ if (ath11k_pull_tx_compl_param_tlv(ab, skb, &tx_compl_param, ++ WMI_TAG_MGMT_TX_COMPL_EVENT) != 0) { + ath11k_warn(ab, "failed to extract mgmt tx compl event"); + return; + } +@@ -7746,7 +7805,7 @@ static void ath11k_mgmt_tx_compl_event(s + goto exit; + } + +- wmi_process_mgmt_tx_comp(ar, &tx_compl_param); ++ wmi_process_tx_comp(ar, &tx_compl_param); + + 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: + rcu_read_unlock(); + } + ++static void ath11k_qos_null_compl_event(struct ath11k_base *ab, struct sk_buff *skb) ++{ ++ struct wmi_tx_compl_event tx_compl_param = {0}; ++ struct ath11k *ar; ++ ++ if (ath11k_pull_tx_compl_param_tlv(ab, skb, &tx_compl_param, ++ WMI_TAG_QOS_NULL_FRAME_TX_STATUS) != 0) { ++ ath11k_warn(ab, "failed to extract qos null tx compl event"); ++ return; ++ } ++ ++ rcu_read_lock(); ++ ar = ath11k_mac_get_ar_by_pdev_id(ab, tx_compl_param.pdev_id); ++ if (!ar) { ++ ath11k_warn(ab, "invalid pdev id %d in qos_null_tx_compl_event\n", ++ tx_compl_param.pdev_id); ++ goto exit; ++ } ++ ++ wmi_process_tx_comp(ar, &tx_compl_param); ++ ++ ath11k_dbg(ab, ATH11K_DBG_WMI, ++ "QOS null tx compl ev pdev_id %d, desc_id %d, status %d", ++ tx_compl_param.pdev_id, tx_compl_param.desc_id, ++ tx_compl_param.status); ++ ++exit: ++ rcu_read_unlock(); ++} ++ + 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); + 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; +--- a/drivers/net/wireless/ath/ath11k/wmi.h ++++ b/drivers/net/wireless/ath/ath11k/wmi.h +@@ -363,6 +363,7 @@ enum wmi_tlv_cmd_id { + WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, + WMI_VDEV_BCN_OFFLOAD_QUIET_CONFIG_CMDID, + WMI_FILS_DISCOVERY_TMPL_CMDID, ++ WMI_QOS_NULL_FRAME_TX_SEND_CMDID, + WMI_ADDBA_CLEAR_RESP_CMDID = WMI_TLV_CMD(WMI_GRP_BA_NEG), + WMI_ADDBA_SEND_CMDID, + WMI_ADDBA_STATUS_CMDID, +@@ -693,6 +694,8 @@ enum wmi_tlv_event_id { + WMI_TBTTOFFSET_EXT_UPDATE_EVENTID, + WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID, + WMI_HOST_FILS_DISCOVERY_EVENTID, ++ WMI_HOST_SWBA_V2_EVENTID, ++ WMI_QOS_NULL_FRAME_TX_COMPLETION_EVENTID, + WMI_TX_DELBA_COMPLETE_EVENTID = WMI_TLV_CMD(WMI_GRP_BA_NEG), + WMI_TX_ADDBA_COMPLETE_EVENTID, + WMI_BA_RSP_SSN_EVENTID, +@@ -1880,6 +1883,9 @@ enum wmi_tlv_tag { + 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_MAX + }; + +@@ -2107,7 +2113,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, ++ WMI_TLV_SERVICE_CONFIGURE_ROAM_TRIGGER_PARAM_SUPPORT = 254, ++ WMI_TLV_SERVICE_CFR_TA_RA_AS_FP_SUPPORT = 255, ++ WMI_TLV_SERVICE_CFR_CAPTURE_COUNT_SUPPORT = 256, ++ WMI_TLV_SERVICE_OCV_SUPPORT = 257, ++ WMI_TLV_SERVICE_LL_STATS_PER_CHAN_RX_TX_TIME_SUPPORT = 258, ++ WMI_TLV_SERVICE_THERMAL_MULTI_CLIENT_SUPPORT = 259, ++ WMI_TLV_SERVICE_NAN_SEND_NAN_ENABLE_RESPONSE_TO_HOST = 260, ++ WMI_TLV_SERVICE_UNIFIED_LL_GET_STA_CMD_SUPPORT = 261, ++ WMI_TLV_SERVICE_FSE_CMEM_ALLOC_SUPPORT = 262, + WMI_TLV_SERVICE_PASSIVE_SCAN_START_TIME_ENHANCE = 263, ++ WMI_TLV_SERVICE_QOS_NULL_FRAME_TX_OVER_WMI = 264, + + /* The second 128 bits */ + WMI_MAX_EXT_SERVICE = 256, +@@ -3814,6 +3830,7 @@ struct wmi_scan_prob_req_oui_cmd { + } __packed; + + #define WMI_MGMT_SEND_DOWNLD_LEN 64 ++#define WMI_QOS_NULL_SEND_BUF_LEN 64 + + #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 { + #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) +-#define WMI_TX_PARAMS_DWORD1_RSVD GENMASK(31, 21) ++#define WMI_TX_PARAMS_DWORD1_CFR_CAPTURE BIT(21) ++#define WMI_TX_PARAMS_DWORD1_RSVD GENMASK(31, 22) + +-struct wmi_mgmt_send_params { ++struct wmi_tx_send_params { + 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 { + u32 rssi_ctl_ext[MAX_ANTENNA_EIGHT - ATH_MAX_ANTENNA]; + }; + +-struct wmi_mgmt_tx_compl_event { ++struct wmi_tx_compl_event { + u32 desc_id; + u32 status; + u32 pdev_id; +@@ -5748,6 +5765,17 @@ struct wmi_debug_log_config_cmd_fixed_pa + u32 value; + } __packed; + ++struct wmi_qos_null_tx_cmd { ++ u32 tlv_header; ++ u32 vdev_id; ++ u32 desc_id; ++ u32 paddr_lo; ++ u32 paddr_hi; ++ u32 frame_len; ++ u32 buf_len; ++ u32 tx_params_valid; ++} __packed; ++ + #define WMI_MAX_MEM_REQS 32 + + #define MAX_RADIOS 3 +@@ -6358,6 +6386,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); ++int ath11k_wmi_qos_null_send(struct ath11k *ar, u32 vdev_id, u32 buf_id, ++ struct sk_buff *frame); + int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id, + struct ieee80211_mutable_offsets *offs, + struct sk_buff *bcn, u32 ema_param); diff --git a/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch b/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch new file mode 100644 index 00000000000000..0b9d559a4857ae --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch @@ -0,0 +1,906 @@ +From 30f54666ae15128f26fbad787a35253885a10513 Mon Sep 17 00:00:00 2001 +From: Ramya Gnanasekar +Date: Fri, 25 Dec 2020 16:11:06 +0530 +Subject: [PATCH] ath11k: Disable rx_header tlv for 2K SKB + +On low memory platform hdr_status in hal_rx_desc is not subscribed to +get a savings of 128bytes in skb. This is required to reduce the skb +size from 4K to 2K. Use HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG message +to unsubscribe rx_pkt_header tlv for rxdma ring. + +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 + } + + ar->debug.rx_filter = tlv_filter.rx_filter; ++ tlv_filter.offset_valid = false; + + 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 + } + + /* Clear rx filter set for monitor mode and rx status */ ++ tlv_filter.offset_valid = false; + 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, 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 { + #define DP_REO_CMD_RING_SIZE 256 + #define DP_REO_STATUS_RING_SIZE 2048 + #define DP_RXDMA_BUF_RING_SIZE 4096 +-#define DP_RXDMA_REFILL_RING_SIZE 2048 ++#define DP_RXDMA_REFILL_RING_SIZE ATH11K_DP_RXDMA_REFILL_RING_SIZE ++#define DP_RXDMA_NSS_REFILL_RING_SIZE ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE + #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 { + * + * |31 26|25|24|23 16|15 8|7 0| + * |-----------------+----------------+----------------+---------------| +- * | rsvd1 |PS|SS| ring_id | pdev_id | msg_type | ++ * | rsvd1|OV|PS|SS| ring_id | pdev_id | msg_type | + * |-------------------------------------------------------------------| + * | rsvd2 | ring_buffer_size | + * |-------------------------------------------------------------------| +@@ -623,6 +624,14 @@ enum htt_ppdu_stats_tag_type { + * |-------------------------------------------------------------------| + * | tlv_filter_in_flags | + * |-------------------------------------------------------------------| ++ * | rx_header_offset | rx_packet_offset | ++ * |-------------------------------------------------------------------| ++ * | rx_mpdu_start_offset | rx_mpdu_end_offset | ++ * |-------------------------------------------------------------------| ++ * | rx_msdu_start_offset | rx_msdu_end_offset | ++ * |-------------------------------------------------------------------| ++ * | rsvd3 | rx_attention_offset | ++ * |-------------------------------------------------------------------| + * Where: + * PS = pkt_swap + * SS = status_swap +@@ -636,6 +645,9 @@ enum htt_ppdu_stats_tag_type { + * 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 - rx_offset_valid (OV): flag to indicate rx offsets ++ * configuration fields are valid ++ * + * b'26: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 { + * dword6 - b'0:31 - tlv_filter_in_flags: + * Filter in Attention/MPDU/PPDU/Header/User tlvs + * Refer to CFG_TLV_FILTER_IN_FLAG defs ++ * dword7 - b'0:15 - rx_packet_offset: rx_packet_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_1 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * - b'16:31 - rx_header_offset: rx_header_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_1 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * dword8 - b'0:15 - rx_mpdu_end_offset: rx_mpdu_end_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_2 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * - b'16:31 - rx_mpdu_start_offset: rx_mpdu_start_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_2 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * dword9 - b'0:15 - rx_msdu_end_offset: rx_msdu_end_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_3 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * - b'16:31 - rx_msdu_start_offset: rx_msdu_start_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_3 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * dword10- b'0:15 - rx_attention_offset: rx_attention_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_4 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * - b'16:31 - rsvd3 for future use + */ + + #define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) +@@ -672,8 +720,16 @@ enum htt_ppdu_stats_tag_type { + #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) ++#define HTT_RX_RING_SELECTION_CFG_CMD_OFFSET_VALID BIT(26) + + #define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE GENMASK(15, 0) ++#define HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET GENMASK(15, 0) ++#define HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET GENMASK(31, 16) ++#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET GENMASK(15, 0) ++#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET GENMASK(31, 16) ++#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET GENMASK(15, 0) ++#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET GENMASK(31, 16) ++#define HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET GENMASK(15, 0) + + 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 { + HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER | \ + HTT_RX_FILTER_TLV_FLAGS_ATTENTION) + ++#define HTT_RX_RXDMA_FILTER_TLV_FLAGS_BUF_RING \ ++ (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ ++ HTT_RX_FILTER_TLV_FLAGS_MSDU_START | \ ++ HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \ ++ HTT_RX_FILTER_TLV_FLAGS_MSDU_END | \ ++ HTT_RX_FILTER_TLV_FLAGS_MPDU_END | \ ++ HTT_RX_FILTER_TLV_FLAGS_ATTENTION) ++ + struct htt_rx_ring_selection_cfg_cmd { + u32 info0; + u32 info1; +@@ -985,6 +1049,10 @@ struct htt_rx_ring_selection_cfg_cmd { + u32 pkt_type_en_flags2; + u32 pkt_type_en_flags3; + u32 rx_filter_tlv; ++ u32 rx_packet_offset; ++ u32 rx_mpdu_offset; ++ u32 rx_msdu_offset; ++ u32 rx_attn_offset; + } __packed; + + struct htt_rx_ring_tlv_filter { +@@ -993,6 +1061,14 @@ struct htt_rx_ring_tlv_filter { + u32 pkt_filter_flags1; /* MGMT */ + u32 pkt_filter_flags2; /* CTRL */ + u32 pkt_filter_flags3; /* DATA */ ++ bool offset_valid; ++ u16 rx_packet_offset; ++ u16 rx_header_offset; ++ u16 rx_mpdu_end_offset; ++ u16 rx_mpdu_start_offset; ++ u16 rx_msdu_end_offset; ++ u16 rx_msdu_start_offset; ++ u16 rx_attn_offset; + }; + + #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 + return ab->hw_params.hw_ops->rx_desc_get_mpdu_fc_valid(desc); + } + ++static u16 ath11k_dp_rxdesc_get_mpdu_frame_ctrl(struct ath11k_base *ab, ++ struct hal_rx_desc *desc) ++{ ++ return ab->hw_params.hw_ops->rx_desc_get_mpdu_frame_ctl(desc); ++} ++ + 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 + return ab->hw_params.hw_ops->rx_desc_mpdu_start_addr2(desc); + } + ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M ++static void ath11k_dp_get_rx_header_offset(struct ath11k_base *ab, ++ struct htt_rx_ring_tlv_filter *tlv_filter) ++{ ++ ab->hw_params.hw_ops->rx_desc_get_offset(tlv_filter); ++} ++#endif ++ ++static bool ath11k_dp_rx_desc_dot11_hdr_fields_valid(struct ath11k_base *ab, ++ struct hal_rx_desc *desc) ++{ ++ return ab->hw_params.hw_ops->rx_desc_dot11_hdr_fields_valid(desc); ++} ++ ++static void ath11k_dp_rx_desc_get_dot11_hdr(struct ath11k_base *ab, ++ struct hal_rx_desc *desc, ++ struct ieee80211_hdr *hdr) ++{ ++ ab->hw_params.hw_ops->rx_desc_get_dot11_hdr(desc, hdr); ++} ++ ++static void ath11k_dp_rx_desc_get_crypto_header(struct ath11k_base *ab, ++ struct hal_rx_desc *desc, ++ u8 *crypto_hdr, ++ enum hal_encrypt_type enctype) ++{ ++ ab->hw_params.hw_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); ++} ++ + 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 + return 0; + } + ++static void ath11k_get_dot11_hdr_from_rx_desc(struct ath11k *ar, ++ struct sk_buff *msdu, ++ struct ath11k_skb_rxcb *rxcb, ++ struct ieee80211_rx_status *status, ++ enum hal_encrypt_type enctype) ++{ ++ struct hal_rx_desc *rx_desc = rxcb->rx_desc; ++ struct ath11k_base *ab = ar->ab; ++ size_t hdr_len, crypto_len; ++ struct ieee80211_hdr *hdr; ++ u16 fc, qos_ctl = 0; ++ u8 *crypto_hdr; ++ ++ if (!(status->flag & RX_FLAG_IV_STRIPPED)) { ++ crypto_len = ath11k_dp_rx_crypto_param_len(ar, enctype); ++ crypto_hdr = skb_push(msdu, crypto_len); ++ ath11k_dp_rx_desc_get_crypto_header(ab, rx_desc, crypto_hdr, enctype); ++ } ++ ++ fc = ath11k_dp_rxdesc_get_mpdu_frame_ctrl(ab, rx_desc); ++ hdr_len = ieee80211_hdrlen(fc); ++ skb_push(msdu, hdr_len); ++ hdr = (struct ieee80211_hdr *)msdu->data; ++ hdr->frame_control = fc; ++ ++ /* Get wifi header from rx_desc */ ++ ath11k_dp_rx_desc_get_dot11_hdr(ab, rx_desc, hdr); ++ ++ if (rxcb->is_mcbc) ++ status->flag &= ~RX_FLAG_PN_VALIDATED; ++ ++ /* Add QOS header */ ++ if (ieee80211_is_data_qos(hdr->frame_control)) { ++ qos_ctl = rxcb->tid; ++ if (ath11k_dp_rx_h_msdu_start_mesh_ctl_present(ab, rx_desc)) ++ qos_ctl |= IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT; ++ ++ /* TODO Add other QoS ctl fields when required */ ++ memcpy(msdu->data + (hdr_len - IEEE80211_QOS_CTL_LEN), ++ &qos_ctl, IEEE80211_QOS_CTL_LEN); ++ } ++} ++ + 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 + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + u16 qos_ctl = 0; +- u8 *qos; ++ u8 *qos, *crypto_hdr; ++ bool add_qos_ctrl = false; + + /* 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 + ether_addr_copy(sa, ieee80211_get_SA(hdr)); + skb_pull(msdu, ieee80211_hdrlen(hdr->frame_control)); + +- if (rxcb->is_first_msdu) { ++ if (rxcb->is_first_msdu && first_hdr) { + /* 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 + + /* copy decap header before overwriting for reuse below */ + memcpy(decap_hdr, (uint8_t *)hdr, hdr_len); ++ add_qos_ctrl = true; + } + + 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)); ++ if (first_hdr) { ++ memcpy(skb_push(msdu, ++ ath11k_dp_rx_crypto_param_len(ar, enctype)), ++ (void *)hdr + hdr_len, ++ ath11k_dp_rx_crypto_param_len(ar, enctype)); ++ } else { ++ crypto_hdr = skb_push(msdu, ath11k_dp_rx_crypto_param_len(ar, enctype)); ++ ath11k_dp_rx_desc_get_crypto_header(ar->ab, ++ rxcb->rx_desc, crypto_hdr, enctype); ++ } + } + +- if (!rxcb->is_first_msdu) { ++ if (!rxcb->is_first_msdu || add_qos_ctrl) { + 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 + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + void *rfc1042; ++ struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); ++ struct ath11k_dp_rfc1042_hdr rfc = {0xaa, 0xaa, 0x03, {0x00, 0x00, 0x00}}; ++ ++ if (!first_hdr) { ++ eth = (struct ethhdr *)msdu->data; ++ ether_addr_copy(da, eth->h_dest); ++ ether_addr_copy(sa, eth->h_source); ++ rfc.snap_type = eth->h_proto; ++ skb_pull(msdu, sizeof(struct ethhdr)); ++ 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); ++ goto exit; ++ } + + 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 + + memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); + ++exit: + /* 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( + size_t hdr_len; + u8 l3_pad_bytes; + struct hal_rx_desc *rx_desc; ++ struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); + + /* Delivered decapped frame: + * [amsdu header] <-- replaced with 802.11 hdr +@@ -2212,6 +2314,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); + ++ if (!first_hdr) { ++ ath11k_get_dot11_hdr_from_rx_desc(ar, msdu, rxcb, status, enctype); ++ return; ++ } ++ + 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 + goto free_out; + } + ++ hdr_status = ath11k_dp_rx_h_80211_hdr(ab, rx_desc); ++ /* wifi hdr fields validation for 512M:: ++ * Mcast packets in ethernet frame mode ++ * will need wifi hdr in msdu to validate PN. ++ * Header will be added in undecap routine. ++ * Validation on wifi hdr fields from rx_desc. ++ */ ++ if (!hdr_status && ath11k_dp_rx_h_attn_is_mcbc(ab, rx_desc) && ++ !ath11k_dp_rx_desc_dot11_hdr_fields_valid(ab, rx_desc)) { ++ ath11k_warn(ab, "One or more invalid dot11 header fields\n"); ++ ret = -EIO; ++ goto free_out; ++ } ++ + 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 + hdr_status = ath11k_dp_rx_h_80211_hdr(ab, rx_desc); + ret = -EINVAL; + ath11k_warn(ab, "invalid msdu len %u\n", msdu_len); +- ath11k_dbg_dump(ab, ATH11K_DBG_DATA, NULL, "", hdr_status, +- sizeof(struct ieee80211_hdr)); ++ if (hdr_status) ++ ath11k_dbg_dump(ab, ATH11K_DBG_DATA, NULL, "", hdr_status, ++ sizeof(struct ieee80211_hdr)); + 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 + + hdr = (struct ieee80211_hdr *)(msdu->data + hal_rx_desc_sz); + hdr_len = ieee80211_hdrlen(hdr->frame_control); ++ + 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 + + static u64 ath11k_dp_rx_h_get_pn(struct ath11k *ar, struct sk_buff *skb) + { +- struct ieee80211_hdr *hdr; + u64 pn = 0; ++ struct ieee80211_hdr *hdr; + 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 + 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); +- ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", hdr_status, +- sizeof(struct ieee80211_hdr)); ++ if (hdr_status) ++ ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", hdr_status, ++ sizeof(struct ieee80211_hdr)); + 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 + ath11k_dp_rxdma_pdev_buf_free(ar); + } + ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M ++static int ath11k_dp_rxdma_ring_sel_config(struct ath11k *ar) ++{ ++ struct ath11k_pdev_dp *dp = &ar->dp; ++ struct htt_rx_ring_tlv_filter tlv_filter = {0}; ++ u32 ring_id; ++ int ret; ++ u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; ++ ++ ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id; ++ ++ tlv_filter.rx_filter = HTT_RX_RXDMA_FILTER_TLV_FLAGS_BUF_RING; ++ tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR; ++ tlv_filter.pkt_filter_flags3 = HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST | ++ HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST; ++ tlv_filter.offset_valid = true; ++ tlv_filter.rx_packet_offset = hal_rx_desc_sz; ++ tlv_filter.rx_header_offset = 0; ++ ++ ath11k_dp_get_rx_header_offset(ar->ab, &tlv_filter); ++ ++ if (!ar->ab->nss.enabled) ++ ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, dp->mac_id, ++ HAL_RXDMA_BUF, ++ DP_RXDMA_REFILL_RING_SIZE, ++ &tlv_filter); ++ else ++ ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, dp->mac_id, ++ HAL_RXDMA_BUF, ++ DP_RXDMA_NSS_REFILL_RING_SIZE, ++ &tlv_filter); ++ ++ return ret; ++} ++#else ++static int ath11k_dp_rxdma_ring_sel_config(struct ath11k *ar) ++{ ++ return 0; ++} ++#endif ++ + 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: + } + } + ++ ret = ath11k_dp_rxdma_ring_sel_config(ar); ++ if (ret) { ++ ath11k_warn(ab, "failed to setup rxdma ring selection config\n"); ++ return ret; ++ } ++ + return 0; + } + +--- 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 + !!(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)); ++ cmd->info0 |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_OFFSET_VALID, ++ tlv_filter->offset_valid); + + 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 + cmd->pkt_type_en_flags3 = tlv_filter->pkt_filter_flags3; + cmd->rx_filter_tlv = tlv_filter->rx_filter; + ++ if (tlv_filter->offset_valid) { ++ cmd->rx_packet_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET, ++ tlv_filter->rx_packet_offset); ++ cmd->rx_packet_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET, ++ tlv_filter->rx_header_offset); ++ ++ cmd->rx_mpdu_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET, ++ tlv_filter->rx_mpdu_end_offset); ++ cmd->rx_mpdu_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET, ++ tlv_filter->rx_mpdu_start_offset); ++ ++ cmd->rx_msdu_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET, ++ tlv_filter->rx_msdu_end_offset); ++ cmd->rx_msdu_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET, ++ tlv_filter->rx_msdu_start_offset); ++ ++ cmd->rx_attn_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET, ++ tlv_filter->rx_attn_offset); ++ } ++ + 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 + } + + ring_id = dp->rxdma_mon_buf_ring.refill_buf_ring.ring_id; ++ tlv_filter.offset_valid = false; + + if (!reset) { + tlv_filter.rx_filter = HTT_RX_MON_FILTER_TLV_FLAGS_MON_BUF_RING; +--- a/drivers/net/wireless/ath/ath11k/hw.c ++++ b/drivers/net/wireless/ath/ath11k/hw.c +@@ -260,7 +260,11 @@ static u8 ath11k_hw_ipq8074_rx_desc_get_ + + static u8 *ath11k_hw_ipq8074_rx_desc_get_hdr_status(struct hal_rx_desc *desc) + { ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + return desc->u.ipq8074.hdr_status; ++#else ++ return NULL; ++#endif + } + + 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 + desc->u.ipq8074.msdu_start.info1 = __cpu_to_le32(info); + } + ++static ++struct rx_attention *ath11k_hw_ipq8074_rx_desc_get_attention(struct hal_rx_desc *desc) ++{ ++ return &desc->u.ipq8074.attention; ++} ++ ++static u8 *ath11k_hw_ipq8074_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) ++{ ++ return &desc->u.ipq8074.msdu_payload[0]; ++} ++ ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M ++static void ath11k_hw_ipq8074_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_ipq8074, mpdu_end_tag)); ++ tlv_filter->rx_mpdu_start_offset = __le16_to_cpu(offsetof ++ (struct hal_rx_desc_ipq8074, mpdu_start_tag)); ++ tlv_filter->rx_msdu_end_offset = __le16_to_cpu(offsetof ++ (struct hal_rx_desc_ipq8074, msdu_end_tag)); ++ tlv_filter->rx_msdu_start_offset = __le16_to_cpu(offsetof ++ (struct hal_rx_desc_ipq8074, msdu_start_tag)); ++ tlv_filter->rx_attn_offset = __le16_to_cpu(offsetof ++ (struct hal_rx_desc_ipq8074, rx_attn_tag)); ++} ++#endif ++ ++static u16 ath11k_hw_ipq8074_rx_desc_get_mpdu_frame_ctl(struct hal_rx_desc *desc) ++{ ++ return __le16_to_cpu(desc->u.ipq8074.mpdu_start.frame_ctrl); ++} ++ + static bool ath11k_hw_ipq8074_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) + { + return __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & + RX_MPDU_START_INFO1_MAC_ADDR2_VALID; + } + +-static u8 *ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) ++static u8* ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) + { + return desc->u.ipq8074.mpdu_start.addr2; + } + +-static +-struct rx_attention *ath11k_hw_ipq8074_rx_desc_get_attention(struct hal_rx_desc *desc) ++static bool ath11k_hw_ipq8074_rx_desc_dot11_hdr_fields_valid(struct hal_rx_desc *desc) + { +- return &desc->u.ipq8074.attention; ++ if ((ath11k_hw_ipq8074_rx_desc_get_mpdu_seq_ctl_vld(desc) && ++ ath11k_hw_ipq8074_rx_desc_get_mpdu_fc_valid(desc) && ++ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & ++ RX_MPDU_START_INFO1_MAC_ADDR1_VALID && ++ ath11k_hw_ipq8074_rx_desc_mac_addr2_valid(desc) && ++ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & ++ RX_MPDU_START_INFO1_MAC_ADDR3_VALID && ++ FIELD_GET((RX_MPDU_START_INFO1_MPDU_DUR_VALID), ++ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1)))) { ++ return true; ++ } ++ return false; ++} ++ ++static void ath11k_hw_ipq8074_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, ++ struct ieee80211_hdr *hdr) ++{ ++ hdr->frame_control = __le16_to_cpu(desc->u.ipq8074.mpdu_start.frame_ctrl); ++ hdr->duration_id = __le16_to_cpu(desc->u.ipq8074.mpdu_start.duration); ++ ether_addr_copy(hdr->addr1, desc->u.ipq8074.mpdu_start.addr1); ++ ether_addr_copy(hdr->addr2, desc->u.ipq8074.mpdu_start.addr2); ++ ether_addr_copy(hdr->addr3, desc->u.ipq8074.mpdu_start.addr3); ++ if (__le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & ++ RX_MPDU_START_INFO1_MAC_ADDR4_VALID) { ++ ether_addr_copy(hdr->addr4, desc->u.ipq8074.mpdu_start.addr4); ++ } ++ hdr->seq_ctrl = __le16_to_cpu(desc->u.ipq8074.mpdu_start.seq_ctrl); ++} ++ ++static void ath11k_hw_ipq8074_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.ipq8074.mpdu_start.pn[0]); ++ crypto_hdr[1] = 0; ++ crypto_hdr[2] = ++ HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.ipq8074.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.ipq8074.mpdu_start.pn[0]); ++ crypto_hdr[1] = ++ HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.ipq8074.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_INFO5_KEY_ID, ++ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info5)); ++ crypto_hdr[3] = 0x20 | (key_id << 6); ++ crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.ipq8074.mpdu_start.pn[0]); ++ crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.ipq8074.mpdu_start.pn[0]); ++ crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.ipq8074.mpdu_start.pn[1]); ++ crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.ipq8074.mpdu_start.pn[1]); + } + +-static u8 *ath11k_hw_ipq8074_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) ++static bool ath11k_hw_qcn9074_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) + { +- return &desc->u.ipq8074.msdu_payload[0]; ++ return __le32_to_cpu(desc->u.qcn9074.mpdu_start.info11) & ++ RX_MPDU_START_INFO11_MAC_ADDR2_VALID; ++} ++ ++static u8* ath11k_hw_qcn9074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) ++{ ++ return desc->u.qcn9074.mpdu_start.addr2; + } + + 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_ + + static u8 *ath11k_hw_qcn9074_rx_desc_get_hdr_status(struct hal_rx_desc *desc) + { ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + return desc->u.qcn9074.hdr_status; ++#else ++ return NULL; ++#endif + } + + 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_ + + static u8 *ath11k_hw_wcn6855_rx_desc_get_hdr_status(struct hal_rx_desc *desc) + { ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + return desc->u.wcn6855.hdr_status; ++#else ++ return NULL; ++#endif + } + + 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, + .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2, + .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, ++#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 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 = + .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, + .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, + }; + +--- a/drivers/net/wireless/ath/ath11k/hw.h ++++ b/drivers/net/wireless/ath/ath11k/hw.h +@@ -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 + #else + /* Num VDEVS per radio */ + #define TARGET_NUM_VDEVS(ab) (ab->hw_params.num_vdevs) +@@ -34,6 +39,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 ++#define ATH11K_DP_RXDMA_REFILL_RING_SIZE 2048 ++#define ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE 2048 + #endif + + /* Num of peers for Single Radio mode */ +@@ -129,6 +136,8 @@ 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]; +@@ -218,6 +227,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; +@@ -285,6 +295,16 @@ 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); ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M ++ void (*rx_desc_get_offset)(struct htt_rx_ring_tlv_filter *tlv_filter); ++#endif ++ u16 (*rx_desc_get_mpdu_frame_ctl)(struct hal_rx_desc *desc); ++ bool (*rx_desc_dot11_hdr_fields_valid)(struct hal_rx_desc *desc); ++ void (*rx_desc_get_dot11_hdr)(struct hal_rx_desc *desc, ++ struct ieee80211_hdr *hdr); ++ void (*rx_desc_get_crypto_header)(struct hal_rx_desc *desc, ++ u8 *crypto_hdr, ++ enum hal_encrypt_type enctype); + }; + + 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_ + tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar); + } + ++ tlv_filter.offset_valid = false; + 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 { + __le32 mpdu_end_tag; + struct rx_mpdu_end mpdu_end; + u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES]; ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + __le32 hdr_status_tag; + __le32 phy_ppdu_id; + u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN]; ++#endif + u8 msdu_payload[]; + } __packed; + +@@ -1461,9 +1463,11 @@ struct hal_rx_desc_qcn9074 { + __le32 mpdu_end_tag; + struct rx_mpdu_end mpdu_end; + u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES]; ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + __le32 hdr_status_tag; + __le32 phy_ppdu_id; + u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN]; ++#endif + u8 msdu_payload[]; + } __packed; + +@@ -1480,9 +1484,11 @@ struct hal_rx_desc_wcn6855 { + __le32 mpdu_end_tag; + struct rx_mpdu_end mpdu_end; + u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES]; ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + __le32 hdr_status_tag; + __le32 phy_ppdu_id; + u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN]; ++#endif + u8 msdu_payload[]; + } __packed; + +@@ -1502,4 +1508,17 @@ struct hal_rx_desc { + #define RU_484 18 + #define RU_996 37 + ++#define HAL_RX_MPDU_INFO_PN_GET_BYTE1(__val) \ ++ FIELD_GET(GENMASK(7, 0), __le32_to_cpu(__val)) ++ ++#define HAL_RX_MPDU_INFO_PN_GET_BYTE2(__val) \ ++ FIELD_GET(GENMASK(15, 8), __le32_to_cpu(__val)) ++ ++#define HAL_RX_MPDU_INFO_PN_GET_BYTE3(__val) \ ++ FIELD_GET(GENMASK(23, 16), __le32_to_cpu(__val)) ++ ++#define HAL_RX_MPDU_INFO_PN_GET_BYTE4(__val) \ ++ FIELD_GET(GENMASK(31, 24), __le32_to_cpu(__val)) ++ ++ + #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 + + /* fill rx parameters to initialize rx context */ + wim->wrip.tlv_size = ab->hw_params.hal_desc_sz; +- wim->wrip.rx_buf_len = DP_RX_BUFFER_SIZE; ++ wim->wrip.rx_buf_len = DP_RXDMA_NSS_REFILL_RING_SIZE; + + /* fill hal srng message */ + wim->hssm.dev_base_addr = (u32)ab->mem_pa; 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 new file mode 100644 index 00000000000000..08e158a407ca8f --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/234-001-ath11k-account-tx-rx-packets-flow.patch @@ -0,0 +1,494 @@ +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 new file mode 100644 index 00000000000000..7488f0c2bfce6b --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/234-002-mac80211-account-tx-rx-packets-flow.patch @@ -0,0 +1,369 @@ +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 new file mode 100644 index 00000000000000..a95308a74ed223 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/235-001-ath11k-Add-support-for-beacon-tx-mode.patch @@ -0,0 +1,45 @@ +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 +@@ -3483,7 +3483,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) +@@ -3491,8 +3494,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 new file mode 100644 index 00000000000000..6fb460f6b4f740 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/235-002-mac80211-Add-support-for-beacon-tx-mode.patch @@ -0,0 +1,159 @@ +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 new file mode 100644 index 00000000000000..83c019b871e81b --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/237-002-ath11k-Add-provision-to-configure-rx-hashmap.patch @@ -0,0 +1,208 @@ +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/237-003-ath11k-allocate-dst-ring-descriptors-from-cacheable-.patch b/package/kernel/mac80211/patches/ath11k_nss/237-003-ath11k-allocate-dst-ring-descriptors-from-cacheable-.patch new file mode 100644 index 00000000000000..c054ee146f748a --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/237-003-ath11k-allocate-dst-ring-descriptors-from-cacheable-.patch @@ -0,0 +1,147 @@ +From 61342ee83df7fa0b90d5ece88e3f83dea426802c Mon Sep 17 00:00:00 2001 +From: P Praneesh +Date: Mon, 14 Dec 2020 20:22:22 +0530 +Subject: [PATCH] ath11k: allocate dst ring descriptors from cacheable + memory + +tcl_data and reo_dst rings are currently being allocated +using dma_allocate_coherent() which is non cachable. + +Allocating ring memory from cacheable memory area +allows cached descriptor access and prefetch next +descriptors to optimize CPU usage during +descriptor processing on NAPI. + +Signed-off-by: Pradeep Kumar Chitrapu +Signed-off-by: Sriram R +Signed-off-by: P Praneesh +--- + drivers/net/wireless/ath/ath11k/dp.c | 39 ++++++++++++++++++++++++++++++----- + drivers/net/wireless/ath/ath11k/dp.h | 1 + + drivers/net/wireless/ath/ath11k/hal.c | 33 ++++++++++++++++++++++++++--- + drivers/net/wireless/ath/ath11k/hal.h | 1 + + 4 files changed, 66 insertions(+), 8 deletions(-) + +--- 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 + struct sk_buff *msdu; + struct hal_tx_status ts = { 0 }; + struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id]; ++ int valid_entries; + u32 *desc; + u32 msdu_id; + u8 mac_id; +@@ -713,9 +714,18 @@ void ath11k_dp_tx_completion_handler(str + + ath11k_hal_srng_access_begin(ab, status_ring); + ++ valid_entries = ath11k_hal_srng_dst_num_free(ab, status_ring, false); ++ if (!valid_entries) { ++ ath11k_hal_srng_access_end(ab, status_ring); ++ spin_unlock_bh(&status_ring->lock); ++ return; ++ } ++ ++ ath11k_hal_srng_dst_invalidate_entry(ab, status_ring, valid_entries); ++ + while ((ATH11K_TX_COMPL_NEXT(tx_ring->tx_status_head) != + tx_ring->tx_status_tail) && +- (desc = ath11k_hal_srng_dst_get_next_entry(ab, status_ring))) { ++ (desc = ath11k_hal_srng_dst_get_next_cache_entry(ab, status_ring))) { + memcpy(&tx_ring->tx_status[tx_ring->tx_status_head], + desc, sizeof(struct hal_wbm_release_ring)); + tx_ring->tx_status_head = +--- a/drivers/net/wireless/ath/ath11k/hal.c ++++ b/drivers/net/wireless/ath/ath11k/hal.c +@@ -653,7 +653,8 @@ u32 *ath11k_hal_srng_dst_get_next_entry( + + desc = srng->ring_base_vaddr + srng->u.dst_ring.tp; + +- srng->u.dst_ring.tp += srng->entry_size; ++ srng->u.dst_ring.tp = (srng->u.dst_ring.tp + srng->entry_size) % ++ srng->ring_size; + + /* wrap around to start of ring*/ + if (srng->u.dst_ring.tp == srng->ring_size) +@@ -666,8 +667,63 @@ u32 *ath11k_hal_srng_dst_get_next_entry( + return desc; + } + ++u32 *ath11k_hal_srng_dst_get_next_cache_entry(struct ath11k_base *ab, ++ struct hal_srng *srng) ++{ ++ u32 *desc,*desc_next; ++ lockdep_assert_held(&srng->lock); ++ ++ if (srng->u.dst_ring.tp == srng->u.dst_ring.cached_hp) ++ return NULL; ++ ++ desc = srng->ring_base_vaddr + srng->u.dst_ring.tp; ++ ++ srng->u.dst_ring.tp = (srng->u.dst_ring.tp + srng->entry_size) % ++ srng->ring_size; ++ ++ /* Try to prefetch the next descriptor in the ring */ ++ if (srng->u.dst_ring.tp != srng->u.dst_ring.cached_hp) { ++ /* prefetch only if desc is available */ ++ desc_next = srng->ring_base_vaddr + srng->u.dst_ring.tp; ++ prefetch(desc_next); ++ } ++ return desc; ++} ++ ++void ath11k_hal_srng_dst_invalidate_entry(struct ath11k_base *ab, ++ struct hal_srng *srng, int entries) ++{ ++ u32 *desc; ++ u32 tp, hp; ++ ++ lockdep_assert_held(&srng->lock); ++ ++ if (!(srng->flags & HAL_SRNG_FLAGS_CACHED) || !entries) ++ return; ++ ++ tp = srng->u.dst_ring.tp; ++ hp = srng->u.dst_ring.cached_hp; ++ ++ desc = srng->ring_base_vaddr + tp; ++ if (hp > tp) { ++ dma_sync_single_for_cpu(ab->dev, virt_to_phys(desc), ++ entries * srng->entry_size * sizeof(u32), ++ DMA_FROM_DEVICE); ++ } else { ++ entries = srng->ring_size - tp; ++ dma_sync_single_for_cpu(ab->dev, virt_to_phys(desc), ++ entries * sizeof(u32), ++ DMA_FROM_DEVICE); ++ ++ entries = hp; ++ dma_sync_single_for_cpu(ab->dev, virt_to_phys(srng->ring_base_vaddr), ++ entries * sizeof(u32), ++ DMA_FROM_DEVICE); ++ } ++} ++ + int ath11k_hal_srng_dst_num_free(struct ath11k_base *ab, struct hal_srng *srng, +- bool sync_hw_ptr) ++ bool sync_hw_ptr) + { + u32 tp, hp; + +--- 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 + 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); ++u32 *ath11k_hal_srng_dst_get_next_cache_entry(struct ath11k_base *ab, ++ struct hal_srng *srng); + int ath11k_hal_srng_dst_num_free(struct ath11k_base *ab, struct hal_srng *srng, +- bool sync_hw_ptr); ++ bool sync_hw_ptr); ++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); + u32 *ath11k_hal_srng_src_get_next_reaped(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/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch new file mode 100644 index 00000000000000..bb46abada6b9e3 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch @@ -0,0 +1,412 @@ +From 594992a7ef169aa406e7fc025df2455af5d226be Mon Sep 17 00:00:00 2001 +From: P Praneesh +Date: Tue, 15 Dec 2020 10:31:30 +0530 +Subject: [PATCH] ath11k: Allow fast rx by bypassing stats update + +Add a provision to disable stats and enable fast rx support +for a peer when it is connected to an AP with ethernet decap support. +All valid IP packets are directly passed to the net core stack +bypassing mac80211 stats update + +Signed-off-by: Sriram R +Signed-off-by: P Praneesh +--- + drivers/net/wireless/ath/ath11k/core.h | 3 ++ + drivers/net/wireless/ath/ath11k/debugfs.c | 76 +++++++++++++++++++++++++++++++++ + drivers/net/wireless/ath/ath11k/dp.c | 45 +++++++++++++++++++ + drivers/net/wireless/ath/ath11k/dp_rx.c | 54 ++++++++++++++++++++--- + drivers/net/wireless/ath/ath11k/hw.c | 25 +++++++++++ + drivers/net/wireless/ath/ath11k/hw.h | 1 + + drivers/net/wireless/ath/ath11k/mac.c | 2 + + drivers/net/wireless/ath/ath11k/peer.h | 1 + + 8 files changed, 201 insertions(+), 6 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -135,6 +135,7 @@ struct ath11k_skb_rxcb { + u8 tid; + u16 peer_id; + u16 seq_no; ++ struct napi_struct *napi; + }; + + 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 + return -ETIMEDOUT; + } + ++static inline u8 ath11k_dp_rx_h_msdu_start_ip_valid(struct ath11k_base *ab, ++ struct hal_rx_desc *desc) ++{ ++ return ab->hw_params.hw_ops->rx_desc_get_ip_valid(desc); ++} ++ + /* 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 + return peer; + } + ++static bool ath11k_dp_rx_check_fast_rx(struct ath11k *ar, ++ struct sk_buff *msdu, ++ struct hal_rx_desc *rx_desc, ++ struct ath11k_peer *peer) ++{ ++ struct ethhdr *ehdr; ++ struct ath11k_peer *f_peer; ++ struct ath11k_skb_rxcb *rxcb; ++ u8 decap; ++ ++ lockdep_assert_held(&ar->ab->base_lock); ++ ++ decap = ath11k_dp_rx_h_msdu_start_decap_type(ar->ab, rx_desc); ++ rxcb = ATH11K_SKB_RXCB(msdu); ++ ++ if (!ar->ab->stats_disable || ++ decap != DP_RX_DECAP_TYPE_ETHERNET2_DIX || ++ peer->vif->type != NL80211_IFTYPE_AP) ++ return false; ++ ++ /* mcbc packets go through mac80211 for PN validation */ ++ if (rxcb->is_mcbc) ++ return false; ++ ++ if (!peer->is_authorized) ++ return false; ++ ++ if (!ath11k_dp_rx_h_msdu_start_ip_valid(ar->ab, rx_desc)) ++ return false; ++ ++ /* fast rx is supported only on ethernet decap, so ++ * we can directly gfet the ethernet header ++ */ ++ ehdr = (struct ethhdr *)msdu->data; ++ ++ /* requires rebroadcast from mac80211 */ ++ if (is_multicast_ether_addr(ehdr->h_dest)) ++ return false; ++ ++ /* check if the msdu needs to be bridged to our connected peer */ ++ f_peer = ath11k_peer_find_by_addr(ar->ab, ehdr->h_dest); ++ ++ if (f_peer && f_peer != peer) ++ return false; ++ ++ /* allow direct rx */ ++ return true; ++} ++ + static void ath11k_dp_rx_h_mpdu(struct ath11k *ar, + struct sk_buff *msdu, + struct hal_rx_desc *rx_desc, +- struct ieee80211_rx_status *rx_status) ++ struct ieee80211_rx_status *rx_status, ++ bool *fast_rx) + { + bool fill_crypto_hdr; + enum hal_encrypt_type enctype; +@@ -2417,6 +2473,9 @@ static void ath11k_dp_rx_h_mpdu(struct a + 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 + spin_lock_bh(&ar->ab->base_lock); + peer = ath11k_dp_rx_h_find_peer(ar->ab, msdu); + if (peer) { ++ /* If the pkt is a valid IP packet and peer supports ++ * fast rx, deliver directly to net, also note that ++ * pkts with crypto error are not expected to arrive in this ++ * path, so its safe to skip checking errors here */ ++ if (*fast_rx && ++ ath11k_dp_rx_check_fast_rx(ar, msdu, rx_desc, peer)) { ++ wdev = ieee80211_vif_to_wdev(peer->vif); ++ if (wdev) { ++ spin_unlock_bh(&ar->ab->base_lock); ++ ath11k_dp_rx_h_csum_offload(ar, msdu); ++ msdu->dev = wdev->netdev; ++ msdu->protocol = eth_type_trans(msdu, msdu->dev); ++ napi_gro_receive(rxcb->napi, msdu); ++ 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 + static int ath11k_dp_rx_process_msdu(struct ath11k *ar, + struct sk_buff *msdu, + struct sk_buff_head *msdu_list, +- struct ieee80211_rx_status *rx_status) ++ struct ieee80211_rx_status *rx_status, ++ bool *fast_rx) + { + 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 + } + } + ++ ath11k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_status, fast_rx); ++ if (*fast_rx) { ++ ab->soc_stats.invalid_rbm++; ++ return 0; ++ } ++ + ath11k_dp_rx_h_ppdu(ar, rx_desc, rx_status); +- ath11k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_status); + + rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; + +@@ -2791,10 +2880,12 @@ static void ath11k_dp_rx_process_receive + struct sk_buff_head *msdu_list, + int mac_id) + { ++ struct ath11k_skb_rxcb *rxcb; + struct sk_buff *msdu; + struct ath11k *ar; + struct ieee80211_rx_status rx_status = {0}; + int ret; ++ bool fast_rx; + + if (skb_queue_empty(msdu_list)) + return; +@@ -2811,7 +2902,12 @@ static void ath11k_dp_rx_process_receive + } + + while ((msdu = __skb_dequeue(msdu_list))) { +- ret = ath11k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_status); ++ rxcb = ATH11K_SKB_RXCB(msdu); ++ /* Enable fast rx by default, the value will cahnge based on peer cap ++ * and packet type */ ++ fast_rx = true; ++ rxcb->napi = napi; ++ ret = ath11k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_status, &fast_rx); + 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 + continue; + } + +- ath11k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_status); ++ /* msdu is already delivered directectly */ ++ if (!fast_rx) ++ ath11k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_status); ++ + } + } + +@@ -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; ++ 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 + } + ath11k_dp_rx_h_ppdu(ar, desc, status); + +- ath11k_dp_rx_h_mpdu(ar, msdu, desc, status); ++ fast_rx = false; ++ ath11k_dp_rx_h_mpdu(ar, msdu, desc, status, &fast_rx); + + rxcb->tid = ath11k_dp_rx_h_mpdu_start_tid(ar->ab, desc); + +--- 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 + __le32_to_cpu(desc->u.ipq8074.msdu_start.info2)); + } + ++static u8 ath11k_hw_ipq8074_rx_desc_get_ip_valid(struct hal_rx_desc *desc) ++{ ++ bool ipv4, ipv6; ++ ipv4 = FIELD_GET(RX_MSDU_START_INFO2_IPV4, ++ __le32_to_cpu(desc->u.ipq8074.msdu_start.info2)); ++ ipv6 = FIELD_GET(RX_MSDU_START_INFO2_IPV6, ++ __le32_to_cpu(desc->u.ipq8074.msdu_start.info2)); ++ return (ipv4 || ipv6); ++} ++ + 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 + __le32_to_cpu(desc->u.qcn9074.msdu_start.info2)); + } + ++static u8 ath11k_hw_qcn9074_rx_desc_get_ip_valid(struct hal_rx_desc *desc) ++{ ++ bool ipv4 , ipv6; ++ ipv4 = FIELD_GET(RX_MSDU_START_INFO2_IPV4, ++ __le32_to_cpu(desc->u.qcn9074.msdu_start.info2)); ++ ipv6 = FIELD_GET(RX_MSDU_START_INFO2_IPV6, ++ __le32_to_cpu(desc->u.qcn9074.msdu_start.info2)); ++ return (ipv4 || ipv6); ++} ++ + 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 = + .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, +@@ -1293,6 +1314,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, ++ .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, +--- a/drivers/net/wireless/ath/ath11k/hw.h ++++ b/drivers/net/wireless/ath/ath11k/hw.h +@@ -270,6 +270,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); ++ u8 (*rx_desc_get_ip_valid)(struct hal_rx_desc *desc); + bool (*rx_desc_get_ldpc_support)(struct hal_rx_desc *desc); + bool (*rx_desc_get_mpdu_seq_ctl_vld)(struct hal_rx_desc *desc); + 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 +@@ -5197,6 +5197,14 @@ static int ath11k_mac_op_sta_state(struc + } + } 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); diff --git a/package/kernel/mac80211/patches/ath11k_nss/245-compilation_fix.patch b/package/kernel/mac80211/patches/ath11k_nss/245-compilation_fix.patch new file mode 100644 index 00000000000000..b4a735f10fc0e6 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/245-compilation_fix.patch @@ -0,0 +1,192 @@ +From 9cdb8bae50aca80b593d0f53be5b8efedfc91324 Mon Sep 17 00:00:00 2001 +From: Tamizh Chelvam +Date: Sun, 7 Mar 2021 22:49:26 +0530 +Subject: [PATCH] backport: Compile fix + +Adding these changes to fix compilation issue due to +package upgrade + +Signed-off-by: Tamizh Chelvam +Signed-off-by: Gautham Kumar Senthilkumaran +--- + include/linux/backport-refcount.h | 4 +-- + include/net/fq.h | 10 +++++- + net/mac80211/cfg.c | 4 +-- + net/mac80211/ieee80211_i.h | 4 ++- + net/mac80211/iface.c | 2 -- + net/mac80211/rx.c | 23 +++++++++----- + 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 { + }; + + struct ieee80211_rx_data { ++ struct napi_struct *napi; + 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 + + ieee80211_aggr_check(sdata, sta, skb); + +- tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; +- tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); +- if (tid_tx) { +- if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) { +- /* fall back to non-offload slow path */ +- __ieee80211_subif_start_xmit(skb, dev, 0, +- IEEE80211_TX_CTRL_MLO_LINK_UNSPEC, +- NULL); +- return; +- } ++ if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) { ++ tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; ++ tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); ++ if (tid_tx) { ++ if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) { ++ /* fall back to non-offload slow path */ ++ __ieee80211_subif_start_xmit(skb, dev, 0, ++ IEEE80211_TX_CTRL_MLO_LINK_UNSPEC, ++ NULL); ++ return; ++ } + +- if (tid_tx->timeout) +- tid_tx->last_tx = jiffies; ++ if (tid_tx->timeout) ++ tid_tx->last_tx = jiffies; ++ } + } + + skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); +@@ -4739,7 +4741,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; +- struct ieee80211_key *key; ++ struct ieee80211_key *key = NULL; + struct sta_info *sta; + + #ifdef CPTCFG_MAC80211_NSS_SUPPORT +@@ -4757,9 +4759,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 + goto out; + } + +- if (unlikely(IS_ERR_OR_NULL(sta) || !sta->uploaded || +- !test_sta_flag(sta, WLAN_STA_AUTHORIZED) || +- sdata->control_port_protocol == ehdr->h_proto)) ++ if (ieee80211_hw_check(&sdata->local->hw, SUPPORTS_NSS_OFFLOAD)) { ++ if (unlikely(IS_ERR_OR_NULL(sta) || !sta->uploaded)) ++ sta = NULL; ++ goto tx_offload; ++ } else if (unlikely(IS_ERR_OR_NULL(sta) || !sta->uploaded || ++ !test_sta_flag(sta, WLAN_STA_AUTHORIZED) || ++ sdata->control_port_protocol == ehdr->h_proto)) + goto skip_offload; + + key = rcu_dereference(sta->ptk[sta->ptk_idx]); +@@ -4770,6 +4776,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); ++tx_offload: + 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_ + + 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)); +- + /* + * 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); +- +- 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); 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 new file mode 100644 index 00000000000000..6f7c1aadd95b64 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/245-revert-dev-sw-netstats-txrx-add.patch @@ -0,0 +1,145 @@ +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/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch b/package/kernel/mac80211/patches/ath11k_nss/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch new file mode 100644 index 00000000000000..0a7dcf5e845780 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch @@ -0,0 +1,109 @@ +From 246e530a47d9adab9106fb6f2b92197cace17e53 Mon Sep 17 00:00:00 2001 +From: Seevalamuthu Mariappan +Date: Fri, 21 May 2021 14:16:22 +0530 +Subject: [PATCH] ath11k: configure nss radio priority during pdev_init + +pdev's priority value is read from dts. Get scheme_id +using pdev priority. Configure scheme_id during pdev_init. + +Signed-off-by: Seevalamuthu Mariappan +--- + drivers/net/wireless/ath/ath11k/nss.c | 20 +++++++++++++++++++- + drivers/net/wireless/ath/ath11k/nss.h | 3 +++ + 2 files changed, 22 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath11k/nss.c ++++ b/drivers/net/wireless/ath/ath11k/nss.c +@@ -2,6 +2,7 @@ + /* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + */ ++#include + + #include "debug.h" + #include "mac.h" +@@ -1782,6 +1783,7 @@ static int ath11k_nss_init(struct ath11k + nss_tx_status_t status; + struct ath11k_dp *dp; + int i, ret; ++ struct device *dev = ab->dev; + + dp = &ab->dp; + +@@ -1801,6 +1803,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; ++ if (of_property_read_bool(dev->of_node, "nss-radio-priority")) ++ wim->flags |= WIFILI_MULTISOC_THREAD_MAP_ENABLE; + + /* 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 + struct nss_wifili_msg *wlmsg = NULL; + nss_wifili_msg_callback_t msg_cb; + nss_tx_status_t status; ++ struct device *dev = ab->dev; + int radio_if_num = -1; + int refill_ring_id; + int features = 0; + int dyn_if_type; +- int ret, i; ++ int ret, i, scheme_id = 0; ++ u32 nss_radio_priority; + + dyn_if_type = ath11k_nss_get_dynamic_interface_type(ab); + +@@ -2010,6 +2016,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); + ++ if (!of_property_read_u32(dev->of_node, "nss-radio-priority", &nss_radio_priority)) { ++ scheme_id = nss_wifili_thread_scheme_alloc(ab->nss.ctx, ar->nss.if_num, nss_radio_priority); ++ if (scheme_id == WIFILI_SCHEME_ID_INVALID) { ++ ath11k_warn(ab, "received invalid scheme_id, configuring default value\n"); ++ scheme_id = 0; ++ } ++ } ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "ifnum: %d scheme_id: %d nss_radio_priority: %d\n", ar->nss.if_num, scheme_id, nss_radio_priority); ++ + 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 + 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; ++ pdevmsg->scheme_id = scheme_id; + + /* 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 + /* pdev deinit msg success, dealloc, deregister and return */ + ret = 0; + ++ /* reset thread scheme*/ ++ nss_wifili_thread_scheme_dealloc(ab->nss.ctx, ar->nss.if_num); ++ + nss_dynamic_interface_dealloc_node(ar->nss.if_num, dyn_if_type); + nss_unregister_wifili_radio_if(ar->nss.if_num); + 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; + /* Init Flags */ + #define WIFILI_NSS_CCE_DISABLED 0x1 + #define WIFILI_ADDTL_MEM_SEG_SET 0x000000002 ++#define WIFILI_MULTISOC_THREAD_MAP_ENABLE 0x10 + + /* 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, + }; + ++#define WIFILI_SCHEME_ID_INVALID -1 ++ + enum ath11k_nss_opmode { + ATH11K_NSS_OPMODE_UNKNOWN, + ATH11K_NSS_OPMODE_AP, diff --git a/package/kernel/mac80211/patches/ath11k_nss/318-ath11k-avoid-stack-corrupt-in-nwifi-undecap.patch b/package/kernel/mac80211/patches/ath11k_nss/318-ath11k-avoid-stack-corrupt-in-nwifi-undecap.patch new file mode 100644 index 00000000000000..9189729b77f595 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/318-ath11k-avoid-stack-corrupt-in-nwifi-undecap.patch @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/ath/ath11k/dp_rx.h ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.h +@@ -9,7 +9,7 @@ + #include "rx_desc.h" + #include "debug.h" + +-#define DP_MAX_NWIFI_HDR_LEN 30 ++#define DP_MAX_NWIFI_HDR_LEN 36 + + #define DP_RX_MPDU_ERR_FCS BIT(0) + #define DP_RX_MPDU_ERR_DECRYPT BIT(1) 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/ath11k_nss/319-ath11k-fix-double-free-of-peer-rx_tid-during-reo-cmd.patch new file mode 100644 index 00000000000000..7ea6b471e340aa --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/319-ath11k-fix-double-free-of-peer-rx_tid-during-reo-cmd.patch @@ -0,0 +1,40 @@ +From 210b20357989ace8bb5c861b37e25b6c986c816d Mon Sep 17 00:00:00 2001 +From: Sathishkumar Muruganandam +Date: Thu, 1 Jul 2021 13:08:54 +0530 +Subject: [PATCH] ath11k: fix double free of peer rx_tid during reo cmd failure + +Peer rx_tid is locally copied thrice during peer_rx_tid_cleanup to send +REO_CMD_UPDATE_RX_QUEUE followed by REO_CMD_FLUSH_CACHE to flush all +aged REO descriptors from HW cache. + +When sending REO_CMD_FLUSH_CACHE fails, we do dma unmap of already +mapped rx_tid->vaddr and free it. This is not checked during +reo_cmd_list_cleanup() and dp_reo_cmd_free() before trying to free and +unmap again. + +Fix this by setting rx_tid->vaddr NULL in rx tid delete and also wherever +freeing it to check in reo_cmd_list_cleanup() and reo_cmd_free() before +trying to free again. + +Prevent REO cmd failures causing double free by increasing REO cmd +ring size and moving REO status ring mask to IRQ group 3 from group +0 to separate from tx completion ring on IRQ group 0 which may delay +reo status processing. + +Signed-off-by: Sathishkumar Muruganandam +--- + drivers/net/wireless/ath/ath11k/dp.h | 2 +- + drivers/net/wireless/ath/ath11k/dp_rx.c | 66 ++++++++++++++++++------- + drivers/net/wireless/ath/ath11k/hw.c | 1 + + 3 files changed, 49 insertions(+), 20 deletions(-) + +--- 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_ + ATH11K_RX_WBM_REL_RING_MASK_0, + }, + .reo_status = { ++ 0, 0, 0, + ATH11K_REO_STATUS_RING_MASK_0, + }, + .rxdma2host = { diff --git a/package/kernel/mac80211/patches/ath11k_nss/335-0005-mac80211-simple-tx-for-AP-mode.patch b/package/kernel/mac80211/patches/ath11k_nss/335-0005-mac80211-simple-tx-for-AP-mode.patch new file mode 100644 index 00000000000000..d859d038003196 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/335-0005-mac80211-simple-tx-for-AP-mode.patch @@ -0,0 +1,99 @@ +From 190652ce1b56a41ed3a99d9f9c9160deba34810b Mon Sep 17 00:00:00 2001 +From: Venkateswara Naralasetty +Date: Thu, 18 Nov 2021 12:28:31 +0530 +Subject: [PATCH] mac80211: simple tx for AP mode + +Introduced new API ieee80211_8023_xmit_ap to make tx simple and +to avoid unnecessary checks for AP mode. + +Signed-off-by: Venkateswara Naralasetty +Signed-off-by: Aloka Dixit +--- + net/mac80211/tx.c | 40 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 40 insertions(+) + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -4748,6 +4748,70 @@ out_free: + kfree_skb(skb); + } + ++void ieee80211_8023_xmit_ap(struct ieee80211_sub_if_data *sdata, ++ struct net_device *dev, struct sta_info *sta, ++ struct ieee80211_key *key, struct sk_buff *skb) ++{ ++ struct ieee80211_tx_info *info; ++ struct ieee80211_local *local = sdata->local; ++ struct ieee80211_sta *pubsta = NULL; ++ struct ieee80211_tx_control control = {}; ++ unsigned long flags; ++ int q; ++ u16 q_map; ++ ++ /* ++ * If the skb is shared we need to obtain our own copy. ++ */ ++ skb = skb_share_check(skb, GFP_ATOMIC); ++ ++ if (unlikely(!skb)) ++ return; ++ ++ info = IEEE80211_SKB_CB(skb); ++ memset(info, 0, sizeof(*info)); ++ ++ if (unlikely(skb->sk && ++ skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) ++ info->ack_frame_id = ieee80211_store_ack_skb(local, skb, ++ &info->flags, NULL); ++ ++ info->flags |= IEEE80211_TX_CTL_HW_80211_ENCAP; ++ info->control.vif = &sdata->vif; ++ ++ if (key) ++ info->control.hw_key = &key->conf; ++ ++ q_map = skb_get_queue_mapping(skb); ++ q = sdata->vif.hw_queue[q_map]; ++ ++ 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); ++ ++ if (local->queue_stop_reasons[q] || !skb_queue_empty(&local->pending[q])) { ++ skb_queue_tail(&local->pending[q], skb); ++ spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); ++ return; ++ } ++ ++ spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); ++ ++ if (sta && sta->uploaded) ++ pubsta = &sta->sta; ++ ++ control.sta = pubsta; ++ ++ 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 + if (key && (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))) + goto skip_offload; + ++ if (sdata->vif.type == NL80211_IFTYPE_AP) { ++ ieee80211_8023_xmit_ap(sdata, dev, sta, key, skb); ++ goto out; ++ } ++ + sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift); + tx_offload: + ieee80211_8023_xmit(sdata, dev, sta, key, skb); diff --git a/package/kernel/mac80211/patches/ath11k_nss/336-ath11k-skip-status-ring-entry-processing.patch b/package/kernel/mac80211/patches/ath11k_nss/336-ath11k-skip-status-ring-entry-processing.patch new file mode 100644 index 00000000000000..2e874d321d0ad1 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/336-ath11k-skip-status-ring-entry-processing.patch @@ -0,0 +1,191 @@ +From 0e79fe8c6937e080816230892d5382af5a5a86c6 Mon Sep 17 00:00:00 2001 +From: Venkateswara Naralasetty +Date: Mon, 29 Nov 2021 11:07:53 +0530 +Subject: [PATCH] ath11k: skip status ring entry processing + +If STATUS_BUFFER_DONE is not set for a monitor status ring entry, +we don't process the status ring until STATUS_BUFFER_DONE set +for that status ring entry. + +During LMAC reset it may happnen that HW will not write +STATUS_BUFFER_DONE tlv in status buffer, in that case we end up +waiting for STATUS_BUFFER_DONE leading to backpressure on monitor +status ring. + +As per MAC team's suggestion, when HP + 1 entry is peeked and if DMA +is not done and if HP + 2 entry's DMA done is set, +replenish HP + 1 entry and start processing in next interrupt. +If HP + 2 entry's DMA done is not set, +poll onto HP + 1 entry DMA done to be set. + +Also, During monitor attach HP points to the end of the ring and TP +points to the start of the ring. Using ath11k_hal_srng_src_peek() +may result in processing invali buffer for the very first interrupt. +Since, HW starts writing buffer from TP. + +Hence, replaced ath11k_hal_srng_src_peek() with +ath11k_hal_srng_src_next_peek(). + +Signed-off-by: Venkateswara Naralasetty +--- + drivers/net/wireless/ath/ath11k/dp_rx.c | 92 ++++++++++++++++++++++++++++----- + drivers/net/wireless/ath/ath11k/hal.c | 30 +++++++++++ + drivers/net/wireless/ath/ath11k/hal.h | 4 ++ + 3 files changed, 113 insertions(+), 13 deletions(-) + +--- 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 + } + } + ++enum dp_mon_status_buf_state ++dp_rx_mon_handle_status_buf_done(struct ath11k_base *ab, struct hal_srng *srng, ++ struct dp_rxdma_ring *rx_ring) ++{ ++ void *status_desc; ++ struct sk_buff *skb; ++ struct ath11k_skb_rxcb *rxcb; ++ struct hal_tlv_hdr *tlv; ++ dma_addr_t paddr; ++ u32 cookie; ++ int buf_id; ++ u8 rbm; ++ ++ status_desc = ath11k_hal_srng_src_next_peek(ab, srng); ++ if (!status_desc) ++ return DP_MON_STATUS_NO_DMA; ++ ++ ath11k_hal_rx_buf_addr_info_get(status_desc, &paddr, &cookie, &rbm); ++ ++ buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID, cookie); ++ ++ spin_lock_bh(&rx_ring->idr_lock); ++ skb = idr_find(&rx_ring->bufs_idr, buf_id); ++ spin_unlock_bh(&rx_ring->idr_lock); ++ ++ if (!skb) ++ return DP_MON_STATUS_NO_DMA; ++ ++ rxcb = ATH11K_SKB_RXCB(skb); ++ dma_sync_single_for_cpu(ab->dev, rxcb->paddr, ++ skb->len + skb_tailroom(skb), ++ DMA_FROM_DEVICE); ++ ++ tlv = (struct hal_tlv_hdr *)skb->data; ++ if (FIELD_GET(HAL_TLV_HDR_TAG, tlv->tl) != HAL_RX_STATUS_BUFFER_DONE) ++ return DP_MON_STATUS_NO_DMA; ++ ++ return DP_MON_STATUS_REPLINISH; ++} ++ + 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_ + struct sk_buff *skb; + struct ath11k_skb_rxcb *rxcb; + struct hal_tlv_hdr *tlv; ++ enum dp_mon_status_buf_state reap_status; + u32 cookie; + int buf_id, srng_id; + dma_addr_t paddr; +@@ -3328,8 +3369,7 @@ static int ath11k_dp_rx_reap_mon_status_ + ath11k_hal_srng_access_begin(ab, srng); + while (*budget) { + *budget -= 1; +- rx_mon_status_desc = +- ath11k_hal_srng_src_peek(ab, srng); ++ rx_mon_status_desc = ath11k_hal_srng_src_peek(ab, srng); + 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_ + tlv = (struct hal_tlv_hdr *)skb->data; + if (FIELD_GET(HAL_TLV_HDR_TAG, tlv->tl) != + HAL_RX_STATUS_BUFFER_DONE) { +- ath11k_warn(ab, "mon status DONE not set %lx, buf_id %d\n", +- FIELD_GET(HAL_TLV_HDR_TAG, +- tlv->tl), buf_id); +- /* If done status is missing, hold onto status +- * ring until status is done for this status +- * ring buffer. +- * Keep HP in mon_status_ring unchanged, +- * and break from here. +- * Check status for same buffer for next time ++ /* RxDMA status done bit might not be set even ++ * though tp is moved by HW. + */ +- pmon->buf_state = DP_MON_STATUS_NO_DMA; +- break; ++ ++ /* If done status is missing: ++ * 1. As per MAC team's suggestion, ++ * when HP + 1 entry is peeked and if DMA ++ * is not done and if HP + 2 entry's DMA done ++ * is set. skip HP + 1 entry and ++ * start processing in next interrupt. ++ * 2. If HP + 2 entry's DMA done is not set, ++ * poll onto HP + 1 entry DMA done to be set. ++ * Check status for same buffer for next time ++ * dp_rx_mon_status_srng_process ++ */ ++ ++ reap_status = dp_rx_mon_handle_status_buf_done(ab, srng, ++ rx_ring); ++ if (reap_status == DP_MON_STATUS_NO_DMA) { ++ continue; ++ } else if (reap_status == DP_MON_STATUS_REPLINISH) { ++ ath11k_warn(ab, "mon status DONE not set %lx, buf_id %d\n", ++ FIELD_GET(HAL_TLV_HDR_TAG, tlv->tl), ++ buf_id); ++ ++ spin_lock_bh(&rx_ring->idr_lock); ++ idr_remove(&rx_ring->bufs_idr, buf_id); ++ spin_unlock_bh(&rx_ring->idr_lock); ++ ++ dma_unmap_single(ab->dev, rxcb->paddr, ++ skb->len + skb_tailroom(skb), ++ DMA_FROM_DEVICE); ++ ++ dev_kfree_skb_any(skb); ++ pmon->buf_state = DP_MON_STATUS_REPLINISH; ++ goto move_next; ++ } + } + + spin_lock_bh(&rx_ring->idr_lock); +--- a/drivers/net/wireless/ath/ath11k/hal.c ++++ b/drivers/net/wireless/ath/ath11k/hal.c +@@ -837,6 +837,20 @@ u32 *ath11k_hal_srng_src_get_next_reaped + return desc; + } + ++u32 *ath11k_hal_srng_src_next_peek(struct ath11k_base *ab, struct hal_srng *srng) ++{ ++ u32 next_hp; ++ ++ lockdep_assert_held(&srng->lock); ++ ++ next_hp = (srng->u.src_ring.hp + srng->entry_size) % srng->ring_size; ++ ++ if (next_hp != srng->u.src_ring.cached_tp) ++ return srng->ring_base_vaddr + next_hp; ++ ++ return NULL; ++} ++ + u32 *ath11k_hal_srng_src_peek(struct ath11k_base *ab, struct hal_srng *srng) + { + 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 + 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); ++u32 *ath11k_hal_srng_src_next_peek(struct ath11k_base *ab, ++ struct hal_srng *srng); + u32 *ath11k_hal_srng_src_get_next_reaped(struct ath11k_base *ab, + struct hal_srng *srng); + u32 *ath11k_hal_srng_src_reap_next(struct ath11k_base *ab, 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/ath11k_nss/342-ath11k-provide-access-of-the-dma-buffer-back-to-dma-.patch new file mode 100644 index 00000000000000..db779080b71f96 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/342-ath11k-provide-access-of-the-dma-buffer-back-to-dma-.patch @@ -0,0 +1,28 @@ +From a12157095a8a59eeaeb7c9efe70495288140159c Mon Sep 17 00:00:00 2001 +From: Hari Chandrakanthan +Date: Mon, 10 Jan 2022 12:38:10 +0530 +Subject: [PATCH] ath11k: provide access of the dma buffer back to dma device + +In ath11k_dbring_bufs_replenish, after accessing paddr which is a member of +ath11k_dbring_element, provide the access of the buffer back to +dma device by using dma_sync_single_for_device. + +Also the gfp flag to used inside ath11k_dbring_fill_bufs is changed +from GFP_KERNEL to GFP_ATOMIC as the buffers are allocated inside spin lock. + +Signed-off-by: Hari Chandrakanthan +--- + drivers/net/wireless/ath/ath11k/dbring.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath11k/dbring.c ++++ b/drivers/net/wireless/ath/ath11k/dbring.c +@@ -80,6 +80,8 @@ static int ath11k_dbring_bufs_replenish( + + buff->paddr = paddr; + ++ dma_sync_single_for_device(ab->dev, paddr, ring->buf_sz, DMA_FROM_DEVICE); ++ + cookie = FIELD_PREP(DP_RXDMA_BUF_COOKIE_PDEV_ID, ar->pdev_idx) | + FIELD_PREP(DP_RXDMA_BUF_COOKIE_BUF_ID, buf_id); + diff --git a/package/kernel/mac80211/patches/ath11k_nss/342-mac80211-fix-unconditional-sta-usage.patch b/package/kernel/mac80211/patches/ath11k_nss/342-mac80211-fix-unconditional-sta-usage.patch new file mode 100644 index 00000000000000..e4890a3654c3b3 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/342-mac80211-fix-unconditional-sta-usage.patch @@ -0,0 +1,50 @@ +From 479096a023928cc75aa38953b7170a8984acd0da Mon Sep 17 00:00:00 2001 +From: Tamizh Chelvam +Date: Tue, 11 Jan 2022 14:04:09 +0530 +Subject: [PATCH] mac80211: Fix kernel panic due to unsafe sta usage + +Observing below crash in dynamic vlan scneario when +abruptly killing hostapd while ping or any traffic to stations +are going on. + +[ 753.307213] Unable to handle kernel NULL pointer dereference at virtual address 0000058c +[ 753.309137] pgd = 7514769a +[ 753.317392] [0000058c] *pgd=00000000 +[ 753.319892] Internal error: Oops: 5 [#1] PREEMPT SMP ARM +[ 753.604280] PC is at __ieee80211_subif_start_xmit+0xc58/0xe48 [mac80211] +[ 753.608954] LR is at __ieee80211_subif_start_xmit+0xc3c/0xe48 [mac80211] +[ 753.615729] pc : [] lr : [] psr: 40000013 +[ 753.622411] sp : 843b5940 ip : 98e7d348 fp : 99463e42 +[ 753.628398] r10: 98e7d318 r9 : 92d0e000 r8 : 00000000 +[ 753.633606] r7 : 963c8d20 r6 : 92d0e580 r5 : 00000000 r4 : 98e7d300 +[ 753.638819] r3 : 00000163 r2 : fffffff0 r1 : 00000000 r0 : 98e7d318 +[ 753.645416] Flags: nZcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user +[ 753.651928] Control: 10c0383d Table: 5db8806a DAC: 00000055 +[ 753.659135] Process ping (pid: 4436, stack limit = 0xf466aee4) + +Its due to accessing the sta pointer +unconditionally. Fix that by checking sta pointer is +available or not before using. + +Signed-off-by: Tamizh Chelvam +--- + net/mac80211/tx.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -4725,12 +4725,12 @@ 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, + &info->flags, NULL); + + ieee80211_tx_stats(dev, 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; + sta->deflink.tx_stats.bytes[queue] += len; + } diff --git a/package/kernel/mac80211/patches/ath11k_nss/357-ath11k-fix-clear-peer-keys-during-disassoc.patch b/package/kernel/mac80211/patches/ath11k_nss/357-ath11k-fix-clear-peer-keys-during-disassoc.patch new file mode 100644 index 00000000000000..5050192acc64ae --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/357-ath11k-fix-clear-peer-keys-during-disassoc.patch @@ -0,0 +1,50 @@ +From 451cd8d4f107750d86a51c3cf750015676991d17 Mon Sep 17 00:00:00 2001 +From: Karthikeyan Kathirvel +Date: Thu, 11 Aug 2022 21:27:16 +0530 +Subject: [PATCH] ath11k: fix clearing peer keys during sta state auth to assoc + +During station state change from AUTHORIZED to ASSOC, driver must clear its key +from hw. Ath11k clearing the keys during ASSOC to AUTH which is not a +valid sequence and there is a chance of accessing ptr after free. + +Clear the peer keys while the state of station changes from AUTHORIZED +to ASSOC. + +Signed-off-by: Karthikeyan Kathirvel +--- + drivers/net/wireless/ath/ath11k/mac.c | 37 ++++++++++++++++++++--------------- + 1 file changed, 21 insertions(+), 16 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -4708,12 +4708,6 @@ static int ath11k_station_disassoc(struc + return ret; + } + +- 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; +- } + return 0; + } + +@@ -5176,6 +5170,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); ++ ++ /* 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); 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 new file mode 100644 index 00000000000000..d8c907556645cf --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/359-ath11k-fix-tkip-encryption-traffic-failure.patch @@ -0,0 +1,25 @@ +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/376-ath11k-Add-nss-event-handler-support-for-link-desc.patch b/package/kernel/mac80211/patches/ath11k_nss/376-ath11k-Add-nss-event-handler-support-for-link-desc.patch new file mode 100644 index 00000000000000..7b3df32c05b69e --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/376-ath11k-Add-nss-event-handler-support-for-link-desc.patch @@ -0,0 +1,73 @@ +From 69356d5f6947c8a6182e1c6283478ad40c6df37b Mon Sep 17 00:00:00 2001 +From: Tamizh Chelvam Raja +Date: Wed, 21 Jun 2023 20:26:02 +0530 +Subject: [PATCH] ath11k: Add nss event handler support for link desc + +Add NSS event handler support for NSS_WIFILI_LINK_DESC_INFO_MSG. +This event will be given to host from NSS for releasing +link descriptor which used for fragmentation. This needs to be +handled to release the link descriptor back to hardware for +other usage. + +Signed-off-by: Tamizh Chelvam Raja +--- + drivers/net/wireless/ath/ath11k/nss.c | 43 +++++++++++++++++++++++++++ + 1 file changed, 43 insertions(+) + +--- 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 + spin_unlock_bh(&ab->base_lock); + } + ++static void ath11k_nss_wifili_link_desc_set(struct ath11k_base *ab, void *desc, ++ struct ath11k_buffer_addr *buf_addr_info, ++ enum hal_wbm_rel_bm_act action) ++{ ++ struct hal_wbm_release_ring *dst_desc = desc; ++ ++ dst_desc->buf_addr_info = *buf_addr_info; ++ dst_desc->info0 |= FIELD_PREP(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE, ++ HAL_WBM_REL_SRC_MODULE_SW) | ++ FIELD_PREP(HAL_WBM_RELEASE_INFO0_BM_ACTION, action) | ++ FIELD_PREP(HAL_WBM_RELEASE_INFO0_DESC_TYPE, ++ HAL_WBM_REL_DESC_TYPE_MSDU_LINK); ++} ++ ++static void ath11k_nss_wifili_link_desc_return(struct ath11k_base *ab, ++ struct ath11k_buffer_addr *buf_addr_info) ++{ ++ struct ath11k_dp *dp = &ab->dp; ++ struct hal_srng *srng; ++ u32 *desc; ++ ++ srng = &ab->hal.srng_list[dp->wbm_desc_rel_ring.ring_id]; ++ spin_lock_bh(&srng->lock); ++ ++ ath11k_hal_srng_access_begin(ab, srng); ++ desc = ath11k_hal_srng_src_get_next_entry(ab, srng); ++ ++ if (!desc) ++ goto exit; ++ ++ ath11k_nss_wifili_link_desc_set(ab, desc, buf_addr_info, HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); ++ ++exit: ++ ath11k_hal_srng_access_end(ab, srng); ++ spin_unlock(&srng->lock); ++} ++ + 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 */ + break; ++ case NSS_WIFILI_LINK_DESC_INFO_MSG: ++ ath11k_nss_wifili_link_desc_return(ab, ++ (void *)&msg->msg.linkdescinfomsg); ++ break; + default: + ath11k_dbg(ab, ATH11K_DBG_NSS, "unhandled event %d\n", msg_type); + break; 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/ath11k_nss/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch new file mode 100644 index 00000000000000..2d1fbc097df375 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch @@ -0,0 +1,85 @@ +From 11d0cce62afc157468e1d97ea80a2510091ea2c2 Mon Sep 17 00:00:00 2001 +From: P Praneesh +Date: Fri, 1 Jul 2022 11:57:00 +0530 +Subject: [PATCH] mac80211: Remove unused RX_FLAGS from mac80211_rx_flags + +Remove unused RX_FLAG_AMPDU_DELIM_CRC_KNOWN flag from +mac80211_rx_flags to provide space for new EHT flags. + +Signed-off-by: P Praneesh +--- + include/net/mac80211.h | 33 +++++++++++++++------------------ + net/mac80211/rx.c | 7 +------ + 2 files changed, 16 insertions(+), 24 deletions(-) + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -1385,8 +1385,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 +- * @RX_FLAG_AMPDU_DELIM_CRC_KNOWN: The delimiter CRC field is known (the CRC +- * is stored in the @ampdu_delimiter_crc field) + * @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 +@@ -1458,22 +1456,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), +- RX_FLAG_AMPDU_DELIM_CRC_KNOWN = BIT(15), +- RX_FLAG_MACTIME_END = BIT(16), +- RX_FLAG_ONLY_MONITOR = BIT(17), +- RX_FLAG_SKIP_MONITOR = BIT(18), +- RX_FLAG_AMSDU_MORE = BIT(19), +- RX_FLAG_RADIOTAP_TLV_AT_END = BIT(20), +- RX_FLAG_MIC_STRIPPED = BIT(21), +- RX_FLAG_ALLOW_SAME_PN = BIT(22), +- RX_FLAG_ICV_STRIPPED = BIT(23), +- RX_FLAG_AMPDU_EOF_BIT = BIT(24), +- RX_FLAG_AMPDU_EOF_BIT_KNOWN = BIT(25), +- RX_FLAG_RADIOTAP_HE = BIT(26), +- RX_FLAG_RADIOTAP_HE_MU = BIT(27), +- RX_FLAG_RADIOTAP_LSIG = BIT(28), +- RX_FLAG_NO_PSDU = BIT(29), +- RX_FLAG_8023 = BIT(30), ++ RX_FLAG_MACTIME_END = BIT(15), ++ RX_FLAG_ONLY_MONITOR = BIT(16), ++ RX_FLAG_SKIP_MONITOR = BIT(17), ++ RX_FLAG_AMSDU_MORE = BIT(18), ++ RX_FLAG_RADIOTAP_TLV_AT_END = BIT(19), ++ RX_FLAG_MIC_STRIPPED = BIT(20), ++ RX_FLAG_ALLOW_SAME_PN = BIT(21), ++ RX_FLAG_ICV_STRIPPED = BIT(22), ++ RX_FLAG_AMPDU_EOF_BIT = BIT(23), ++ RX_FLAG_AMPDU_EOF_BIT_KNOWN = BIT(24), ++ RX_FLAG_RADIOTAP_HE = BIT(25), ++ RX_FLAG_RADIOTAP_HE_MU = BIT(26), ++ RX_FLAG_RADIOTAP_LSIG = BIT(27), ++ RX_FLAG_NO_PSDU = BIT(28), ++ RX_FLAG_8023 = BIT(29), + }; + + /** +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -527,18 +527,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; +- if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN) +- flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN; + if (status->flag & RX_FLAG_AMPDU_EOF_BIT_KNOWN) + flags |= IEEE80211_RADIOTAP_AMPDU_EOF_KNOWN; + if (status->flag & RX_FLAG_AMPDU_EOF_BIT) + flags |= IEEE80211_RADIOTAP_AMPDU_EOF; + put_unaligned_le16(flags, pos); + pos += 2; +- if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN) +- *pos++ = status->ampdu_delimiter_crc; +- else +- *pos++ = 0; ++ *pos++ = 0; + *pos++ = 0; + } + 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 new file mode 100644 index 00000000000000..b8d2b614dd4759 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/640-006-mac80211-add-eht-radiotap.patch @@ -0,0 +1,506 @@ +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 +@@ -1439,7 +1439,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), +@@ -1471,6 +1475,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), + }; + + /** +@@ -1538,6 +1544,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 +@@ -1591,6 +1598,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/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch b/package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch new file mode 100644 index 00000000000000..b64643140a14b1 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch @@ -0,0 +1,232 @@ +From f2c96599c02eb0d47602d000fe0f40358c10c892 Mon Sep 17 00:00:00 2001 +From: Aaradhana Sahu +Date: Fri, 26 Aug 2022 17:54:37 +0530 +Subject: [PATCH] mac80211: Avoid encapsulation of EAPOL frames if OFFLOAD_ENCAP is enabled + +EAP Frames over NL80211 Control port are 802.11 Native WiFi +encapsulated by default, but for a vdev operating in 802.3, when FW doesn’t +advertise WMI_SERVICE_EAPOL_OVER_NWIFI, it cannot accept an 802.11 +Native WiFi frame. + +Allow EAP Frames over NL80211 Control port to be passed as 802.3 +if vif has IEEE80211_OFFLOAD_ENCAP_ENABLED set. + +Signed-off-by: Rameshkumar Sundaram +Signed-off-by: Aaradhana Sahu +--- + net/mac80211/ieee80211_i.h | 5 ++++ + net/mac80211/tx.c | 58 ++++++++++++++++++++++++++------------ + 2 files changed, 45 insertions(+), 18 deletions(-) + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -2062,6 +2062,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); ++netdev_tx_t __ieee80211_subif_start_xmit_8023(struct sk_buff *skb, ++ struct net_device *dev, ++ u32 info_flags, ++ u32 ctrl_flags, ++ u64 *cookie); + void __ieee80211_subif_start_xmit(struct sk_buff *skb, + struct net_device *dev, + u32 info_flags, +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -39,7 +39,8 @@ + + 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); ++ struct ieee80211_key *key, struct sk_buff *skb, ++ u32 info_flags, u32 ctrl_flags, u64 *cookie); + + 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 && + !is_multicast_ether_addr(skb->data)) { + 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); + rcu_read_unlock(); + return; + } +@@ -4657,19 +4663,29 @@ 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, +- struct ieee80211_key *key, struct sk_buff *skb) ++ struct ieee80211_key *key, struct sk_buff *skb, ++ 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 + 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 + 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))) + info->ack_frame_id = ieee80211_store_ack_skb(local, skb, + &info->flags, NULL); + +@@ -4750,7 +4768,8 @@ out_free: + + void ieee80211_8023_xmit_ap(struct ieee80211_sub_if_data *sdata, + struct net_device *dev, struct sta_info *sta, +- struct ieee80211_key *key, struct sk_buff *skb) ++ struct ieee80211_key *key, struct sk_buff *skb, ++ u32 info_flags, u32 ctrl_flags, u64 *cookie) + { + struct ieee80211_tx_info *info; + struct ieee80211_local *local = sdata->local; +@@ -4759,6 +4778,9 @@ void ieee80211_8023_xmit_ap(struct ieee8 + unsigned long flags; + int q; + u16 q_map; ++ struct ethhdr *ehdr = (struct ethhdr *)skb->data; ++ unsigned char *ra = ehdr->h_dest; ++ bool multicast = is_multicast_ether_addr(ra); + + /* + * If the skb is shared we need to obtain our own copy. +@@ -4770,11 +4792,13 @@ void ieee80211_8023_xmit_ap(struct ieee8 + + info = IEEE80211_SKB_CB(skb); + memset(info, 0, sizeof(*info)); ++ info->flags |= info_flags; + +- if (unlikely(skb->sk && +- skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) ++ if (unlikely((skb->sk && ++ skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) || ++ ((ctrl_flags & IEEE80211_TX_CTL_REQ_TX_STATUS) && !multicast))) + info->ack_frame_id = ieee80211_store_ack_skb(local, skb, +- &info->flags, NULL); ++ &info->flags, cookie); + + 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); + } +- + 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); ++} ++ ++netdev_tx_t __ieee80211_subif_start_xmit_8023(struct sk_buff *skb, ++ struct net_device *dev, ++ u32 info_flags, ++ u32 ctrl_flags, ++ u64 *cookie) ++{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ethhdr *ehdr = (struct ethhdr *)skb->data; + struct ieee80211_key *key = NULL; + struct sta_info *sta; ++ bool is_eapol; + + #ifdef CPTCFG_MAC80211_NSS_SUPPORT + ieee80211_xmit_nss_fixup(skb, dev); +@@ -4834,14 +4867,15 @@ netdev_tx_t ieee80211_subif_start_xmit_8 + kfree_skb(skb); + goto out; + } ++ is_eapol = (sdata->control_port_protocol == ehdr->h_proto); + + if (ieee80211_hw_check(&sdata->local->hw, SUPPORTS_NSS_OFFLOAD)) { + if (unlikely(IS_ERR_OR_NULL(sta) || !sta->uploaded)) + sta = NULL; + goto tx_offload; + } else if (unlikely(IS_ERR_OR_NULL(sta) || !sta->uploaded || +- !test_sta_flag(sta, WLAN_STA_AUTHORIZED) || +- sdata->control_port_protocol == ehdr->h_proto)) ++ (!test_sta_flag(sta, WLAN_STA_AUTHORIZED) && !is_eapol) || ++ (is_eapol && !(sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)))) + goto skip_offload; + + key = rcu_dereference(sta->ptk[sta->ptk_idx]); +@@ -4852,13 +4886,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 + goto skip_offload; + + if (sdata->vif.type == NL80211_IFTYPE_AP) { +- ieee80211_8023_xmit_ap(sdata, dev, sta, key, skb); ++ ieee80211_8023_xmit_ap(sdata, dev, sta, key, skb, info_flags, ctrl_flags, cookie); + goto out; + } + + sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift); + tx_offload: +- ieee80211_8023_xmit(sdata, dev, sta, key, skb); ++ ieee80211_8023_xmit(sdata, dev, sta, key, skb, info_flags, ctrl_flags, cookie); + goto out; + + skip_offload: +@@ -6364,13 +6398,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_8023(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/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 new file mode 100644 index 00000000000000..1bfa9b89b45c5f --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/702-ath11k-fix-memory-leak-in-dp-rx.patch @@ -0,0 +1,48 @@ +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 new file mode 100644 index 00000000000000..31db236d5fd4ef --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch @@ -0,0 +1,74 @@ +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/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch b/package/kernel/mac80211/patches/ath11k_nss/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch new file mode 100644 index 00000000000000..e5b4d7d9e7ef4e --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch @@ -0,0 +1,140 @@ +From d4ddaebe2132dbb169f78da3666b11a21f645ea0 Mon Sep 17 00:00:00 2001 +From: Tamizh Chelvam Raja +Date: Fri, 21 Apr 2023 12:28:21 +0530 +Subject: [PATCH] mac80211: Advertise HW checksum offload only for ethmode + +Upper(NSS/SFE) layer might remove checksum offset from a skb +for the net device which advertise HW checksum offload +feature. This would create an issue if any software encrypted +packet or for the netdev which don't support IEEE80211_OFFLOAD_*. +Avoid this by advertising the HW checksum offload feature +only for the netdev which supports IEEE80211_OFFLOAD_* +and have an check before checking checksum offset for the +exceptional packets getting called from 8023_xmit API. + +Signed-off-by: Tamizh Chelvam Raja +--- + net/mac80211/ieee80211_i.h | 3 ++- + net/mac80211/iface.c | 4 ++++ + net/mac80211/tdls.c | 2 +- + net/mac80211/tx.c | 19 ++++++++++--------- + 4 files changed, 17 insertions(+), 11 deletions(-) + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -37,6 +37,8 @@ + #include "wme.h" + #include "rate.h" + ++#define IS_HW_CSUM_NOT_ENABLED(dev) (!((dev)->features & NETIF_F_HW_CSUM)) ++ + 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 + } + + static struct sk_buff * +-ieee80211_tx_skb_fixup(struct sk_buff *skb, netdev_features_t features) ++ieee80211_tx_skb_fixup(struct sk_buff *skb, netdev_features_t features, struct net_device *dev) + { + if (skb_is_gso(skb)) { + struct sk_buff *segs; +@@ -3651,7 +3653,7 @@ ieee80211_tx_skb_fixup(struct sk_buff *s + if (skb_needs_linearize(skb, features) && __skb_linearize(skb)) + goto free; + +- if (skb->ip_summed == CHECKSUM_PARTIAL) { ++ if (skb->ip_summed == CHECKSUM_PARTIAL && IS_HW_CSUM_NOT_ENABLED(dev)) { + int ofs = skb_checksum_start_offset(skb); + + if (skb->encapsulation) +@@ -3797,7 +3799,7 @@ static bool ieee80211_xmit_fast(struct i + memcpy(ð, skb->data, ETH_HLEN - 2); + + /* after this point (skb is modified) we cannot return false */ +- skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); ++ skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata), sdata->dev); + if (!skb) + return true; + +@@ -4345,7 +4347,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. + */ +- skb = ieee80211_tx_skb_fixup(skb, 0); ++ skb = ieee80211_tx_skb_fixup(skb, 0, dev); + 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 + } + } + +- skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); ++ skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata), dev); + 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 + + ndev->features |= local->hw.netdev_features; + ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE; ++ if ((type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_STATION) && ++ ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) && !params->use_4addr) ++ ndev->features |= NETIF_F_HW_CSUM; ++ + ndev->hw_features |= ndev->features & + MAC80211_SUPPORTED_FEATURES_TX; + sdata->vif.netdev_features = local->hw.netdev_features; +--- a/net/mac80211/mesh.c ++++ b/net/mac80211/mesh.c +@@ -13,6 +13,8 @@ + #include "wme.h" + #include "driver-ops.h" + ++#define IS_HW_CSUM_NOT_ENABLED(dev) (!((dev)->features & NETIF_F_HW_CSUM)) ++ + static int mesh_allocated; + static struct kmem_cache *rm_cache; + +@@ -797,7 +799,7 @@ bool ieee80211_mesh_xmit_fast(struct iee + if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) + return false; + +- if (skb->ip_summed == CHECKSUM_PARTIAL) { ++ if (skb->ip_summed == CHECKSUM_PARTIAL && IS_HW_CSUM_NOT_ENABLED(sdata->dev)) { + skb_set_transport_header(skb, skb_checksum_start_offset(skb)); + if (skb_checksum_help(skb)) + return false; diff --git a/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch b/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch new file mode 100644 index 00000000000000..67d6e5285bdd94 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch @@ -0,0 +1,236 @@ +--- 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 +@@ -9224,7 +9224,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 + */ +-int cfg80211_bss_color_notify(struct net_device *dev, ++int cfg80211_bss_color_notify(struct net_device *dev, gfp_t gfp, + enum nl80211_commands cmd, u8 count, + u64 color_bitmap); + +@@ -9234,9 +9234,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, +- u64 color_bitmap) ++ u64 color_bitmap, gfp_t gfp) + { +- return cfg80211_bss_color_notify(dev, NL80211_CMD_OBSS_COLOR_COLLISION, ++ return cfg80211_bss_color_notify(dev, gfp, NL80211_CMD_OBSS_COLOR_COLLISION, + 0, color_bitmap); + } + +@@ -9250,7 +9250,7 @@ static inline int cfg80211_obss_color_co + static inline int cfg80211_color_change_started_notify(struct net_device *dev, + u8 count) + { +- return cfg80211_bss_color_notify(dev, NL80211_CMD_COLOR_CHANGE_STARTED, ++ return cfg80211_bss_color_notify(dev, GFP_KERNEL, NL80211_CMD_COLOR_CHANGE_STARTED, + count, 0); + } + +@@ -9262,7 +9262,7 @@ static inline int cfg80211_color_change_ + */ + static inline int cfg80211_color_change_aborted_notify(struct net_device *dev) + { +- return cfg80211_bss_color_notify(dev, NL80211_CMD_COLOR_CHANGE_ABORTED, ++ return cfg80211_bss_color_notify(dev, GFP_KERNEL, NL80211_CMD_COLOR_CHANGE_ABORTED, + 0, 0); + } + +@@ -9274,7 +9274,7 @@ static inline int cfg80211_color_change_ + */ + static inline int cfg80211_color_change_notify(struct net_device *dev) + { +- return cfg80211_bss_color_notify(dev, ++ return cfg80211_bss_color_notify(dev, GFP_KERNEL, + NL80211_CMD_COLOR_CHANGE_COMPLETED, + 0, 0); + } +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -5239,6 +5239,10 @@ void ieee80211_tx_status_ext(struct ieee + * (NULL for multicast packets) + * @info: tx status information + */ ++void ieee80211_tx_status_8023(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct sk_buff *skb); ++ + static inline void ieee80211_tx_status_noskb(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + struct ieee80211_tx_info *info) +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -4775,7 +4775,7 @@ void ieee80211_color_collision_detection + struct ieee80211_sub_if_data *sdata = link->sdata; + + sdata_lock(sdata); +- cfg80211_obss_color_collision_notify(sdata->dev, link->color_bitmap); ++ cfg80211_obss_color_collision_notify(sdata->dev, link->color_bitmap, GFP_KERNEL); + sdata_unlock(sdata); + } + +--- a/net/mac80211/debugfs_netdev.c ++++ b/net/mac80211/debugfs_netdev.c +@@ -889,7 +889,7 @@ void ieee80211_debugfs_add_netdev(struct + { + char buf[10+IFNAMSIZ]; + +- sprintf(buf, "netdev:%s", sdata->name); ++ snprintf(buf, 10 + IFNAMSIZ, "netdev:%s", sdata->name); + sdata->vif.debugfs_dir = debugfs_create_dir(buf, + sdata->local->hw.wiphy->debugfsdir); + sdata->debugfs.subdir_stations = debugfs_create_dir("stations", +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -1406,18 +1406,6 @@ static void __sta_info_destroy_part2(str + WARN_ON_ONCE(ret); + } + +- /* Flush queues before removing keys, as that might remove them +- * from hardware, and then depending on the offload method, any +- * frames sitting on hardware queues might be sent out without +- * any encryption at all. +- */ +- if (local->ops->set_key) { +- if (local->ops->flush_sta) +- drv_flush_sta(local, sta->sdata, sta); +- else +- ieee80211_flush_queues(local, sta->sdata, false); +- } +- + /* now keys can no longer be reached */ + ieee80211_free_sta_keys(local, sta); + +--- a/net/mac80211/status.c ++++ b/net/mac80211/status.c +@@ -1244,6 +1244,30 @@ void ieee80211_tx_rate_update(struct iee + } + EXPORT_SYMBOL(ieee80211_tx_rate_update); + ++void ieee80211_tx_status_8023(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct sk_buff *skb) ++{ ++ struct ieee80211_sub_if_data *sdata; ++ struct ieee80211_tx_status status = { ++ .skb = skb, ++ .info = IEEE80211_SKB_CB(skb), ++ }; ++ struct sta_info *sta; ++ ++ sdata = vif_to_sdata(vif); ++ ++ rcu_read_lock(); ++ ++ if (!ieee80211_lookup_ra_sta(sdata, skb, &sta) && !IS_ERR(sta)) ++ status.sta = &sta->sta; ++ ++ ieee80211_tx_status_ext(hw, &status); ++ ++ rcu_read_unlock(); ++} ++EXPORT_SYMBOL(ieee80211_tx_status_8023); ++ + void ieee80211_report_low_ack(struct ieee80211_sta *pubsta, u32 num_packets) + { + struct sta_info *sta = container_of(pubsta, struct sta_info, sta); +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -19406,7 +19406,7 @@ void cfg80211_ch_switch_started_notify(s + } + EXPORT_SYMBOL(cfg80211_ch_switch_started_notify); + +-int cfg80211_bss_color_notify(struct net_device *dev, ++int cfg80211_bss_color_notify(struct net_device *dev, gfp_t gfp, + enum nl80211_commands cmd, u8 count, + u64 color_bitmap) + { +@@ -19420,7 +19420,7 @@ int cfg80211_bss_color_notify(struct net + + trace_cfg80211_bss_color_notify(dev, cmd, count, color_bitmap); + +- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); ++ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); + if (!msg) + return -ENOMEM; + +@@ -19443,7 +19443,7 @@ int cfg80211_bss_color_notify(struct net + genlmsg_end(msg, hdr); + + return genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), +- msg, 0, NL80211_MCGRP_MLME, GFP_KERNEL); ++ msg, 0, NL80211_MCGRP_MLME, gfp); + + nla_put_failure: + nlmsg_free(msg); +--- a/backport-include/linux/netdevice.h ++++ b/backport-include/linux/netdevice.h +@@ -70,6 +70,9 @@ static inline void netif_trans_update(st + (_dev)->needs_free_netdev = true; + #endif + ++#define netdev_tstats(dev) dev->tstats ++#define netdev_assign_tstats(dev, e) dev->tstats = (e); ++ + #if LINUX_VERSION_IS_LESS(4,15,0) + static inline int _bp_netdev_upper_dev_link(struct net_device *dev, + struct net_device *upper_dev) 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/ath11k_nss/902-000-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch new file mode 100644 index 00000000000000..f0fc8c14ec1efd --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/902-000-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch @@ -0,0 +1,206 @@ +From 05d9bff2eb8b057d34c7c4b24329dd92cf4faddb Mon Sep 17 00:00:00 2001 +From: Sathishkumar Muruganandam +Date: Wed, 18 Nov 2020 23:54:38 +0530 +Subject: [PATCH 1/3] mac80211: add AP_VLAN iftype support on NSS offload case + +- allow AP_VLAN iftype to get added, removed +- add new callback for 4addr rx_notify to get AP_VLAN created from hostapd +- modify sta_use_4addr drv callback to advertise AP_VLAN vif instead of AP vif +- modify drv_tx callback to use AP_VLAN vif on NSS offload case + +Signed-off-by: Sathishkumar Muruganandam +--- + include/net/mac80211.h | 11 +++++++++++ + net/mac80211/cfg.c | 5 ++++- + net/mac80211/driver-ops.c | 9 +++++---- + net/mac80211/iface.c | 10 ++++++---- + net/mac80211/rx.c | 6 ++++++ + net/mac80211/tx.c | 14 ++++++++++---- + net/mac80211/util.c | 6 ++---- + 7 files changed, 44 insertions(+), 17 deletions(-) + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -5100,6 +5100,17 @@ void ieee80211_sta_pspoll(struct ieee802 + */ + void ieee80211_sta_uapsd_trigger(struct ieee80211_sta *sta, u8 tid); + ++/** ++ * ieee80211_rx_nss_notify_4addr - notify userspace about 4addr frame rx ++ * @dev: The device the frame matched to ++ * @addr: the transmitter address of 4addr sta ++ * ++ * When operating in AP mode with NSS offload enabled, this function is used ++ * to invoke cfg80211 callback to notify userspace that an associated station ++ * sent a 4addr frame. ++ */ ++void ieee80211_rx_nss_notify_4addr(struct net_device *dev, u8* sta_addr); ++ + /* + * The TX headroom reserved by mac80211 for its own tx_status functions. + * This is enough for the radiotap header. +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -2176,7 +2176,13 @@ static int ieee80211_change_station(stru + + rcu_assign_pointer(vlansdata->u.vlan.sta, sta); + __ieee80211_check_fast_rx_iface(vlansdata); +- drv_sta_set_4addr(local, sta->sdata, &sta->sta, true); ++ ++ if (ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) ++ drv_sta_set_4addr(local, vlansdata, &sta->sta, ++ true); ++ else ++ drv_sta_set_4addr(local, sta->sdata, &sta->sta, ++ true); + } + + if (sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN && +--- a/net/mac80211/driver-ops.c ++++ b/net/mac80211/driver-ops.c +@@ -59,10 +59,9 @@ int drv_add_interface(struct ieee80211_l + + might_sleep(); + +- if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN || +- (sdata->vif.type == NL80211_IFTYPE_MONITOR && ++ if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_MONITOR && + !ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) && +- !(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE)))) ++ !(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))) + return -EINVAL; + + trace_drv_add_interface(local, sdata); +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -676,6 +676,9 @@ static void ieee80211_do_stop(struct iee + + switch (sdata->vif.type) { + case NL80211_IFTYPE_AP_VLAN: ++ if (ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD) && ++ going_down) ++ drv_remove_interface(local, sdata); + break; + case NL80211_IFTYPE_MONITOR: + if (local->monitors == 0) +@@ -960,6 +963,7 @@ static bool ieee80211_iftype_supports_hd + switch (iftype) { + /* P2P GO and client are mapped to AP/STATION types */ + case NL80211_IFTYPE_AP: ++ case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_STATION: + return true; + default: +@@ -1014,7 +1018,8 @@ static void ieee80211_set_vif_encap_ops( + struct ieee80211_sub_if_data *bss = sdata; + bool enabled; + +- if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { ++ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && ++ !ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) { + if (!sdata->bss) + return; + +@@ -1359,10 +1364,17 @@ int ieee80211_do_open(struct wireless_de + + switch (sdata->vif.type) { + case NL80211_IFTYPE_AP_VLAN: +- /* no need to tell driver, but set carrier and chanctx */ + if (sdata->bss->active) { + ieee80211_link_vlan_copy_chanctx(&sdata->deflink); + netif_carrier_on(dev); ++ ++ if (ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) { ++ ieee80211_set_sdata_offload_flags(sdata); ++ res = drv_add_interface(local, sdata); ++ if (res) ++ goto err_del_interface; ++ } ++ + ieee80211_set_vif_encap_ops(sdata); + } else { + netif_carrier_off(dev); +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1759,6 +1759,12 @@ void ieee80211_sta_uapsd_trigger(struct + } + EXPORT_SYMBOL(ieee80211_sta_uapsd_trigger); + ++void ieee80211_rx_nss_notify_4addr(struct net_device *dev, u8 *sta_addr) ++{ ++ cfg80211_rx_unexpected_4addr_frame(dev, sta_addr, GFP_ATOMIC); ++} ++EXPORT_SYMBOL(ieee80211_rx_nss_notify_4addr); ++ + static ieee80211_rx_result debug_noinline + ieee80211_rx_h_uapsd_and_pspoll(struct ieee80211_rx_data *rx) + { +--- 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; + info->hw_queue = sdata->vif.hw_queue[queue]; + +- if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) ++ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && ++ !ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) + sdata = container_of(sdata->bss, + struct ieee80211_sub_if_data, u.ap); + +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -2410,6 +2410,9 @@ static void ieee80211_assign_chanctx(str + if (!local->use_chanctx) + return; + ++ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) ++ return; ++ + mutex_lock(&local->chanctx_mtx); + conf = rcu_dereference_protected(link->conf->chanctx_conf, + lockdep_is_held(&local->chanctx_mtx)); +@@ -2615,7 +2618,8 @@ int ieee80211_reconfig(struct ieee80211_ + } + + list_for_each_entry(sdata, &local->interfaces, list) { +- if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && ++ if ((sdata->vif.type != NL80211_IFTYPE_AP_VLAN || ++ ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) && + sdata->vif.type != NL80211_IFTYPE_MONITOR && + ieee80211_sdata_running(sdata)) { + res = drv_add_interface(local, sdata); +@@ -2630,7 +2634,8 @@ int ieee80211_reconfig(struct ieee80211_ + if (res) { + list_for_each_entry_continue_reverse(sdata, &local->interfaces, + list) +- if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && ++ if ((sdata->vif.type != NL80211_IFTYPE_AP_VLAN || ++ ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) && + sdata->vif.type != NL80211_IFTYPE_MONITOR && + ieee80211_sdata_running(sdata)) + 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 + * 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 + */ +- if (ifmgd->use_4addr) ++ if (ifmgd->use_4addr && ++ (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD))) + ieee80211_send_4addr_nullfunc(local, sdata); + + /* +--- a/net/mac80211/driver-ops.h ++++ b/net/mac80211/driver-ops.h +@@ -1457,7 +1457,9 @@ static inline void drv_sta_set_4addr(str + struct ieee80211_sub_if_data *sdata, + struct ieee80211_sta *sta, bool enabled) + { +- sdata = get_bss_sdata(sdata); ++ if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) ++ sdata = get_bss_sdata(sdata); ++ + if (!check_sdata_in_driver(sdata)) + return; + 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/ath11k_nss/902-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch new file mode 100644 index 00000000000000..7e2a9f0ee4dd4b --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/902-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch @@ -0,0 +1,701 @@ +From d4c3b17e66243a2d6d8845192453ef7da568bac2 Mon Sep 17 00:00:00 2001 +From: Sathishkumar Muruganandam +Date: Thu, 10 Sep 2020 15:58:53 +0530 +Subject: [PATCH 1/2] ath11k: add WDS offload changes to NSS driver interface + +add WDS and MEC AST handling to NSS + +Signed-off-by: Sathishkumar Muruganandam +--- + drivers/net/wireless/ath/ath11k/nss.c | 465 ++++++++++++++++++++++++++++++++-- + drivers/net/wireless/ath/ath11k/nss.h | 36 ++- + 2 files changed, 473 insertions(+), 28 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/nss.c ++++ b/drivers/net/wireless/ath/ath11k/nss.c +@@ -9,10 +9,12 @@ + #include "nss.h" + #include "core.h" + #include "peer.h" ++#include "dp_tx.h" + #include "dp_rx.h" + #include "dp_tx.h" + #include "hif.h" + #include "wmi.h" ++#include "wmi.h" + #include "../../../../../net/mac80211/sta_info.h" + + /*-----------------------------ATH11K-NSS Helpers--------------------------*/ +@@ -348,6 +350,22 @@ void ath11k_nss_wifili_event_receive(str + ath11k_nss_wifili_link_desc_return(ab, + (void *)&msg->msg.linkdescinfomsg); + 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", ++ msg_type, response, error); ++ break; ++ case NSS_WIFILI_WDS_PEER_UPDATE_MSG: ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, "nss wifili wds peer update event received %d response %d error %d\n", ++ msg_type, response, error); ++ break; ++ case NSS_WIFILI_WDS_PEER_MAP_MSG: ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, "nss wifili wds peer map event received %d response %d error %d\n", ++ msg_type, response, error); ++ break; ++ case NSS_WIFILI_WDS_PEER_DEL_MSG: ++ 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; + 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 + /*TODO*/ + } + +-static void +-ath11k_nss_vdev_special_data_receive(struct net_device *dev, struct sk_buff *skb, +- __attribute__((unused)) struct napi_struct *napi) +-{ +- /* TODO */ +-} +- + /* 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 + return 0; + } + ++static void ath11k_nss_wds_type_rx(struct ath11k *ar, u8* src_mac, u8 is_sa_valid, ++ u8 addr4_valid, u16 peer_id) ++{ ++ struct ath11k_base *ab = ar->ab; ++ struct ath11k_ast_entry *ast_entry = NULL; ++ struct ath11k_peer *ta_peer = NULL; ++ ++ spin_lock_bh(&ab->base_lock); ++ ta_peer = ath11k_peer_find_by_id(ab, peer_id); ++ ++ if (!ta_peer) { ++ spin_unlock_bh(&ab->base_lock); ++ return; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS,"ath11k_nss_wds_type_rx ta_peer %pM\n", ++ ta_peer->addr); ++ ++ if (addr4_valid) { ++ ast_entry = ath11k_peer_ast_find_by_addr(ab, src_mac); ++ if (!is_sa_valid) { ++ ath11k_peer_add_ast(ar, ta_peer, src_mac, ++ ATH11K_AST_TYPE_WDS); ++ ath11k_nss_add_wds_peer(ar, ta_peer, ++ src_mac, ATH11K_AST_TYPE_WDS); ++ } else { ++ if (!ast_entry) { ++ ath11k_peer_add_ast(ar, ta_peer, src_mac, ++ ATH11K_AST_TYPE_WDS); ++ ath11k_nss_add_wds_peer(ar, ta_peer, src_mac, ++ ATH11K_AST_TYPE_WDS); ++ } else { ++ ath11k_peer_update_ast(ar, ta_peer, ast_entry); ++ ath11k_nss_update_wds_peer(ar, ta_peer, src_mac); ++ } ++ } ++ } ++ ++ spin_unlock_bh(&ab->base_lock); ++} ++ ++static void ath11k_nss_mec_handler(struct ath11k *ar, u8* mec_mac_addr) ++{ ++ struct ath11k_base *ab = ar->ab; ++ struct ath11k_peer *peer = ar->bss_peer; ++ u8 mac_addr[ETH_ALEN]; ++ u32 *mac_addr_l32; ++ u16 *mac_addr_h16; ++ ++ if (!peer) ++ return; ++ ++ /* mec_mac_addr has the swapped mac_addr after 4 bytes (sizeof(u32)) ++ * mec_mac_addr[0] ++ * | ++ * 03:0a:00:00:2d:15:22:f0:fd:8c ++ * ^ ++ * Swapped MAC address present after 4 bytes ++ * MAC address after swapping is 8c:fd:f0:22:15:2d */ ++ ++ mac_addr_l32 = (u32 *) (mec_mac_addr + sizeof(u32)); ++ mac_addr_h16 = (u16 *) (mec_mac_addr + sizeof(u32) + sizeof(u32)); ++ ++ *mac_addr_l32 = swab32(*mac_addr_l32); ++ *mac_addr_h16 = swab16(*mac_addr_h16); ++ ++ memcpy(mac_addr, mac_addr_h16, ETH_ALEN - 4); ++ memcpy(mac_addr + 2, mac_addr_l32, 4); ++ ++ if (!ether_addr_equal(ar->mac_addr, mac_addr)) { ++ spin_lock_bh(&ab->base_lock); ++ ath11k_peer_add_ast(ar, peer, mac_addr, ++ ATH11K_AST_TYPE_MEC); ++ spin_unlock_bh(&ab->base_lock); ++ } ++} ++ ++static void ath11k_nss_vdev_spl_receive_ext_wdsdata(struct ath11k_vif *arvif, ++ struct sk_buff *skb, ++ struct nss_wifi_vdev_wds_per_packet_metadata *wds_metadata) ++{ ++ struct ath11k *ar = arvif->ar; ++ struct ath11k_base *ab = ar->ab; ++ enum wifi_vdev_ext_wds_info_type wds_type; ++ u8 is_sa_valid = 0, addr4_valid = 0; ++ u16 peer_id; ++ u8 src_mac[ETH_ALEN]; ++ ++ is_sa_valid = wds_metadata->is_sa_valid; ++ addr4_valid = wds_metadata->addr4_valid; ++ wds_type = wds_metadata->wds_type; ++ peer_id = wds_metadata->peer_id; ++ ++ memcpy(src_mac, ((struct ethhdr *)skb->data)->h_source, ETH_ALEN); ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS,"receive_ext_wdsdata wds_type %d peer id %u sa_valid %d addr4_valid %d src_mac %pM\n", ++ wds_type, peer_id, is_sa_valid, addr4_valid, src_mac); ++ ++ switch (wds_type) { ++ case NSS_WIFI_VDEV_WDS_TYPE_RX: ++ ath11k_nss_wds_type_rx(ar, src_mac, is_sa_valid, ++ addr4_valid, peer_id); ++ break; ++ case NSS_WIFI_VDEV_WDS_TYPE_MEC: ++ ath11k_nss_mec_handler(ar, (u8 *)(skb->data)); ++ break; ++ default: ++ ath11k_warn(ab, "unsupported wds_type %d\n", wds_type); ++ break; ++ } ++} ++ ++static bool ath11k_nss_vdev_data_receive_mec_check(struct ath11k *ar, ++ struct sk_buff *skb) ++{ ++ struct ath11k_base *ab = ar->ab; ++ struct ath11k_ast_entry *ast_entry = NULL; ++ u8 src_mac[ETH_ALEN]; ++ ++ memcpy(src_mac, ((struct ethhdr *)skb->data)->h_source, ETH_ALEN); ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, ++ "ath11k_nss_vdev_data_receive_mec_check src mac %pM\n", ++ src_mac); ++ ++ spin_lock_bh(&ab->base_lock); ++ ast_entry = ath11k_peer_ast_find_by_addr(ab, src_mac); ++ ++ if (ast_entry && ast_entry->type == ATH11K_AST_TYPE_MEC) { ++ spin_unlock_bh(&ab->base_lock); ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, ++ "dropping mec traffic from %pM\n", ast_entry->addr); ++ return true; ++ } ++ ++ spin_unlock_bh(&ab->base_lock); ++ return false; ++} ++ ++static int ath11k_nss_undecap(struct ath11k_vif *arvif, struct sk_buff *skb, ++ int *data_offs, bool *eth_decap) ++{ ++ enum ath11k_hw_txrx_mode decap_type; ++ ++ decap_type = arvif->nss.decap; ++ ++ switch (decap_type) { ++ case ATH11K_HW_TXRX_RAW: ++ return ath11k_nss_undecap_raw(arvif, skb, data_offs); ++ case ATH11K_HW_TXRX_NATIVE_WIFI: ++ return ath11k_nss_undecap_nwifi(arvif, skb, data_offs); ++ case ATH11K_HW_TXRX_ETHERNET: ++ *eth_decap = true; ++ return 0; ++ default: ++ return -EINVAL; ++ } ++} ++ ++static void ++ath11k_nss_vdev_special_data_receive(struct net_device *dev, struct sk_buff *skb, ++ __attribute__((unused)) struct napi_struct *napi) ++{ ++ 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 eth_decap = false; ++ 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; ++ if (!arvif) { ++ dev_kfree_skb_any(skb); ++ return; ++ } ++ ++ ab = arvif->ar->ab; ++ ++ skb->dev = dev; ++ ++ dma_unmap_single(ab->dev, virt_to_phys(skb->head), ++ NSS_WIFI_VDEV_PER_PACKET_METADATA_OFFSET + ++ sizeof(struct nss_wifi_vdev_per_packet_metadata), ++ DMA_FROM_DEVICE); ++ ++ wifi_metadata = (struct nss_wifi_vdev_per_packet_metadata *)(skb->head + ++ NSS_WIFI_VDEV_PER_PACKET_METADATA_OFFSET); ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, ++ "dp special data from nss: wifi_metadata->pkt_type %d", ++ wifi_metadata->pkt_type); ++ ++ ret = ath11k_nss_undecap(arvif, skb, &data_offs, ð_decap); ++ if (ret) { ++ ath11k_warn(ab, "error in nss rx undecap, type %d err %d\n", ++ arvif->nss.decap, ret); ++ dev_kfree_skb_any(skb); ++ return; ++ } ++ ++ if (eth_decap && wifi_metadata->pkt_type == ++ 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, ++ wds_metadata); ++ } ++ ++ ath11k_nss_deliver_rx(arvif->vif, skb, eth_decap, data_offs, napi); ++} ++ + static void + ath11k_nss_vdev_data_receive(struct net_device *dev, struct sk_buff *skb, + __attribute__((unused)) struct napi_struct *napi) + { +- enum ath11k_hw_txrx_mode decap_type; + struct wireless_dev *wdev; + struct ieee80211_vif *vif; + struct ath11k_vif *arvif; +@@ -632,28 +871,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); + +- decap_type = arvif->nss.decap; +- +- switch (decap_type) { +- case ATH11K_HW_TXRX_RAW: +- ret = ath11k_nss_undecap_raw(arvif, skb, &data_offs); +- break; +- case ATH11K_HW_TXRX_NATIVE_WIFI: +- ret = ath11k_nss_undecap_nwifi(arvif, skb, &data_offs); +- break; +- case ATH11K_HW_TXRX_ETHERNET: +- /* no changes required for ethernet decap */ +- ret = 0; +- eth_decap = true; +- break; +- default: +- ret = -EINVAL; +- break; ++ if ((vif->type == NL80211_IFTYPE_STATION && wdev->use_4addr) && ++ ath11k_nss_vdev_data_receive_mec_check(arvif->ar, skb)) { ++ dev_kfree_skb_any(skb); ++ return; + } + ++ ret = ath11k_nss_undecap(arvif, skb, &data_offs, ð_decap); + if (ret) { +- ath11k_warn(ab, "error in nss rx undecap, type %d err %d\n", decap_type, +- ret); ++ ath11k_warn(ab, "error in nss rx undecap, type %d err %d\n", ++ arvif->nss.decap, ret); + dev_kfree_skb_any(skb); + return; + } +@@ -1362,7 +1589,7 @@ void ath11k_nss_update_sta_rxrate(struct + peer->nss.nss_stats->rxrate.bw = ath11k_mac_bw_to_mac80211_bw(ppdu_info->bw); + } + +-int ath11k_nss_peer_delete(struct ath11k_base *ab, const u8 *addr) ++int ath11k_nss_peer_delete(struct ath11k_base *ab, u32 vdev_id, const u8 *addr) + { + struct nss_wifili_peer_msg *peer_msg; + struct nss_wifili_msg *wlmsg = NULL; +@@ -1376,9 +1603,10 @@ int ath11k_nss_peer_delete(struct ath11k + + spin_lock_bh(&ab->base_lock); + +- peer = ath11k_peer_find_by_addr(ab, addr); ++ peer = ath11k_peer_find(ab, vdev_id, addr); + if (!peer) { +- ath11k_warn(ab, "peer (%pM) not found for nss peer delete\n", addr); ++ ath11k_warn(ab, "peer (%pM) not found on vdev_id %d for nss peer delete\n", ++ addr, vdev_id); + spin_unlock_bh(&ab->base_lock); + return -EINVAL; + } +@@ -1451,8 +1679,9 @@ free_peer: + return ret; + } + +-int ath11k_nss_peer_create(struct ath11k_base *ab, struct ath11k_peer *peer) ++int ath11k_nss_peer_create(struct ath11k *ar, struct ath11k_peer *peer) + { ++ struct ath11k_base *ab = ar->ab; + 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 + status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg); + if (status != NSS_TX_SUCCESS) { + ret = -EINVAL; +- ath11k_warn(ab, "nss send peer (%pM) create msg tx error\n", +- peer->addr); ++ ath11k_warn(ab, "nss send peer (%pM) create msg tx error: %d\n", ++ peer->addr, status); + goto peer_mem_free; + } + +- ret = 0; + ath11k_dbg(ab, ATH11K_DBG_NSS, + "nss peer_create msg success mac:%pM vdev:%d peer_id:%d hw_ast_idx:%d ast_hash:%d\n", + peer_msg->peer_mac_addr, peer_msg->vdev_id, peer_msg->peer_id, + peer_msg->hw_ast_idx, peer_msg->tx_ast_hash); + ++ ret = ath11k_peer_add_ast(ar, peer, peer->addr, ++ ATH11K_AST_TYPE_STATIC); ++ if (ret) { ++ ath11k_warn(ab, "failed to add STATIC ast: %d\n", ret); ++ goto peer_mem_free; ++ } ++ + 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: + return ret; + } + ++int ath11k_nss_add_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, ++ u8 *dest_mac, enum ath11k_ast_entry_type type) ++{ ++ struct ath11k_base *ab = ar->ab; ++ struct nss_wifili_wds_peer_msg *wds_peer_msg; ++ 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 == NULL) ++ return -ENOMEM; ++ ++ wds_peer_msg = &wlmsg->msg.wdspeermsg; ++ ++ wds_peer_msg->pdev_id = ar->pdev->pdev_id; ++ wds_peer_msg->ast_type = type; ++ wds_peer_msg->peer_id = peer->peer_id; ++ ++ if (type == ATH11K_AST_TYPE_MEC) ++ ether_addr_copy(wds_peer_msg->peer_mac, ar->mac_addr); ++ else ++ ether_addr_copy(wds_peer_msg->peer_mac, peer->addr); ++ ++ ether_addr_copy(wds_peer_msg->dest_mac, dest_mac); ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_WDS_PEER_ADD_MSG, ++ sizeof(struct nss_wifili_wds_peer_msg), ++ msg_cb, NULL); ++ ++ status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ret = -EINVAL; ++ ath11k_warn(ab, "nss send wds add peer msg tx error: %d\n", ++ status); ++ goto msg_free; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, ++ "nss add wds peer success peer mac:%pM dest mac:%pM peer_id:%d\n", ++ wds_peer_msg->peer_mac, wds_peer_msg->dest_mac, wds_peer_msg->peer_id); ++ ++msg_free: ++ kfree(wlmsg); ++ return ret; ++} ++ ++int ath11k_nss_update_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, ++ u8 *dest_mac) ++{ ++ struct ath11k_base *ab = ar->ab; ++ struct nss_wifili_wds_peer_msg *wds_peer_msg; ++ 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 == NULL) ++ return -ENOMEM; ++ ++ wds_peer_msg = &wlmsg->msg.wdspeermsg; ++ ++ wds_peer_msg->pdev_id = ar->pdev->pdev_id; ++ wds_peer_msg->ast_type = ATH11K_AST_TYPE_WDS; ++ wds_peer_msg->peer_id = peer->peer_id; ++ ether_addr_copy(wds_peer_msg->peer_mac, peer->addr); ++ ether_addr_copy(wds_peer_msg->dest_mac, dest_mac); ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_WDS_PEER_UPDATE_MSG, ++ sizeof(struct nss_wifili_wds_peer_msg), ++ msg_cb, NULL); ++ ++ status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ret = -EINVAL; ++ ath11k_warn(ab, "nss send wds update peer msg tx error: %d\n", ++ status); ++ goto msg_free; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, ++ "nss update wds peer success peer mac:%pM dest mac:%pM peer_id:%d\n", ++ wds_peer_msg->peer_mac, wds_peer_msg->dest_mac, wds_peer_msg->peer_id); ++ ++msg_free: ++ kfree(wlmsg); ++ return ret; ++} ++ ++int ath11k_nss_map_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, ++ u8 *dest_mac, enum ath11k_ast_entry_type type) ++{ ++ struct ath11k_base *ab = ar->ab; ++ struct nss_wifili_wds_peer_map_msg *wds_peer_map_msg; ++ 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 == NULL) ++ return -ENOMEM; ++ ++ wds_peer_map_msg = &wlmsg->msg.wdspeermapmsg; ++ ++ wds_peer_map_msg->vdev_id = peer->vdev_id; ++ wds_peer_map_msg->ast_idx = peer->hw_peer_id; ++ ++ if (type == ATH11K_AST_TYPE_MEC) ++ wds_peer_map_msg->peer_id = NSS_WIFILI_MEC_PEER_ID; ++ else ++ wds_peer_map_msg->peer_id = peer->peer_id; ++ ++ ether_addr_copy(wds_peer_map_msg->dest_mac, dest_mac); ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_WDS_PEER_MAP_MSG, ++ sizeof(struct nss_wifili_wds_peer_map_msg), ++ msg_cb, NULL); ++ ++ status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ret = -EINVAL; ++ ath11k_warn(ab, "nss send wds peer map msg tx error: %d\n", ++ status); ++ goto msg_free; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, ++ "nss wds peer map success mac:%pM hw_ast_idx:%d peer_id:%d\n", ++ wds_peer_map_msg->dest_mac, wds_peer_map_msg->ast_idx, wds_peer_map_msg->peer_id); ++ ++msg_free: ++ kfree(wlmsg); ++ return ret; ++} ++ ++int ath11k_nss_del_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, ++ u8 *dest_mac) ++{ ++ struct ath11k_base *ab = ar->ab; ++ struct nss_wifili_wds_peer_msg *wds_peer_msg; ++ 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 == NULL) ++ return -ENOMEM; ++ ++ wds_peer_msg = &wlmsg->msg.wdspeermsg; ++ ++ wds_peer_msg->pdev_id = ar->pdev->pdev_id; ++ wds_peer_msg->ast_type = ATH11K_AST_TYPE_NONE; ++ wds_peer_msg->peer_id = peer->peer_id; ++ ether_addr_copy(wds_peer_msg->peer_mac, peer->addr); ++ ether_addr_copy(wds_peer_msg->dest_mac, dest_mac); ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_WDS_PEER_DEL_MSG, ++ sizeof(struct nss_wifili_wds_peer_msg), ++ msg_cb, NULL); ++ ++ status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ret = -EINVAL; ++ ath11k_warn(ab, "nss send wds del peer msg tx error: %d\n", ++ status); ++ goto msg_free; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, ++ "nss del wds peer success peer mac:%pM dest mac:%pM peer_id:%d\n", ++ wds_peer_msg->peer_mac, wds_peer_msg->dest_mac, wds_peer_msg->peer_id); ++ ++msg_free: ++ kfree(wlmsg); ++ return ret; ++} ++ + /*-------------------------------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 + + status = nss_wifili_tx_msg(nss_contex, wlmsg); + if (status != NSS_TX_SUCCESS) { +- ath11k_warn(ab, "failure to send nss init msg\n"); ++ ath11k_warn(ab, "failure to send nss init msg: %d \n", status); + goto unregister; + } + +@@ -1985,7 +2413,8 @@ static int ath11k_nss_stats_cfg(struct a + + status = nss_wifili_tx_msg(ar->nss.ctx, wlmsg); + if (status != NSS_TX_SUCCESS) { +- ath11k_warn(ab, "nss stats cfg %d msg tx failure\n", nss_msg); ++ ath11k_warn(ab, "nss stats cfg %d msg tx failure: %d\n", ++ nss_msg, status); + ret = -EINVAL; + goto free; + } +--- a/drivers/net/wireless/ath/ath11k/nss.h ++++ b/drivers/net/wireless/ath/ath11k/nss.h +@@ -17,12 +17,14 @@ struct ath11k_base; + struct ath11k_vif; + struct ath11k_peer; + struct ath11k_sta; ++enum ath11k_ast_entry_type; + struct hal_rx_mon_ppdu_info; + 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 0x80000000 ++#define ATH11K_DBG_NSS 0x40000000 ++#define ATH11K_DBG_NSS_WDS 0x80000000 + + /* WIFILI Supported Target Types */ + #define ATH11K_WIFILI_TARGET_TYPE_UNKNOWN 0xFF +@@ -208,11 +210,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); +-int ath11k_nss_peer_delete(struct ath11k_base *ab, const u8 *addr); ++int ath11k_nss_peer_delete(struct ath11k_base *ab, u32 vdev_id, const u8 *addr); + int ath11k_nss_set_peer_authorize(struct ath11k *ar, u16 peer_id); +-int ath11k_nss_peer_create(struct ath11k_base *ab, struct ath11k_peer *peer); ++int ath11k_nss_peer_create(struct ath11k *ar, struct ath11k_peer *peer); + void ath11k_nss_peer_stats_enable(struct ath11k *ar); + void ath11k_nss_peer_stats_disable(struct ath11k *ar); ++int ath11k_nss_add_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, ++ u8 *dest_mac, enum ath11k_ast_entry_type type); ++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, ++ 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); + 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 + return 0; + } + +-static inline int ath11k_nss_peer_delete(struct ath11k_base *ab, const u8 *addr) ++static inline int ath11k_nss_peer_delete(struct ath11k_base *ab, u32 vdev_id, ++ const u8 *addr) + { + return 0; + } + +-static inline int ath11k_nss_peer_create(struct ath11k_base *ab, struct ath11k_peer *peer) ++static inline int ath11k_nss_add_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, ++ u8 *dest_mac, int type) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_update_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, ++ u8 *dest_mac) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_map_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, ++ u8 *dest_mac, int type) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_del_wds_peer(struct ath11k_vif *arvif, struct ath11k_peer *peer, ++ u8 *dest_mac) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_peer_create(struct ath11k *ar, struct ath11k_peer *peer) + { + return 0; + } 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/ath11k_nss/902-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch new file mode 100644 index 00000000000000..143191f6a9bca9 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/902-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch @@ -0,0 +1,102 @@ +From 36ee9d37b53c933f4dd8f934f8e0273b5e901549 Mon Sep 17 00:00:00 2001 +From: Sathishkumar Muruganandam +Date: Fri, 8 Jan 2021 00:02:54 +0530 +Subject: [PATCH 1/3] mac80211: add dynamic VLAN support on NSS offload + +NSS requires dynamic AP_VLAN vif ifnum and its corresponding VLAN ID +and group key index to configure dynamic VLAN ext VDEV in NSS. + +Hence mac80211 set_key and sta_state callbacks are modified to advertise +AP_VLAN vif when NSS offload is enabled and VLAN ID provided by hostapd +in key params is stored to ieee80211_key_conf for the driver. + +Co-Developed-by: Seevalamuthu Mariappan +Signed-off-by: Seevalamuthu Mariappan +Signed-off-by: Sathishkumar Muruganandam +--- + include/net/mac80211.h | 3 +++ + net/mac80211/cfg.c | 1 + + net/mac80211/driver-ops.c | 4 +++- + net/mac80211/driver-ops.h | 4 +++- + net/mac80211/key.c | 5 ++++- + net/mac80211/tx.c | 4 ++++ + 6 files changed, 18 insertions(+), 3 deletions(-) + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -2089,6 +2089,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. ++ * @vlan_id: VLAN ID corresponding to the group key. ++ * For VLAN interfaces 1-4096, 0 for non-vlan interfaces + * @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) +@@ -2108,6 +2110,7 @@ struct ieee80211_key_conf { + u8 hw_key_idx; + s8 keyidx; + u16 flags; ++ u16 vlan_id; + s8 link_id; + u8 keylen; + u8 key[]; +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -538,6 +538,7 @@ static int ieee80211_add_key(struct wiph + break; + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_AP_VLAN: ++ key->conf.vlan_id = params->vlan_id; + /* Keys without a station are used for TX only */ + if (sta && test_sta_flag(sta, WLAN_STA_MFP)) + key->conf.flags |= IEEE80211_KEY_FLAG_RX_MGMT; +--- a/net/mac80211/driver-ops.c ++++ b/net/mac80211/driver-ops.c +@@ -116,7 +116,11 @@ int drv_sta_state(struct ieee80211_local + + might_sleep(); + +- sdata = get_bss_sdata(sdata); ++ if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD) || ++ !(old_state == IEEE80211_STA_ASSOC && ++ new_state == IEEE80211_STA_AUTHORIZED)) ++ sdata = get_bss_sdata(sdata); ++ + if (!check_sdata_in_driver(sdata)) + return -EIO; + +--- a/net/mac80211/driver-ops.h ++++ b/net/mac80211/driver-ops.h +@@ -453,7 +453,9 @@ static inline int drv_sta_add(struct iee + + might_sleep(); + +- sdata = get_bss_sdata(sdata); ++ if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) ++ sdata = get_bss_sdata(sdata); ++ + if (!check_sdata_in_driver(sdata)) + return -EIO; + +--- a/net/mac80211/key.c ++++ b/net/mac80211/key.c +@@ -166,7 +166,8 @@ static int ieee80211_key_enable_hw_accel + if (sta && !sta->uploaded) + goto out_unsupported; + +- if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { ++ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && ++ !ieee80211_hw_check(&key->local->hw, SUPPORTS_NSS_OFFLOAD)) { + /* + * The driver doesn't know anything about VLAN interfaces. + * Hence, don't send GTKs for VLAN interfaces to the driver. +@@ -610,6 +611,8 @@ ieee80211_key_alloc(u32 cipher, int idx, + */ + key->conf.flags = 0; + key->flags = 0; ++ /* VLAN ID initialised to zero for non-vlan interfaces */ ++ key->conf.vlan_id = 0; + + key->conf.link_id = -1; + key->conf.cipher = cipher; 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/ath11k_nss/902-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch new file mode 100644 index 00000000000000..12d42ddaa9ba9c --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/902-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch @@ -0,0 +1,973 @@ +From e6ecf9e1cc115b5821a880c6dccc5d8c9cd76fbd Mon Sep 17 00:00:00 2001 +From: Sathishkumar Muruganandam +Date: Tue, 15 Sep 2020 21:12:37 +0530 +Subject: [PATCH] ath11k: add WDS offload support on NSS offload for STA mode + +When 4addr is set ON for STA interface along with NSS enabled case, WDS +offload is enabled for ethernet mode. + +STA mode uses MEC (Multicast Echo Check) AST (Address Search Table) entry +to update the bridge MAC address from NSS to drop the locally generated +multicast/broadcast frames as multicast echo frames. + +AST handling and callbacks to NSS WDS APIs are added. + +Signed-off-by: Sathishkumar Muruganandam +--- + drivers/net/wireless/ath/ath11k/core.h | 8 +- + drivers/net/wireless/ath/ath11k/dp.h | 6 +- + drivers/net/wireless/ath/ath11k/dp_rx.c | 18 +- + drivers/net/wireless/ath/ath11k/dp_tx.c | 2 +- + drivers/net/wireless/ath/ath11k/peer.c | 389 +++++++++++++++++++++++++++++++- + drivers/net/wireless/ath/ath11k/peer.h | 117 ++++++++++ + drivers/net/wireless/ath/ath11k/wmi.c | 99 +++++++- + drivers/net/wireless/ath/ath11k/wmi.h | 33 +++ + 8 files changed, 658 insertions(+), 14 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -655,6 +655,7 @@ struct ath11k { + struct ath11k_pdev_wmi *wmi; + #ifdef CPTCFG_ATH11K_NSS_SUPPORT + struct ath11k_nss nss; ++ struct ath11k_peer *bss_peer; + #endif + struct ath11k_pdev_dp dp; + u8 mac_addr[ETH_ALEN]; +@@ -1065,6 +1066,8 @@ struct ath11k_base { + u32 rx_hash; + bool stats_disable; + ++ 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 +@@ -1181,13 +1181,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 +-#define HTT_T2H_PEER_MAP_INFO1_NEXT_HOP_M HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_M +-#define HTT_T2H_PEER_MAP_INFO1_NEXT_HOP_S HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_S ++#define HTT_T2H_PEER_UNMAP_INFO1_NEXT_HOP_M HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_M ++#define HTT_T2H_PEER_UNMAP_INFO1_NEXT_HOP_S HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_S ++#define HTT_T2H_PEER_UNMAP_INFO3_WDS_FREE_COUNT GENMASK(15, 0) + + struct htt_t2h_peer_unmap_event { + u32 info; + u32 mac_addr_l32; + u32 info1; ++ u32 info2; ++ u32 info3; + } __packed; + + struct htt_resp_msg { +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -1890,6 +1890,8 @@ void ath11k_dp_htt_htc_t2h_msg_handler(s + u16 peer_mac_h16; + u16 ast_hash; + u16 hw_peer_id; ++ u32 free_wds_count; ++ bool is_wds = false; + + ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "dp_htt rx msg type :0x%0x\n", type); + +@@ -1925,15 +1927,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); +- ath11k_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash, +- hw_peer_id); ++ is_wds = FIELD_GET(HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_M, ++ resp->peer_map_ev.info2); ++ ath11k_peer_map_v2_event(ab, vdev_id, peer_id, mac_addr, ast_hash, ++ hw_peer_id, is_wds); + break; + case HTT_T2H_MSG_TYPE_PEER_UNMAP: +- case HTT_T2H_MSG_TYPE_PEER_UNMAP2: + peer_id = FIELD_GET(HTT_T2H_PEER_UNMAP_INFO_PEER_ID, + resp->peer_unmap_ev.info); + ath11k_peer_unmap_event(ab, peer_id); + break; ++ case HTT_T2H_MSG_TYPE_PEER_UNMAP2: ++ peer_id = FIELD_GET(HTT_T2H_PEER_UNMAP_INFO_PEER_ID, ++ resp->peer_unmap_ev.info); ++ peer_mac_h16 = FIELD_GET(HTT_T2H_PEER_UNMAP_INFO1_MAC_ADDR_H16, ++ resp->peer_unmap_ev.info1); ++ ath11k_dp_get_mac_addr(resp->peer_map_ev.mac_addr_l32, ++ peer_mac_h16, mac_addr); ++ is_wds = FIELD_GET(HTT_T2H_PEER_UNMAP_INFO1_NEXT_HOP_M, ++ resp->peer_unmap_ev.info1); ++ free_wds_count = FIELD_GET(HTT_T2H_PEER_UNMAP_INFO3_WDS_FREE_COUNT, ++ resp->peer_unmap_ev.info3); ++ ath11k_peer_unmap_v2_event(ab, peer_id, mac_addr, is_wds, free_wds_count); ++ break; + case HTT_T2H_MSG_TYPE_PPDU_STATS_IND: + ath11k_htt_pull_ppdu_stats(ab, skb); + 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 + break; + case HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY: + /* This event is to be handled only when the driver decides to +- * use WDS offload functionality. ++ * use WDS offload functionality on NSS disabled case. + */ + break; + 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_ + 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, ++ u8* addr) ++{ ++ struct ath11k_ast_entry *ast_entry; ++ ++ lockdep_assert_held(&ab->base_lock); ++ ++ list_for_each_entry(ast_entry, &peer->ast_entry_list, ase_list) ++ if (ether_addr_equal(ast_entry->addr, addr)) ++ return ast_entry; ++ ++ return NULL; ++} ++ ++struct ath11k_ast_entry *ath11k_peer_ast_find_by_addr(struct ath11k_base *ab, ++ u8* addr) ++{ ++ struct ath11k_ast_entry *ast_entry; ++ struct ath11k_peer *peer; ++ ++ lockdep_assert_held(&ab->base_lock); ++ ++ list_for_each_entry(peer, &ab->peers, list) ++ list_for_each_entry(ast_entry, &peer->ast_entry_list, ase_list) ++ if (ether_addr_equal(ast_entry->addr, addr)) ++ return ast_entry; ++ ++ return NULL; ++} ++ ++void ath11k_peer_ast_wds_wmi_wk(struct work_struct *wk) ++{ ++ struct ath11k_ast_entry *ast_entry = container_of(wk, ++ struct ath11k_ast_entry, ++ wds_wmi_wk); ++ struct ath11k *ar; ++ struct ath11k_peer *peer; ++ int ret; ++ ++ if (!ast_entry) ++ return; ++ ++ ar = ast_entry->ar; ++ peer = ast_entry->peer; ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "ath11k_peer_ast_wds_wmi_wk action %d ast_entry %pM next_node %pM vdev %d\n", ++ ast_entry->action, ast_entry->addr, ast_entry->next_node_mac, ++ ast_entry->vdev_id); ++ ++ if (ast_entry->action == ATH11K_WDS_WMI_ADD) { ++ ret = ath11k_wmi_send_add_update_wds_entry_cmd(ar, ++ ast_entry->next_node_mac, ++ ast_entry->addr, ++ ast_entry->vdev_id, ++ true); ++ if (ret) { ++ ath11k_warn(ar->ab, "add wds_entry_cmd failed %d for %pM next_node %pM\n", ++ ret, ast_entry->addr, ++ ast_entry->next_node_mac); ++ if (peer) ++ ath11k_nss_del_wds_peer(ar, peer, ++ ast_entry->addr); ++ } ++ } else if (ast_entry->action == ATH11K_WDS_WMI_UPDATE) { ++ if (!peer) ++ return; ++ ++ ret = ath11k_wmi_send_add_update_wds_entry_cmd(ar, peer->addr, ++ ast_entry->addr, ++ ast_entry->vdev_id, ++ false); ++ if (ret) ++ ath11k_warn(ar->ab, "update wds_entry_cmd failed %d for %pM on peer %pM\n", ++ ret, ast_entry->addr, peer->addr); ++ } ++} ++ ++int ath11k_peer_add_ast(struct ath11k *ar, struct ath11k_peer *peer, ++ u8* mac_addr, enum ath11k_ast_entry_type type) ++{ ++ struct ath11k_ast_entry *ast_entry = NULL; ++ struct ath11k_base *ab = ar->ab; ++ ++ if (ab->num_ast_entries == ab->max_ast_index) { ++ ath11k_warn(ab, "failed to add ast for %pM due to insufficient ast entry resource %d in target\n", ++ mac_addr, ab->max_ast_index); ++ return -ENOBUFS; ++ } ++ ++ if (type != ATH11K_AST_TYPE_STATIC) { ++ ast_entry = ath11k_peer_ast_find_by_addr(ab, mac_addr); ++ if (ast_entry) { ++ ath11k_dbg(ab, ATH11K_DBG_MAC, "ast_entry %pM already present on peer %pM\n", ++ mac_addr, ast_entry->peer->addr); ++ return 0; ++ } ++ } ++ ++ ast_entry = kzalloc(sizeof(*ast_entry), GFP_ATOMIC); ++ if (!ast_entry) { ++ ath11k_warn(ab, "failed to alloc ast_entry for %pM\n", ++ mac_addr); ++ return -ENOMEM; ++ } ++ ++ switch (type) { ++ case ATH11K_AST_TYPE_STATIC: ++ peer->self_ast_entry = ast_entry; ++ ast_entry->type = ATH11K_AST_TYPE_STATIC; ++ break; ++ case ATH11K_AST_TYPE_SELF: ++ peer->self_ast_entry = ast_entry; ++ ast_entry->type = ATH11K_AST_TYPE_SELF; ++ break; ++ case ATH11K_AST_TYPE_WDS: ++ ast_entry->type = ATH11K_AST_TYPE_WDS; ++ ast_entry->next_hop = 1; ++ break; ++ case ATH11K_AST_TYPE_MEC: ++ ast_entry->type = ATH11K_AST_TYPE_MEC; ++ ast_entry->next_hop = 1; ++ break; ++ default: ++ ath11k_warn(ab, "unsupported ast_type %d", type); ++ kfree(ast_entry); ++ return -EINVAL; ++ } ++ ++ INIT_LIST_HEAD(&ast_entry->ase_list); ++ INIT_WORK(&ast_entry->wds_wmi_wk, ath11k_peer_ast_wds_wmi_wk); ++ ast_entry->vdev_id = peer->vdev_id; ++ ast_entry->pdev_idx = peer->pdev_idx; ++ ast_entry->is_mapped = false; ++ ast_entry->is_active = true; ++ ast_entry->peer = peer; ++ ast_entry->ar = ar; ++ ether_addr_copy(ast_entry->addr, mac_addr); ++ ++ list_add_tail(&ast_entry->ase_list, &peer->ast_entry_list); ++ ++ ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_add_ast peer %pM ast_entry %pM, ast_type %d\n", ++ peer->addr, mac_addr, ast_entry->type); ++ ++ if (type == ATH11K_AST_TYPE_MEC) ++ ether_addr_copy(ast_entry->next_node_mac, ar->mac_addr); ++ else if (type == ATH11K_AST_TYPE_WDS) ++ ether_addr_copy(ast_entry->next_node_mac, peer->addr); ++ ++ if ((ast_entry->type == ATH11K_AST_TYPE_WDS) || ++ (ast_entry->type == ATH11K_AST_TYPE_MEC)) { ++ ath11k_nss_add_wds_peer(ar, peer, mac_addr, ast_entry->type); ++ ast_entry->action = ATH11K_WDS_WMI_ADD; ++ ieee80211_queue_work(ar->hw, &ast_entry->wds_wmi_wk); ++ } ++ ++ ab->num_ast_entries++; ++ return 0; ++} ++ ++int ath11k_peer_update_ast(struct ath11k *ar, struct ath11k_peer *peer, ++ struct ath11k_ast_entry *ast_entry) ++{ ++ struct ath11k_peer *old_peer = ast_entry->peer; ++ struct ath11k_base *ab = ar->ab; ++ ++ if (!ast_entry->is_mapped) { ++ ath11k_warn(ab, "ath11k_peer_update_ast: ast_entry %pM not mapped yet\n", ++ ast_entry->addr); ++ return -EINVAL; ++ } ++ ++ if (ether_addr_equal(old_peer->addr, peer->addr) && ++ (ast_entry->type == ATH11K_AST_TYPE_WDS) && ++ (ast_entry->vdev_id == peer->vdev_id) && ++ (ast_entry->is_active)) ++ return 0; ++ ++ ast_entry->vdev_id = peer->vdev_id; ++ ast_entry->pdev_idx = peer->pdev_idx; ++ ast_entry->type = ATH11K_AST_TYPE_WDS; ++ ast_entry->is_active = true; ++ ast_entry->peer = peer; ++ ++ list_move_tail(&ast_entry->ase_list, &peer->ast_entry_list); ++ ++ 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); ++ ++ flush_work(&ast_entry->wds_wmi_wk); ++ ast_entry->action = ATH11K_WDS_WMI_UPDATE; ++ ieee80211_queue_work(ar->hw, &ast_entry->wds_wmi_wk); ++ ++ return 0; ++} ++ ++void ath11k_peer_map_ast(struct ath11k *ar, struct ath11k_peer *peer, ++ u8* mac_addr, u16 hw_peer_id, u16 ast_hash) ++{ ++ struct ath11k_ast_entry *ast_entry = NULL; ++ struct ath11k_base *ab = ar->ab; ++ ++ if (!peer) ++ return; ++ ++ ast_entry = ath11k_peer_ast_find_by_peer(ab, peer, mac_addr); ++ ++ if (ast_entry) { ++ ast_entry->ast_idx = hw_peer_id; ++ ast_entry->is_active = true; ++ ast_entry->is_mapped = true; ++ ast_entry->ast_hash_value = ast_hash; ++ ++ if ((ast_entry->type == ATH11K_AST_TYPE_WDS) || ++ (ast_entry->type == ATH11K_AST_TYPE_MEC)) ++ ath11k_nss_map_wds_peer(ar, peer, mac_addr, ++ ast_entry->type); ++ ++ ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_map_ast peer %pM ast_entry %pM\n", ++ peer->addr, ast_entry->addr); ++ } ++ ++} ++ ++void ath11k_peer_del_ast(struct ath11k *ar, struct ath11k_ast_entry *ast_entry) ++{ ++ struct ath11k_peer *peer; ++ struct ath11k_base *ab = ar->ab; ++ ++ if (!ast_entry || !ast_entry->peer) ++ return; ++ ++ peer = ast_entry->peer; ++ ++ ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_del_ast peer %pM ast_entry %pM\n", ++ peer->addr, ast_entry->addr); ++ ++ if (ast_entry->is_mapped) ++ list_del(&ast_entry->ase_list); ++ ++ /* WDS, MEC type AST entries need to be deleted on NSS */ ++ if (ast_entry->next_hop) ++ ath11k_nss_del_wds_peer(ar, peer, ast_entry->addr); ++ ++ cancel_work_sync(&ast_entry->wds_wmi_wk); ++ kfree(ast_entry); ++ ++ ab->num_ast_entries--; ++} ++ ++void ath11k_peer_ast_cleanup(struct ath11k *ar, struct ath11k_peer *peer, ++ bool is_wds, u32 free_wds_count) ++{ ++ struct ath11k_ast_entry *ast_entry, *tmp; ++ u32 ast_deleted_count = 0; ++ ++ if (peer->self_ast_entry) { ++ ath11k_peer_del_ast(ar, peer->self_ast_entry); ++ peer->self_ast_entry = NULL; ++ } ++ ++ list_for_each_entry_safe(ast_entry, tmp, &peer->ast_entry_list, ++ ase_list) { ++ if ((ast_entry->type == ATH11K_AST_TYPE_WDS) || ++ (ast_entry->type == ATH11K_AST_TYPE_MEC)) ++ ast_deleted_count++; ++ ath11k_peer_del_ast(ar, ast_entry); ++ } ++ ++ if (!is_wds) { ++ if (ast_deleted_count != free_wds_count) ++ ath11k_warn(ar->ab, "ast_deleted_count (%d) mismatch on peer %pM free_wds_count (%d)!\n", ++ ast_deleted_count, peer->addr, free_wds_count); ++ else ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "ast_deleted_count (%d) on peer %pM free_wds_count (%d)\n", ++ ast_deleted_count, peer->addr, free_wds_count); ++ } ++} ++#endif ++ + void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id) + { + struct ath11k_peer *peer; +@@ -118,11 +399,67 @@ exit: + spin_unlock_bh(&ab->base_lock); + } + ++void ath11k_peer_unmap_v2_event(struct ath11k_base *ab, u16 peer_id, u8 *mac_addr, ++ bool is_wds, u32 free_wds_count) ++{ ++ struct ath11k_peer *peer; ++ struct ath11k *ar; ++ ++ spin_lock_bh(&ab->base_lock); ++ ++ peer = ath11k_peer_find_list_by_id(ab, peer_id); ++ if (!peer) { ++ ath11k_warn(ab, "peer-unmap-event: unknown peer id %d\n", ++ peer_id); ++ goto exit; ++ } ++ ++ rcu_read_lock(); ++ ar = ath11k_mac_get_ar_by_vdev_id(ab, peer->vdev_id); ++ if (!ar) { ++ ath11k_warn(ab, "peer-unmap-event: unknown peer vdev id %d\n", ++ peer->vdev_id); ++ goto free_peer; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "htt peer unmap vdev %d peer %pM id %d is_wds %d free_wds_count %d\n", ++ peer->vdev_id, peer->addr, peer_id, is_wds, free_wds_count); ++ ++ if (ab->nss.enabled) { ++ if (is_wds) { ++ struct ath11k_ast_entry *ast_entry = ++ ath11k_peer_ast_find_by_peer(ab, peer, mac_addr); ++ ++ if (ast_entry) ++ ath11k_peer_del_ast(ar, ast_entry); ++ rcu_read_unlock(); ++ goto exit; ++ } else ++ ath11k_peer_ast_cleanup(ar, peer, is_wds, free_wds_count); ++ } ++ ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ if (ar->bss_peer && ether_addr_equal(ar->bss_peer->addr, peer->addr)) ++ ar->bss_peer = NULL; ++#endif ++free_peer: ++ rcu_read_unlock(); ++ list_del(&peer->list); ++ kfree(peer); ++ wake_up(&ab->peer_mapping_wq); ++ ++exit: ++ spin_unlock_bh(&ab->base_lock); ++} ++ + void ath11k_peer_map_event(struct ath11k_base *ab, u8 vdev_id, u16 peer_id, + u8 *mac_addr, u16 ast_hash, u16 hw_peer_id) + { + struct ath11k_peer *peer; ++ struct ath11k *ar = NULL; + ++ rcu_read_lock(); ++ ar = ath11k_mac_get_ar_by_vdev_id(ab, vdev_id); + 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 + ether_addr_copy(peer->addr, mac_addr); + list_add(&peer->list, &ab->peers); + wake_up(&ab->peer_mapping_wq); +- if (ab->nss.enabled) +- ath11k_nss_peer_create(ab, peer); ++ if (ab->nss.enabled && ar) ++ ath11k_nss_peer_create(ar, peer); + } + + 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 + + exit: + spin_unlock_bh(&ab->base_lock); ++ rcu_read_unlock(); ++} ++ ++void ath11k_peer_map_v2_event(struct ath11k_base *ab, u8 vdev_id, u16 peer_id, ++ u8 *mac_addr, u16 ast_hash, u16 hw_peer_id, ++ bool is_wds) ++{ ++ struct ath11k_peer *peer; ++ struct ath11k *ar = NULL; ++ int ret; ++ ++ rcu_read_lock(); ++ ar = ath11k_mac_get_ar_by_vdev_id(ab, vdev_id); ++ spin_lock_bh(&ab->base_lock); ++ peer = ath11k_peer_find(ab, vdev_id, mac_addr); ++ if (!peer && !is_wds) { ++ peer = kzalloc(sizeof(*peer), GFP_ATOMIC); ++ if (!peer) { ++ ath11k_warn(ab, "failed to allocated peer for %pM vdev_id %d\n", ++ mac_addr, vdev_id); ++ spin_unlock_bh(&ab->base_lock); ++ goto exit; ++ } ++ ++ peer->vdev_id = vdev_id; ++ peer->peer_id = peer_id; ++ peer->ast_hash = ast_hash; ++ peer->hw_peer_id = hw_peer_id; ++ ether_addr_copy(peer->addr, mac_addr); ++ list_add(&peer->list, &ab->peers); ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ INIT_LIST_HEAD(&peer->ast_entry_list); ++#endif ++ if (ab->nss.enabled && ar) { ++ ret = ath11k_nss_peer_create(ar, peer); ++ if (ret) { ++ ath11k_warn(ab, "failed to do nss peer create: %d\n", ++ ret); ++ goto peer_free; ++ } ++ } ++ wake_up(&ab->peer_mapping_wq); ++ } ++ ++ if (is_wds) ++ peer = ath11k_peer_find_by_id(ab, peer_id); ++ ++ if (ab->nss.enabled && ar) ++ ath11k_peer_map_ast(ar, peer, mac_addr, hw_peer_id, ast_hash); ++ ++ ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "htt peer map vdev %d peer %pM id %d is_wds %d\n", ++ vdev_id, mac_addr, peer_id, is_wds); ++ ++ spin_unlock_bh(&ab->base_lock); ++ goto exit; ++ ++peer_free: ++ spin_unlock_bh(&ab->base_lock); ++ mutex_lock(&ar->conf_mutex); ++ ath11k_peer_delete(ar, vdev_id, mac_addr); ++ mutex_unlock(&ar->conf_mutex); ++exit: ++ rcu_read_unlock(); + } + + static int ath11k_wait_for_peer_common(struct ath11k_base *ab, int vdev_id, +@@ -242,20 +642,34 @@ err_clean: + + void ath11k_peer_cleanup(struct ath11k *ar, u32 vdev_id) + { +- struct ath11k_peer *peer, *tmp; ++ struct ath11k_peer *peer, *tmp_peer; + struct ath11k_base *ab = ar->ab; ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ struct ath11k_ast_entry *ast_entry, *tmp_ast; ++#endif + + lockdep_assert_held(&ar->conf_mutex); + + mutex_lock(&ab->tbl_mtx_lock); + spin_lock_bh(&ab->base_lock); +- list_for_each_entry_safe(peer, tmp, &ab->peers, list) { ++ list_for_each_entry_safe(peer, tmp_peer, &ab->peers, list) { + if (peer->vdev_id != vdev_id) + continue; + + ath11k_warn(ab, "removing stale peer %pM from vdev_id %d\n", + peer->addr, vdev_id); + ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ if (peer->self_ast_entry) { ++ ath11k_peer_del_ast(ar, peer->self_ast_entry); ++ peer->self_ast_entry = NULL; ++ } ++ ++ list_for_each_entry_safe(ast_entry, tmp_ast, ++ &peer->ast_entry_list, ase_list) ++ ath11k_peer_del_ast(ar, ast_entry); ++#endif ++ + ath11k_peer_rhash_delete(ab, peer); + list_del(&peer->list); + kfree(peer); +@@ -302,7 +716,7 @@ static int __ath11k_peer_delete(struct a + lockdep_assert_held(&ar->conf_mutex); + + reinit_completion(&ar->peer_delete_done); +- ath11k_nss_peer_delete(ar->ab, addr); ++ ath11k_nss_peer_delete(ar->ab, vdev_id, addr); + + mutex_lock(&ab->tbl_mtx_lock); + spin_lock_bh(&ab->base_lock); +@@ -377,6 +791,7 @@ int ath11k_peer_create(struct ath11k *ar + struct ieee80211_sta *sta, struct peer_create_params *param) + { + struct ath11k_peer *peer; ++ struct ieee80211_vif *vif = arvif->vif; + 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; + peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; +- peer->vif = arvif->vif; ++ peer->vif = 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) { +--- a/drivers/net/wireless/ath/ath11k/peer.h ++++ b/drivers/net/wireless/ath/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 */ ++ ATH11K_AST_TYPE_STATIC, /* static ast entry for connected peer */ ++ ATH11K_AST_TYPE_SELF, /* static ast entry for self peer (STA mode) */ ++ ATH11K_AST_TYPE_WDS, /* WDS peer ast entry type*/ ++ ATH11K_AST_TYPE_MEC, /* Multicast echo ast entry type */ ++ ATH11K_AST_TYPE_WDS_HM, /* HM WDS entry */ ++ ATH11K_AST_TYPE_STA_BSS, /* BSS entry(STA mode) */ ++ ATH11K_AST_TYPE_DA, /* AST entry based on Destination address */ ++ ATH11K_AST_TYPE_WDS_HM_SEC, /* HM WDS entry for secondary radio */ ++ ATH11K_AST_TYPE_MAX ++}; ++ ++enum ath11k_wds_wmi_action { ++ ATH11K_WDS_WMI_ADD = 1, ++ ATH11K_WDS_WMI_UPDATE, ++ ++ ATH11K_WDS_WMI_MAX ++}; ++ ++struct ath11k_ast_entry { ++ u16 ast_idx; ++ u8 addr[ETH_ALEN]; ++ u8 next_node_mac[ETH_ALEN]; ++ enum ath11k_wds_wmi_action action; ++ struct work_struct wds_wmi_wk; ++ struct ath11k_peer *peer; ++ struct ath11k *ar; ++ bool next_hop; ++ bool is_active; ++ bool is_mapped; ++ u8 pdev_idx; ++ u8 vdev_id; ++ 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 ath11k_peer { + struct list_head list; + struct ieee80211_sta *sta; +@@ -29,6 +70,10 @@ struct ath11k_peer { + u8 pdev_idx; + u16 hw_peer_id; + struct ath11k_nss_peer nss; ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ struct ath11k_ast_entry *self_ast_entry; ++ struct list_head ast_entry_list; ++#endif + + /* protected by ab->data_lock */ + struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; +@@ -54,8 +99,13 @@ struct ath11k_peer { + }; + + void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id); ++void ath11k_peer_unmap_v2_event(struct ath11k_base *ab, u16 peer_id, u8 *mac_addr, ++ bool is_wds, u32 free_wds_count); + void ath11k_peer_map_event(struct ath11k_base *ab, u8 vdev_id, u16 peer_id, + u8 *mac_addr, u16 ast_hash, u16 hw_peer_id); ++void ath11k_peer_map_v2_event(struct ath11k_base *ab, u8 vdev_id, u16 peer_id, ++ u8 *mac_addr, u16 ast_hash, u16 hw_peer_id, ++ bool is_wds); + 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, +@@ -72,4 +122,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); ++ ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++struct ath11k_ast_entry *ath11k_peer_ast_find_by_addr(struct ath11k_base *ab, ++ u8* addr); ++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, ++ struct ath11k_ast_entry *ast_entry); ++void ath11k_peer_map_ast(struct ath11k *ar, struct ath11k_peer *peer, ++ u8* mac_addr, u16 hw_peer_id, u16 ast_hash); ++void ath11k_peer_del_ast(struct ath11k *ar, struct ath11k_ast_entry *ast_entry); ++void ath11k_peer_ast_cleanup(struct ath11k *ar, struct ath11k_peer *peer, ++ bool is_wds, u32 free_wds_count); ++void ath11k_peer_ast_wds_wmi_wk(struct work_struct *wk); ++struct ath11k_ast_entry *ath11k_peer_ast_find_by_peer(struct ath11k_base *ab, ++ struct ath11k_peer *peer, ++ u8* addr); ++#else ++static inline struct ath11k_ast_entry *ath11k_peer_ast_find_by_addr(struct ath11k_base *ab, ++ u8* addr) ++{ ++ return NULL; ++} ++ ++static inline int ath11k_peer_add_ast(struct ath11k *ar, struct ath11k_peer *peer, ++ u8* mac_addr, enum ath11k_ast_entry_type type) ++{ ++ return 0; ++} ++ ++static inline int ath11k_peer_update_ast(struct ath11k *ar, struct ath11k_peer *peer, ++ struct ath11k_ast_entry *ast_entry) ++{ ++ return 0; ++} ++ ++static inline void ath11k_peer_map_ast(struct ath11k *ar, struct ath11k_peer *peer, ++ u8* mac_addr, u16 hw_peer_id, u16 ast_hash) ++{ ++ return; ++} ++ ++static inline void ath11k_peer_del_ast(struct ath11k *ar, ++ struct ath11k_ast_entry *ast_entry) ++{ ++ return; ++} ++ ++static inline void ath11k_peer_ast_cleanup(struct ath11k *ar, ++ struct ath11k_peer *peer, ++ bool is_wds, u32 free_wds_count) ++{ ++ return; ++} ++ ++static inline void ath11k_peer_ast_wds_wmi_wk(struct work_struct *wk) ++{ ++ return; ++} ++ ++static inline struct ath11k_ast_entry *ath11k_peer_ast_find_by_peer(struct ath11k_base *ab, ++ struct ath11k_peer *peer, ++ u8* addr) ++{ ++ return NULL; ++} ++#endif /* CPTCFG_ATH11K_NSS_SUPPORT */ + #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" }, + [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" }, + }; + + #define PRIMAP(_hw_mode_) \ +@@ -1174,6 +1175,51 @@ int ath11k_wmi_send_peer_delete_cmd(stru + return ret; + } + ++int ath11k_wmi_send_add_update_wds_entry_cmd(struct ath11k *ar, ++ const u8 *peer_addr, ++ const u8 *wds_addr, u8 vdev_id, ++ bool add_wds) ++{ ++ struct ath11k_pdev_wmi *wmi = ar->wmi; ++ struct wmi_add_wds_entry_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_add_wds_entry_cmd *)skb->data; ++ if (add_wds) ++ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PEER_ADD_WDS_ENTRY_CMD) | ++ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); ++ else ++ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PEER_UPDATE_WDS_ENTRY_CMD) | ++ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); ++ ++ ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); ++ ether_addr_copy(cmd->wds_macaddr.addr, wds_addr); ++ cmd->vdev_id = vdev_id; ++ cmd->flags = WMI_WDS_FLAG_STATIC; ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, ++ "WMI add WDS entry vdev_id %d peer_addr %pM, wds_addr %pM flags %x\n", ++ vdev_id, peer_addr, wds_addr, cmd->flags); ++ ++ if (add_wds) ++ ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PEER_ADD_WDS_ENTRY_CMDID); ++ else ++ ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PEER_UPDATE_WDS_ENTRY_CMDID); ++ ++ if (ret) { ++ ath11k_warn(ar->ab, "failed to send WMI_PEER_%s_WDS_ENTRY cmd\n", ++ add_wds ? "ADD" : "UPDATE"); ++ dev_kfree_skb(skb); ++ } ++ ++ return ret; ++} ++ + int ath11k_wmi_send_pdev_set_regdomain(struct ath11k *ar, + struct pdev_set_regdomain_params *param) + { +@@ -6484,6 +6530,36 @@ static int ath11k_pull_peer_assoc_conf_e + return 0; + } + ++static int ath11k_pull_wds_addr_ev(struct ath11k_base *ab, struct sk_buff *skb, ++ struct wmi_wds_addr_arg *wds_addr_arg) ++{ ++ const void **tb; ++ const struct wmi_wds_addr_event *ev; ++ 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 ret; ++ } ++ ++ ev = tb[WMI_TAG_WDS_ADDR_EVENT]; ++ if (!ev) { ++ ath11k_warn(ab, "failed to fetch wds peer ev"); ++ kfree(tb); ++ return -EPROTO; ++ } ++ ++ memcpy(wds_addr_arg->event_type, ev->event_type, WMI_NUM_WDS_EVENTS); ++ wds_addr_arg->vdev_id = ev->vdev_id; ++ wds_addr_arg->peer_macaddr = ev->peer_macaddr.addr; ++ wds_addr_arg->dst_macaddr = ev->dst_macaddr.addr; ++ ++ kfree(tb); ++ return 0; ++} ++ + static void ath11k_wmi_pull_pdev_stats_base(const struct wmi_pdev_stats_base *src, + struct ath11k_fw_stats_pdev *dst) + { +@@ -7399,6 +7475,7 @@ static int ath11k_wmi_tlv_rdy_parse(stru + + ether_addr_copy(ab->mac_addr, + fixed_param.ready_event_min.mac_addr.addr); ++ ab->max_ast_index = fixed_param.max_ast_index + 1; + ab->pktlog_defs_checksum = fixed_param.pktlog_defs_checksum; + break; + case WMI_TAG_ARRAY_FIXED_STRUCT: +@@ -8870,6 +8947,22 @@ static void ath11k_wmi_gtk_offload_statu + kfree(tb); + } + ++static void ath11k_wmi_wds_peer_event(struct ath11k_base *ab, ++ struct sk_buff *skb) ++{ ++ struct wmi_wds_addr_arg wds_addr_arg = {0}; ++ ++ if (ath11k_pull_wds_addr_ev(ab, skb, &wds_addr_arg) != 0) { ++ ath11k_warn(ab, "failed to extract wds addr event"); ++ return; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_WMI, ++ "wds addr event vdev id %d peer macaddr %pM dst macaddr %pM\n", ++ wds_addr_arg.vdev_id, wds_addr_arg.peer_macaddr, ++ wds_addr_arg.dst_macaddr); ++} ++ + static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb) + { + struct wmi_cmd_hdr *cmd_hdr; +@@ -9000,6 +9093,9 @@ static void ath11k_wmi_tlv_op_rx(struct + case WMI_QOS_NULL_FRAME_TX_COMPLETION_EVENTID: + ath11k_qos_null_compl_event(ab, skb); + break; ++ case WMI_WDS_PEER_EVENTID: ++ ath11k_wmi_wds_peer_event(ab, skb); ++ break; + default: + ath11k_dbg(ab, ATH11K_DBG_WMI, "unsupported event id 0x%x\n", id); + 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 { + struct wmi_mac_addr peer_macaddr; + } __packed; + ++#define WMI_WDS_FLAG_STATIC 0x1 /* Disable aging & learning */ ++struct wmi_add_wds_entry_cmd { ++ u32 tlv_header; ++ struct wmi_mac_addr peer_macaddr; ++ struct wmi_mac_addr wds_macaddr; ++ u32 flags; ++ u32 vdev_id; ++} __packed; ++ ++struct wmi_remove_wds_entry_cmd { ++ u32 tlv_header; ++ struct wmi_mac_addr wds_macaddr; ++ u32 vdev_id; ++} __packed; ++ + struct wmi_peer_reorder_queue_setup_cmd { + u32 tlv_header; + u32 vdev_id; +@@ -4629,6 +4644,21 @@ struct wmi_probe_resp_tx_status_event { + u32 tx_status; + } __packed; + ++#define WMI_NUM_WDS_EVENTS 4 ++struct wmi_wds_addr_arg { ++ u32 event_type[WMI_NUM_WDS_EVENTS]; ++ const u8 *peer_macaddr; ++ const u8 *dst_macaddr; ++ u32 vdev_id; ++}; ++ ++struct wmi_wds_addr_event { ++ u32 event_type[WMI_NUM_WDS_EVENTS]; ++ struct wmi_mac_addr peer_macaddr; ++ struct wmi_mac_addr dst_macaddr; ++ u32 vdev_id; ++} __packed; ++ + /* + * PDEV statistics + */ +@@ -6503,6 +6533,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); ++int ath11k_wmi_send_add_update_wds_entry_cmd(struct ath11k *ar, ++ const u8 *peer_addr, const u8 *wds_addr, ++ u8 vdev_id, bool add_wds); + int ath11k_wmi_vdev_delete(struct ath11k *ar, u8 vdev_id); + void ath11k_wmi_start_scan_init(struct ath11k *ar, struct scan_req_params *arg); + int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar, diff --git a/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-HE-stats-in-peer-stats.patch b/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-HE-stats-in-peer-stats.patch new file mode 100644 index 00000000000000..edb60ac18bef10 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-HE-stats-in-peer-stats.patch @@ -0,0 +1,777 @@ +From e4f16128c53b48f166301085cecc23f77bf3ff8e Mon Sep 17 00:00:00 2001 +From: Miles Hu +Date: Fri, 11 Oct 2019 19:24:06 -0700 +Subject: [PATCH] ath11k: add HE stats in peer stats packet counters for MIMO + and OFDMA + +Signed-off-by: Miles Hu +--- + drivers/net/wireless/ath/ath11k/core.h | 23 ++++- + drivers/net/wireless/ath/ath11k/debugfs_sta.c | 127 +++++++++++++++++++++++++- + drivers/net/wireless/ath/ath11k/dp.h | 21 ++++- + drivers/net/wireless/ath/ath11k/dp_rx.c | 17 +++- + drivers/net/wireless/ath/ath11k/rx_desc.h | 5 + + 5 files changed, 185 insertions(+), 8 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -29,6 +29,7 @@ + #include "dbring.h" + #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 { + 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]; ++ u64 transmit_type[ATH11K_COUNTER_TYPE_MAX][HAL_RX_RECEPTION_TYPE_MAX]; ++ u64 ru_loc[ATH11K_COUNTER_TYPE_MAX][HAL_RX_RU_ALLOC_TYPE_MAX]; + }; + + struct ath11k_htt_tx_stats { +@@ -483,6 +486,9 @@ struct ath11k_htt_tx_stats { + u64 tx_duration; + u64 ba_fails; + u64 ack_fails; ++ u16 ru_start; ++ u16 ru_tones; ++ u32 mu_group[MAX_MU_GROUP_ID]; + }; + + struct ath11k_per_ppdu_tx_stats { +@@ -615,11 +621,16 @@ struct ath11k_per_peer_tx_stats { + u32 succ_bytes; + u32 retry_bytes; + u32 failed_bytes; ++ u32 duration; + u16 succ_pkts; + u16 retry_pkts; + u16 failed_pkts; +- u32 duration; ++ u16 ru_start; ++ u16 ru_tones; + u8 ba_fails; ++ u8 ppdu_type; ++ u32 mu_grpid; ++ u32 mu_pos; + bool is_ampdu; + }; + +--- 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" + #include "debugfs_htt_stats.h" + ++static inline u32 ath11k_he_tones_in_ru_to_nl80211_he_ru_alloc(u16 ru_tones) ++{ ++ u32 ret = 0; ++ switch (ru_tones) { ++ case 26: ++ ret = NL80211_RATE_INFO_HE_RU_ALLOC_26; ++ break; ++ case 52: ++ ret = NL80211_RATE_INFO_HE_RU_ALLOC_52; ++ break; ++ case 106: ++ ret = NL80211_RATE_INFO_HE_RU_ALLOC_106; ++ break; ++ case 242: ++ ret = NL80211_RATE_INFO_HE_RU_ALLOC_242; ++ break; ++ case 484: ++ ret = NL80211_RATE_INFO_HE_RU_ALLOC_484; ++ break; ++ case 996: ++ ret = NL80211_RATE_INFO_HE_RU_ALLOC_996; ++ break; ++ } ++ return ret; ++} ++ + void ath11k_debugfs_sta_add_tx_stats(struct ath11k_sta *arsta, + struct ath11k_per_peer_tx_stats *peer_stats, + u8 legacy_rate_idx) + { + struct rate_info *txrate = &arsta->txrate; + struct ath11k_htt_tx_stats *tx_stats; +- int gi, mcs, bw, nss; ++ int gi, mcs, bw, nss, ru_type, ppdu_type; + + if (!arsta->tx_stats) + return; +@@ -63,6 +89,43 @@ void ath11k_debugfs_sta_add_tx_stats(str + STATS_OP_FMT(RETRY).legacy[1][mcs] += peer_stats->retry_pkts; + } + ++ ppdu_type = peer_stats->ppdu_type; ++ if ((ppdu_type == HTT_PPDU_STATS_PPDU_TYPE_MU_OFDMA || ++ ppdu_type == HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO_OFDMA) && ++ (txrate->flags & RATE_INFO_FLAGS_HE_MCS)){ ++ ru_type = peer_stats->ru_tones; ++ ++ if (ru_type <= NL80211_RATE_INFO_HE_RU_ALLOC_996) { ++ STATS_OP_FMT(SUCC).ru_loc[0][ru_type] += peer_stats->succ_bytes; ++ STATS_OP_FMT(SUCC).ru_loc[1][ru_type] += peer_stats->succ_pkts; ++ STATS_OP_FMT(FAIL).ru_loc[0][ru_type] += peer_stats->failed_bytes; ++ STATS_OP_FMT(FAIL).ru_loc[1][ru_type] += peer_stats->failed_pkts; ++ STATS_OP_FMT(RETRY).ru_loc[0][ru_type] += peer_stats->retry_bytes; ++ STATS_OP_FMT(RETRY).ru_loc[1][ru_type] += peer_stats->retry_pkts; ++ if (peer_stats->is_ampdu) { ++ STATS_OP_FMT(AMPDU).ru_loc[0][ru_type] += ++ peer_stats->succ_bytes + peer_stats->retry_bytes; ++ STATS_OP_FMT(AMPDU).ru_loc[1][ru_type] += ++ peer_stats->succ_pkts + peer_stats->retry_pkts; ++ } ++ } ++ } ++ ++ if (ppdu_type < HTT_PPDU_STATS_PPDU_TYPE_MAX) { ++ STATS_OP_FMT(SUCC).transmit_type[0][ppdu_type] += peer_stats->succ_bytes; ++ STATS_OP_FMT(SUCC).transmit_type[1][ppdu_type] += peer_stats->succ_pkts; ++ STATS_OP_FMT(FAIL).transmit_type[0][ppdu_type] += peer_stats->failed_bytes; ++ STATS_OP_FMT(FAIL).transmit_type[1][ppdu_type] += peer_stats->failed_pkts; ++ STATS_OP_FMT(RETRY).transmit_type[0][ppdu_type] += peer_stats->retry_bytes; ++ STATS_OP_FMT(RETRY).transmit_type[1][ppdu_type] += peer_stats->retry_pkts; ++ if (peer_stats->is_ampdu) { ++ STATS_OP_FMT(AMPDU).transmit_type[0][ppdu_type] += ++ peer_stats->succ_bytes + peer_stats->retry_bytes; ++ STATS_OP_FMT(AMPDU).transmit_type[1][ppdu_type] += ++ peer_stats->succ_pkts + peer_stats->retry_pkts; ++ } ++ } ++ + 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 + STATS_OP_FMT(RETRY).gi[1][gi] += peer_stats->retry_pkts; + + tx_stats->tx_duration += peer_stats->duration; ++ ++ tx_stats->ru_start = peer_stats->ru_start; ++ tx_stats->ru_tones = peer_stats->ru_tones; ++ ++ if (peer_stats->mu_grpid <= MAX_MU_GROUP_ID && ++ peer_stats->ppdu_type != HTT_PPDU_STATS_PPDU_TYPE_SU) { ++ if (peer_stats->mu_grpid & (MAX_MU_GROUP_ID - 1)) ++ tx_stats->mu_group[peer_stats->mu_grpid] = ++ (peer_stats->mu_pos + 1); ++ } ++ + } + + void ath11k_debugfs_sta_update_txcompl(struct ath11k *ar, +@@ -139,12 +213,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; +- static const char *str_name[ATH11K_STATS_TYPE_MAX] = {"succ", "fail", ++ static const char *str_name[ATH11K_STATS_TYPE_MAX] = {"success", "fail", + "retry", "ampdu"}; + static const char *str[ATH11K_COUNTER_TYPE_MAX] = {"bytes", "packets"}; + int len = 0, i, j, k, retval = 0; + const int size = 2 * 4096; +- char *buf; ++ 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 + len += scnprintf(buf + len, size - len, "%s_%s\n", + str_name[k], + str[j]); ++ len += scnprintf(buf + len, size - len, "==========\n"); + len += scnprintf(buf + len, size - len, +- " HE MCS %s\n", ++ " HE MCS %s\n\t", + str[j]); + for (i = 0; i < ATH11K_HE_MCS_NUM; i++) + len += scnprintf(buf + len, size - len, +- " %llu ", ++ "%llu ", + stats->he[j][i]); + len += scnprintf(buf + len, size - len, "\n"); + len += scnprintf(buf + len, size - len, +- " VHT MCS %s\n", ++ " VHT MCS %s\n\t", + str[j]); + for (i = 0; i < ATH11K_VHT_MCS_NUM; i++) + len += scnprintf(buf + len, size - len, +- " %llu ", ++ "%llu ", + stats->vht[j][i]); + len += scnprintf(buf + len, size - len, "\n"); +- len += scnprintf(buf + len, size - len, " HT MCS %s\n", ++ len += scnprintf(buf + len, size - len, " HT MCS %s\n\t", + str[j]); + for (i = 0; i < ATH11K_HT_MCS_NUM; i++) + len += scnprintf(buf + len, size - len, +- " %llu ", stats->ht[j][i]); ++ "%llu ", stats->ht[j][i]); + len += scnprintf(buf + len, size - len, "\n"); + len += scnprintf(buf + len, size - len, + " BW %s (20,40,80,160 MHz)\n", str[j]); + len += scnprintf(buf + len, size - len, +- " %llu %llu %llu %llu\n", ++ "\t%llu %llu %llu %llu\n", + stats->bw[j][0], stats->bw[j][1], + stats->bw[j][2], stats->bw[j][3]); + len += scnprintf(buf + len, size - len, + " NSS %s (1x1,2x2,3x3,4x4)\n", str[j]); + len += scnprintf(buf + len, size - len, +- " %llu %llu %llu %llu\n", ++ "\t%llu %llu %llu %llu\n", + stats->nss[j][0], stats->nss[j][1], + stats->nss[j][2], stats->nss[j][3]); + len += scnprintf(buf + len, size - len, + " GI %s (0.4us,0.8us,1.6us,3.2us)\n", + str[j]); + len += scnprintf(buf + len, size - len, +- " %llu %llu %llu %llu\n", ++ "\t%llu %llu %llu %llu\n", + 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 + for (i = 0; i < ATH11K_LEGACY_NUM; i++) + len += scnprintf(buf + len, size - len, "%llu ", + stats->legacy[j][i]); +- len += scnprintf(buf + len, size - len, "\n"); ++ ++ len += scnprintf(buf + len, size - len, "\n ru %s: \n", str[j]); ++ len += scnprintf(buf + len, size - len, ++ "\tru 26: %llu\n", stats->ru_loc[j][0]); ++ len += scnprintf(buf + len, size - len, ++ "\tru 52: %llu \n", stats->ru_loc[j][1]); ++ len += scnprintf(buf + len, size - len, ++ "\tru 106: %llu \n", stats->ru_loc[j][2]); ++ len += scnprintf(buf + len, size - len, ++ "\tru 242: %llu \n", stats->ru_loc[j][3]); ++ len += scnprintf(buf + len, size - len, ++ "\tru 484: %llu \n", stats->ru_loc[j][4]); ++ len += scnprintf(buf + len, size - len, ++ "\tru 996: %llu \n", stats->ru_loc[j][5]); ++ ++ len += scnprintf(buf + len, size - len, ++ " ppdu type %s: \n", str[j]); ++ if (k == ATH11K_STATS_TYPE_FAIL || ++ k == ATH11K_STATS_TYPE_RETRY) { ++ len += scnprintf(buf + len, size - len, ++ "\tSU/MIMO: %llu\n", ++ stats->transmit_type[j][0]); ++ len += scnprintf(buf + len, size - len, ++ "\tOFDMA/OFDMA_MIMO: %llu\n", ++ stats->transmit_type[j][2]); ++ } else { ++ len += scnprintf(buf + len, size - len, ++ "\tSU: %llu\n", ++ stats->transmit_type[j][0]); ++ len += scnprintf(buf + len, size - len, ++ "\tMIMO: %llu\n", ++ stats->transmit_type[j][1]); ++ len += scnprintf(buf + len, size - len, ++ "\tOFDMA: %llu\n", ++ stats->transmit_type[j][2]); ++ len += scnprintf(buf + len, size - len, ++ "\tOFDMA_MIMO: %llu\n", ++ stats->transmit_type[j][3]); ++ } + } + } + ++ len += scnprintf(buf + len, size - len, "\n"); ++ ++ for (i = 0; i < MAX_MU_GROUP_ID;) { ++ index = 0; ++ for (j = 0; j < MAX_MU_GROUP_SHOW && i < MAX_MU_GROUP_ID; ++ j++) { ++ index += snprintf(&mu_group_id[index], ++ MAX_MU_GROUP_LENGTH - index, ++ " %d", ++ arsta->tx_stats->mu_group[i]); ++ i++; ++ } ++ len += scnprintf(buf + len, size - len, ++ "User position list for GID %02d->%d: [%s]\n", ++ i - MAX_MU_GROUP_SHOW, i - 1, mu_group_id); ++ } ++ len += scnprintf(buf + len, size - len, ++ "\nLast Packet RU index [%d], Size [%d]\n", ++ arsta->tx_stats->ru_start, arsta->tx_stats->ru_tones); ++ + 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 + "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); ++ + spin_unlock_bh(&ar->data_lock); + + 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 { + BIT(HTT_PPDU_STATS_TAG_TX_MGMTCTRL_PAYLOAD) | \ + HTT_PPDU_STATS_TAG_DEFAULT) + ++#define HTT_STATS_FRAMECTRL_TYPE_MASK 0x0C ++#define HTT_STATS_GET_FRAME_CTRL_TYPE(_val) \ ++ (((_val) & HTT_STATS_FRAMECTRL_TYPE_MASK) >> 2) ++#define HTT_STATS_FRAME_CTRL_TYPE_MGMT 0x0 ++#define HTT_STATS_FRAME_CTRL_TYPE_CTRL 0x1 ++#define HTT_STATS_FRAME_CTRL_TYPE_DATA 0x2 ++#define HTT_STATS_FRAME_CTRL_TYPE_RESV 0x3 ++ ++enum htt_stats_frametype { ++ HTT_STATS_FTYPE_SGEN_NDPA = 0, ++ HTT_STATS_FTYPE_SGEN_NDP, ++ HTT_STATS_FTYPE_SGEN_BRP, ++ HTT_STATS_FTYPE_SGEN_BAR, ++ HTT_STATS_FTYPE_SGEN_RTS, ++ HTT_STATS_FTYPE_SGEN_CTS, ++ HTT_STATS_FTYPE_SGEN_CFEND, ++ HTT_STATS_FTYPE_SGEN_AX_NDPA, ++ HTT_STATS_FTYPE_SGEN_AX_NDP, ++ HTT_STATS_FTYPE_SGEN_MU_TRIG, ++ HTT_STATS_FTYPE_SGEN_MU_BAR, ++ HTT_STATS_FTYPE_SGEN_MU_BRP, ++ HTT_STATS_FTYPE_SGEN_MU_RTS, ++ HTT_STATS_FTYPE_SGEN_MU_BSR, ++ HTT_STATS_FTYPE_SGEN_UL_BSR, ++ HTT_STATS_FTYPE_SGEN_UL_BSR_TRIGGER = HTT_STATS_FTYPE_SGEN_UL_BSR, ++ HTT_STATS_FTYPE_TIDQ_DATA_SU, ++ HTT_STATS_FTYPE_TIDQ_DATA_MU, ++ HTT_STATS_FTYPE_SGEN_UL_BSR_RESP, ++ HTT_STATS_FTYPE_SGEN_QOS_NULL, ++ HTT_STATS_FTYPE_MAX, ++}; ++ ++enum htt_stats_internal_ppdu_frametype { ++ HTT_STATS_PPDU_FTYPE_CTRL, ++ HTT_STATS_PPDU_FTYPE_DATA, ++ HTT_STATS_PPDU_FTYPE_BAR, ++ HTT_STATS_PPDU_FTYPE_MAX ++}; ++ + /* HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG Message + * + * details: +@@ -1312,6 +1351,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) + ++enum HTT_PPDU_STATS_PPDU_TYPE { ++ HTT_PPDU_STATS_PPDU_TYPE_SU, ++ HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO, ++ HTT_PPDU_STATS_PPDU_TYPE_MU_OFDMA, ++ HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO_OFDMA, ++ HTT_PPDU_STATS_PPDU_TYPE_UL_TRIG, ++ HTT_PPDU_STATS_PPDU_TYPE_BURST_BCN, ++ HTT_PPDU_STATS_PPDU_TYPE_UL_BSR_RESP, ++ HTT_PPDU_STATS_PPDU_TYPE_UL_BSR_TRIG, ++ HTT_PPDU_STATS_PPDU_TYPE_UL_RESP, ++ HTT_PPDU_STATS_PPDU_TYPE_MAX ++}; ++ + #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) + +@@ -1339,6 +1391,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) ++#define HTT_USR_RATE_PPDU_TYPE(_val) \ ++ FIELD_GET(HTT_PPDU_STATS_USER_RATE_INFO1_PPDU_TYPE_M, _val) ++#define HTT_USR_RATE_MU_GRPID(_val) \ ++ FIELD_GET(HTT_PPDU_STATS_USER_RATE_INFO0_MU_GROUP_ID_M, _val) ++#define HTT_USR_RATE_USR_POS(_val) \ ++ FIELD_GET(HTT_PPDU_STATS_USER_RATE_INFO0_USER_POS_M, _val) + + #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) +@@ -1442,6 +1500,21 @@ struct htt_ppdu_stats_usr_cmpltn_ack_ba_ + u32 success_bytes; + } __packed; + ++#define HTT_PPDU_STATS_USR_CMN_FLAG_DELAYBA BIT(14) ++#define HTT_PPDU_STATS_USR_CMN_HDR_SW_PEERID GENMASK(31, 16) ++#define HTT_PPDU_STATS_USR_CMN_CTL_FRM_CTRL GENMASK(15, 0) ++ ++struct htt_ppdu_stats_user_common { ++ u8 tid_num; ++ u8 vdev_id; ++ u16 sw_peer_id; ++ u32 info; ++ u32 ctrl; ++ u32 buffer_paddr_31_0; ++ u32 buffer_paddr_39_32; ++ u32 host_opaque_cookie; ++} __packed; ++ + struct htt_ppdu_stats_usr_cmn_array { + struct htt_tlv tlv_hdr; + u32 num_ppdu_stats; +@@ -1455,14 +1528,16 @@ struct htt_ppdu_stats_usr_cmn_array { + + struct htt_ppdu_user_stats { + u16 peer_id; ++ u16 delay_ba; + u32 tlv_flags; + bool is_valid_peer_id; + 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; + }; + +-#define HTT_PPDU_STATS_MAX_USERS 8 ++#define HTT_PPDU_STATS_MAX_USERS 37 + #define HTT_PPDU_DESC_MAX_DEPTH 16 + + struct htt_ppdu_stats { +@@ -1471,7 +1546,7 @@ struct htt_ppdu_stats { + }; + + struct htt_ppdu_stats_info { +- u32 ppdu_id; ++ u32 tlv_bitmap, ppdu_id, frame_type, frame_ctrl, delay_ba, bar_num_users; + struct htt_ppdu_stats ppdu_stats; + struct list_head list; + }; +--- 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 + void *data) + { + struct htt_ppdu_stats_info *ppdu_info; +- struct htt_ppdu_user_stats *user_stats; ++ struct htt_ppdu_user_stats *user_stats = NULL; + int cur_user; + u16 peer_id; ++ u32 frame_type; + + ppdu_info = data; + +@@ -1334,6 +1335,26 @@ static int ath11k_htt_tlv_ppdu_stats_par + } + memcpy((void *)&ppdu_info->ppdu_stats.common, ptr, + sizeof(struct htt_ppdu_stats_common)); ++ frame_type = ++ FIELD_GET(HTT_PPDU_STATS_CMN_FLAGS_FRAME_TYPE_M, ++ ppdu_info->ppdu_stats.common.flags); ++ switch (frame_type) { ++ case HTT_STATS_FTYPE_TIDQ_DATA_SU: ++ case HTT_STATS_FTYPE_TIDQ_DATA_MU: ++ if (HTT_STATS_GET_FRAME_CTRL_TYPE(ppdu_info->frame_ctrl) <= HTT_STATS_FRAME_CTRL_TYPE_CTRL) ++ ppdu_info->frame_type = HTT_STATS_PPDU_FTYPE_CTRL; ++ else ++ ppdu_info->frame_type = HTT_STATS_PPDU_FTYPE_DATA; ++ break; ++ case HTT_STATS_FTYPE_SGEN_MU_BAR: ++ case HTT_STATS_FTYPE_SGEN_BAR: ++ ppdu_info->frame_type = HTT_STATS_PPDU_FTYPE_BAR; ++ break; ++ default: ++ ppdu_info->frame_type = HTT_STATS_PPDU_FTYPE_CTRL; ++ break; ++ } ++ + 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 + peer_id); + if (cur_user < 0) + return -EINVAL; ++ ppdu_info->bar_num_users += 1; + 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 + sizeof(struct htt_ppdu_stats_usr_cmpltn_ack_ba_status)); + user_stats->tlv_flags |= BIT(tag); + break; +- } +- return 0; +-} +- +-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), +- void *data) +-{ +- const struct htt_tlv *tlv; +- const void *begin = ptr; +- u16 tlv_tag, tlv_len; +- int ret = -EINVAL; +- +- while (len > 0) { +- if (len < sizeof(*tlv)) { +- ath11k_err(ab, "htt tlv parse failure at byte %zd (%zu bytes left, %zu expected)\n", +- ptr - begin, len, sizeof(*tlv)); ++ case HTT_PPDU_STATS_TAG_USR_COMMON: ++ if (len < sizeof(struct htt_ppdu_stats_user_common)) { ++ ath11k_warn(ab, "Invalid len %d for the tag 0x%x\n", ++ len, tag); + return -EINVAL; + } +- tlv = (struct htt_tlv *)ptr; +- tlv_tag = FIELD_GET(HTT_TLV_TAG, tlv->header); +- tlv_len = FIELD_GET(HTT_TLV_LEN, tlv->header); +- ptr += sizeof(*tlv); +- len -= sizeof(*tlv); +- +- if (tlv_len > len) { +- ath11k_err(ab, "htt tlv parse failure of tag %u at byte %zd (%zu bytes left, %u expected)\n", +- tlv_tag, ptr - begin, len, tlv_len); ++ peer_id = ((struct htt_ppdu_stats_user_common *)ptr)->sw_peer_id; ++ cur_user = ath11k_get_ppdu_user_index(&ppdu_info->ppdu_stats, ++ peer_id); ++ if (cur_user < 0) + return -EINVAL; +- } +- ret = iter(ab, tlv_tag, tlv_len, ptr, data); +- if (ret == -ENOMEM) +- return ret; +- +- ptr += tlv_len; +- len -= tlv_len; ++ user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user]; ++ memcpy(&user_stats->common, ptr, ++ sizeof(struct htt_ppdu_stats_user_common)); ++ ppdu_info->frame_ctrl = FIELD_GET(HTT_PPDU_STATS_USR_CMN_CTL_FRM_CTRL, ++ user_stats->common.ctrl); ++ user_stats->delay_ba = FIELD_GET(HTT_PPDU_STATS_USR_CMN_FLAG_DELAYBA, ++ user_stats->common.info); ++ ppdu_info->delay_ba = user_stats->delay_ba; ++ break; ++ default: ++ break; + } ++ ppdu_info->tlv_bitmap |= BIT(tag); + return 0; + } + +@@ -1449,8 +1457,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; +- u32 succ_bytes = 0; +- u16 rate = 0, succ_pkts = 0; ++ u32 succ_bytes = 0, ppdu_type, mu_grpid, mu_pos; ++ u16 rate = 0, succ_pkts = 0, ru_tone, ru_start; + 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 + 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); ++ ppdu_type = HTT_USR_RATE_PPDU_TYPE(user_rate->info1); ++ mu_grpid = HTT_USR_RATE_MU_GRPID(user_rate->info0); ++ mu_pos = HTT_USR_RATE_USR_POS(user_rate->info0); ++ ru_start = user_rate->ru_start; ++ ru_tone = user_rate->ru_end; + + /* 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 + peer_stats->ba_fails = + HTT_USR_CMPLTN_LONG_RETRY(usr_stats->cmpltn_cmn.flags) + + HTT_USR_CMPLTN_SHORT_RETRY(usr_stats->cmpltn_cmn.flags); ++ peer_stats->ppdu_type = ppdu_type; ++ peer_stats->ru_tones = ru_tone; ++ peer_stats->ru_start = ru_start; ++ peer_stats->mu_grpid = mu_grpid; ++ peer_stats->mu_pos = mu_pos; ++ peer_stats->ru_tones = arsta->txrate.he_ru_alloc; + + 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 + return ppdu_info; + } + ++void ath11k_copy_to_delay_stats(struct ath11k_peer *peer, ++ struct htt_ppdu_user_stats* usr_stats) ++{ ++ peer->ppdu_stats_delayba.reserved0 = usr_stats->rate.reserved0; ++ peer->ppdu_stats_delayba.sw_peer_id = usr_stats->rate.sw_peer_id; ++ peer->ppdu_stats_delayba.info0 = usr_stats->rate.info0; ++ peer->ppdu_stats_delayba.ru_end = usr_stats->rate.ru_end; ++ peer->ppdu_stats_delayba.ru_start = usr_stats->rate.ru_start; ++ peer->ppdu_stats_delayba.info1 = usr_stats->rate.info1; ++ peer->ppdu_stats_delayba.rate_flags = usr_stats->rate.rate_flags; ++ peer->ppdu_stats_delayba.resp_rate_flags = usr_stats->rate.resp_rate_flags; ++ ++ peer->delayba_flag = true; ++} ++ ++void ath11k_copy_to_bar(struct ath11k_peer *peer, ++ struct htt_ppdu_user_stats* usr_stats) ++{ ++ usr_stats->rate.reserved0 = peer->ppdu_stats_delayba.reserved0; ++ usr_stats->rate.sw_peer_id = peer->ppdu_stats_delayba.sw_peer_id; ++ usr_stats->rate.info0 = peer->ppdu_stats_delayba.info0; ++ usr_stats->rate.ru_end = peer->ppdu_stats_delayba.ru_end; ++ usr_stats->rate.ru_start = peer->ppdu_stats_delayba.ru_start; ++ usr_stats->rate.info1 = peer->ppdu_stats_delayba.info1; ++ usr_stats->rate.rate_flags = peer->ppdu_stats_delayba.rate_flags; ++ usr_stats->rate.resp_rate_flags = peer->ppdu_stats_delayba.resp_rate_flags; ++ ++ peer->delayba_flag = false; ++} ++ ++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), ++ void *data) ++{ ++ const struct htt_tlv *tlv; ++ const void *begin = ptr; ++ u16 tlv_tag, tlv_len; ++ int ret = -EINVAL; ++ struct htt_ppdu_stats_info * ppdu_info = NULL; ++ ++ 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", ++ ptr - begin, len, sizeof(*tlv)); ++ return -EINVAL; ++ } ++ tlv = (struct htt_tlv *)ptr; ++ tlv_tag = FIELD_GET(HTT_TLV_TAG, tlv->header); ++ tlv_len = FIELD_GET(HTT_TLV_LEN, tlv->header); ++ ptr += sizeof(*tlv); ++ 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", ++ tlv_tag, ptr - begin, len, tlv_len); ++ return -EINVAL; ++ } ++ ++ ret = iter(ab, tlv_tag, tlv_len, ptr, ppdu_info); ++ if (ret == -ENOMEM) ++ return ret; ++ ++ ptr += tlv_len; ++ len -= tlv_len; ++ } ++ return 0; ++} ++ + static int ath11k_htt_pull_ppdu_stats(struct ath11k_base *ab, + struct sk_buff *skb) + { + struct ath11k_htt_ppdu_stats_msg *msg; + struct htt_ppdu_stats_info *ppdu_info; ++ struct ath11k_peer *peer = NULL; ++ struct htt_ppdu_user_stats* usr_stats = NULL; ++ u32 peer_id = 0; + struct ath11k *ar; +- int ret; ++ int ret, i; + u8 pdev_id; + u32 ppdu_id, len; + +@@ -1668,6 +1761,47 @@ static int ath11k_htt_pull_ppdu_stats(st + goto out_unlock_data; + } + ++ /* back up data rate tlv for all peers */ ++ if (ppdu_info->frame_type == HTT_STATS_PPDU_FTYPE_DATA && ++ (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON)) && ++ ppdu_info->delay_ba) { ++ ++ for (i = 0; i < ppdu_info->ppdu_stats.common.num_users; i++) { ++ peer_id = ppdu_info->ppdu_stats.user_stats[i].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; ++ } ++ ++ usr_stats = &ppdu_info->ppdu_stats.user_stats[i]; ++ if (usr_stats->delay_ba) ++ ath11k_copy_to_delay_stats(peer, usr_stats); ++ spin_unlock_bh(&ab->base_lock); ++ } ++ } ++ ++ /* restore all peers' data rate tlv to mu-bar tlv */ ++ if (ppdu_info->frame_type == HTT_STATS_PPDU_FTYPE_BAR && ++ (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON))) { ++ ++ for (i = 0; i < ppdu_info->bar_num_users; i++) { ++ peer_id = ppdu_info->ppdu_stats.user_stats[i].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; ++ } ++ ++ usr_stats = &ppdu_info->ppdu_stats.user_stats[i]; ++ if (peer->delayba_flag) ++ ath11k_copy_to_bar(peer, usr_stats); ++ spin_unlock_bh(&ab->base_lock); ++ } ++ } ++ + out_unlock_data: + spin_unlock_bh(&ar->data_lock); + +--- 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 { + } u; + } __packed; + ++#define MAX_USER_POS 8 ++#define MAX_MU_GROUP_ID 64 ++#define MAX_MU_GROUP_SHOW 16 ++#define MAX_MU_GROUP_LENGTH (6 * MAX_MU_GROUP_SHOW) ++ + #define HAL_RX_RU_ALLOC_TYPE_MAX 6 + #define RU_26 1 + #define RU_52 2 +--- a/drivers/net/wireless/ath/ath11k/peer.h ++++ b/drivers/net/wireless/ath/ath11k/peer.h +@@ -7,6 +7,17 @@ + #ifndef ATH11K_PEER_H + #define ATH11K_PEER_H + ++struct ppdu_user_delayba { ++ u8 reserved0; ++ u16 sw_peer_id; ++ u32 info0; ++ u16 ru_end; ++ u16 ru_start; ++ u32 info1; ++ u32 rate_flags; ++ u32 resp_rate_flags; ++}; ++ + struct ath11k_peer { + struct list_head list; + struct ieee80211_sta *sta; +@@ -38,6 +49,8 @@ struct ath11k_peer { + u16 sec_type_grp; + bool is_authorized; + bool dp_setup_done; ++ struct ppdu_user_delayba ppdu_stats_delayba; ++ bool delayba_flag; + }; + + void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id); diff --git a/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-btcoex-config.patch b/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-btcoex-config.patch new file mode 100644 index 00000000000000..18bc4384094eca --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-btcoex-config.patch @@ -0,0 +1,612 @@ +--- a/drivers/net/wireless/ath/ath11k/Makefile ++++ b/drivers/net/wireless/ath/ath11k/Makefile +@@ -17,7 +17,8 @@ ath11k-y += core.o \ + peer.o \ + dbring.o \ + hw.o \ +- pcic.o ++ pcic.o \ ++ vendor.o + + ath11k-$(CPTCFG_ATH11K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o + ath11k-$(CPTCFG_NL80211_TESTMODE) += testmode.o +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -637,6 +637,16 @@ struct ath11k_per_peer_tx_stats { + #define ATH11K_FLUSH_TIMEOUT (5 * HZ) + #define ATH11K_VDEV_DELETE_TIMEOUT_HZ (5 * HZ) + ++struct ath11k_coex_info { ++ bool coex_support; ++ u32 pta_num; ++ u32 coex_mode; ++ u32 bt_active_time_slot; ++ u32 bt_priority_time_slot; ++ u32 coex_algo_type; ++ u32 pta_priority; ++}; ++ + struct ath11k { + struct ath11k_base *ab; + struct ath11k_pdev *pdev; +@@ -759,6 +769,8 @@ struct ath11k { + struct ath11k_per_peer_tx_stats cached_stats; + u32 last_ppdu_id; + u32 cached_ppdu_id; ++ ++ struct ath11k_coex_info coex; + int monitor_vdev_id; + struct completion fw_mode_reset; + u8 ftm_msgref; +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -24,6 +25,7 @@ + #include "debugfs_sta.h" + #include "hif.h" + #include "wow.h" ++#include "vendor.h" + #include "nss.h" + + #define CHAN2G(_channel, _freq, _flags) { \ +@@ -9282,6 +9284,91 @@ err_fallback: + return 0; + } + ++#define ATH11K_WLAN_PRIO_MAX 0x63 ++#define ATH11K_WLAN_PRIO_WEIGHT 0xff ++ ++int ath11k_mac_coex_config(struct ath11k *ar, struct ath11k_vif *arvif, ++ int coex, u32 wlan_prio_mask, u8 wlan_weight) ++{ ++ struct coex_config_arg coex_config; ++ int ret; ++ ++ if (ar->state != ATH11K_STATE_ON && ++ ar->state != ATH11K_STATE_RESTARTED) ++ return -ENETDOWN; ++ ++ if (coex == -1 || !(test_bit(ATH11K_FLAG_BTCOEX, &ar->ab->dev_flags) ^ coex)) ++ goto next; ++ ++ coex_config.vdev_id = arvif->vdev_id; ++ if (coex == 1) { ++ coex_config.config_type = WMI_COEX_CONFIG_PTA_INTERFACE; ++ coex_config.pta_num = ar->coex.pta_num; ++ coex_config.coex_mode = ar->coex.coex_mode; ++ coex_config.bt_txrx_time = ar->coex.bt_active_time_slot; ++ coex_config.bt_priority_time = ar->coex.bt_priority_time_slot; ++ coex_config.pta_algorithm = ar->coex.coex_algo_type; ++ coex_config.pta_priority = ar->coex.pta_priority; ++ ret = ath11k_send_coex_config_cmd(ar, &coex_config); ++ if (ret) { ++ ath11k_warn(ar->ab, ++ "failed to set coex config vdev_id %d ret %d\n", ++ coex_config.vdev_id, ret); ++ goto out; ++ } ++ } ++ ++ memset(&coex_config, 0, sizeof(struct coex_config_arg)); ++ coex_config.vdev_id = arvif->vdev_id; ++ coex_config.config_type = WMI_COEX_CONFIG_BTC_ENABLE; ++ coex_config.coex_enable = coex; ++ ret = ath11k_send_coex_config_cmd(ar, &coex_config); ++ if (ret) { ++ ath11k_warn(ar->ab, ++ "failed to set coex config vdev_id %d ret %d\n", ++ coex_config.vdev_id, ret); ++ goto out; ++ } ++ ++ if (coex) ++ set_bit(ATH11K_FLAG_BTCOEX, &ar->ab->dev_flags); ++ else ++ clear_bit(ATH11K_FLAG_BTCOEX, &ar->ab->dev_flags); ++ ++next: ++ if (!wlan_prio_mask) { ++ ret = 0; ++ goto out; ++ } ++ ++ if (!(test_bit(ATH11K_FLAG_BTCOEX, &ar->ab->dev_flags))) { ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ if (wlan_prio_mask > ATH11K_WLAN_PRIO_MAX || ++ wlan_weight > ATH11K_WLAN_PRIO_WEIGHT) { ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ memset(&coex_config, 0, sizeof(struct coex_config_arg)); ++ coex_config.vdev_id = arvif->vdev_id; ++ coex_config.config_type = WMI_COEX_CONFIG_WLAN_PKT_PRIORITY; ++ coex_config.wlan_pkt_type = wlan_prio_mask; ++ coex_config.wlan_pkt_weight = wlan_weight; ++ ret = ath11k_send_coex_config_cmd(ar, &coex_config); ++ if (ret) { ++ ath11k_warn(ar->ab, ++ "failed to set coex config vdev_id %d ret %d\n", ++ coex_config.vdev_id, ret); ++ goto out; ++ } ++ ++out: ++ return ret; ++} ++ + static const struct ieee80211_ops ath11k_ops = { + .tx = ath11k_mac_op_tx, + .wake_tx_queue = ieee80211_handle_wake_tx_queue, +@@ -9521,6 +9608,56 @@ static int ath11k_mac_setup_iface_combin + return 0; + } + ++static void ath11k_mac_fetch_coex_info(struct ath11k *ar) ++{ ++ struct ath11k_pdev_cap *cap = &ar->pdev->cap; ++ struct ath11k_base *ab = ar->ab; ++ struct device *dev = ab->dev; ++ ++ ar->coex.coex_support = false; ++ ++ if (!(cap->supported_bands & WMI_HOST_WLAN_2G_CAP)) ++ return; ++ ++ if (of_property_read_u32(dev->of_node, "qcom,pta-num", ++ &ar->coex.pta_num)) { ++ ath11k_err(ab, "No qcom,pta_num entry in dev-tree.\n"); ++ } ++ ++ if (of_property_read_u32(dev->of_node, "qcom,coex-mode", ++ &ar->coex.coex_mode)) { ++ ath11k_err(ab, "No qcom,coex_mode entry in dev-tree.\n"); ++ } ++ ++ if (of_property_read_u32(dev->of_node, "qcom,bt-active-time", ++ &ar->coex.bt_active_time_slot)) { ++ ath11k_err(ab, "No qcom,bt-active-time entry in dev-tree.\n"); ++ } ++ ++ if (of_property_read_u32(dev->of_node, "qcom,bt-priority-time", ++ &ar->coex.bt_priority_time_slot)) { ++ ath11k_err(ab, "No qcom,bt-priority-time entry in dev-tree.\n"); ++ } ++ ++ if (of_property_read_u32(dev->of_node, "qcom,coex-algo", ++ &ar->coex.coex_algo_type)) { ++ ath11k_err(ab, "No qcom,coex-algo entry in dev-tree.\n"); ++ } ++ ++ if (of_property_read_u32(dev->of_node, "qcom,pta-priority", ++ &ar->coex.pta_priority)) { ++ ath11k_err(ab, "No qcom,pta-priority entry in dev-tree.\n"); ++ } ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "coex pta_num %u coex_mode %u" ++ " bt_active_time_slot %u bt_priority_time_slot %u" ++ " coex_algorithm %u pta_priority %u\n", ar->coex.pta_num, ++ ar->coex.coex_mode, ar->coex.bt_active_time_slot, ++ ar->coex.bt_priority_time_slot, ar->coex.coex_algo_type, ++ ar->coex.pta_priority); ++ ar->coex.coex_support = true; ++} ++ + static const u8 ath11k_if_types_ext_capa[] = { + [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, + [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT, +@@ -9782,6 +9919,7 @@ static int __ath11k_mac_register(struct + ar->hw->wiphy->ema_max_profile_periodicity = TARGET_EMA_MAX_PROFILE_PERIOD; + + ath11k_reg_init(ar); ++ ath11k_vendor_register(ar); + + if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) { + ar->hw->netdev_features = NETIF_F_HW_CSUM; +@@ -9944,6 +10082,7 @@ int ath11k_mac_allocate(struct ath11k_ba + */ + ath11k_wmi_pdev_attach(ab, i); + ++ ath11k_mac_fetch_coex_info(ar); + ar->cfg_tx_chainmask = pdev->cap.tx_chain_mask; + ar->cfg_rx_chainmask = pdev->cap.rx_chain_mask; + ar->num_tx_chains = get_num_chains(pdev->cap.tx_chain_mask); +--- a/drivers/net/wireless/ath/ath11k/mac.h ++++ b/drivers/net/wireless/ath/ath11k/mac.h +@@ -150,8 +150,9 @@ void __ath11k_mac_scan_finish(struct ath + void ath11k_mac_scan_finish(struct ath11k *ar); + + struct ath11k_vif *ath11k_mac_get_arvif(struct ath11k *ar, u32 vdev_id); +-struct ath11k_vif *ath11k_mac_get_arvif_by_vdev_id(struct ath11k_base *ab, +- u32 vdev_id); ++struct ath11k_vif *ath11k_mac_get_arvif_by_vdev_id(struct ath11k_base *ab, u32 vdev_id); ++int ath11k_mac_coex_config(struct ath11k *ar, struct ath11k_vif *arvif, ++ int coex, u32 wlan_prio_mask, u8 wlan_weight); + u8 ath11k_mac_get_target_pdev_id(struct ath11k *ar); + u8 ath11k_mac_get_target_pdev_id_from_vif(struct ath11k_vif *arvif); + struct ath11k_vif *ath11k_mac_get_vif_up(struct ath11k_base *ab); +--- /dev/null ++++ b/drivers/net/wireless/ath/ath11k/vendor.c +@@ -0,0 +1,121 @@ ++// SPDX-License-Identifier: ISC ++/* ++ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. ++ */ ++ ++#include ++#include ++#include "core.h" ++#include "vendor.h" ++#include "debug.h" ++ ++static const struct nla_policy ++ath11k_vendor_btcoex_config_policy[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_MAX + 1] = { ++ [QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE] = { .type = NLA_U8 }, ++ [QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY] = { .type = NLA_NESTED }, ++}; ++ ++static const struct nla_policy ++ath11k_vendor_wlan_prio_policy[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MAX + 1] = { ++ [QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK] = { .type = NLA_U8 }, ++ [QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT] = { .type = NLA_U8 }, ++}; ++ ++static int ath11k_vendor_btcoex_configure(struct wiphy *wiphy, ++ 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_BTCOEX_CONFIG_MAX + 1]; ++ struct nlattr *tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MAX + 1]; ++ struct nlattr *wlan_prio; ++ enum qca_wlan_priority_type wlan_prio_mask = 0; ++ int ret, coex = -1, rem_conf; ++ u8 wlan_weight = 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_BTCOEX_CONFIG_MAX, data, data_len, ++ ath11k_vendor_btcoex_config_policy, NULL); ++ if (ret) { ++ ath11k_warn(ar->ab, "invalid BTCOEX config policy attribute\n"); ++ goto out; ++ } ++ ++ if (!tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE] && ++ !tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY]) { ++ ath11k_warn(ar->ab, "invalid BTCOEX config attributes\n"); ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ if (tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE]) { ++ coex = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE]); ++ ret = ath11k_mac_coex_config(ar, arvif, coex, wlan_prio_mask, wlan_weight); ++ if (ret) ++ goto out; ++ } ++ if (tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY]) { ++ nla_for_each_nested(wlan_prio, ++ tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY], ++ rem_conf) { ++ ret = ++ nla_parse_nested(tb_wlan_prio, QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MAX, ++ wlan_prio, ath11k_vendor_wlan_prio_policy, ++ NULL); ++ if (ret) ++ goto out; ++ wlan_prio_mask = ++ nla_get_u8(tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK]); ++ if (tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT]) ++ wlan_weight = ++ nla_get_u8(tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT]); ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, ++ "BTCOEX enable %u WLAN Priority %u wlan weight %u\n", ++ coex, wlan_prio_mask, wlan_weight); ++ ++ ret = ath11k_mac_coex_config(ar, arvif, coex, wlan_prio_mask, wlan_weight); ++ if (ret) ++ goto out; ++ } ++ } ++ ++out: ++ mutex_unlock(&ar->conf_mutex); ++ return ret; ++} ++ ++static struct wiphy_vendor_command ath11k_vendor_commands[] = { ++ { ++ .info.vendor_id = QCA_NL80211_VENDOR_ID, ++ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_BTCOEX_CONFIG, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | ++ WIPHY_VENDOR_CMD_NEED_RUNNING, ++ .doit = ath11k_vendor_btcoex_configure, ++ .policy = ath11k_vendor_btcoex_config_policy ++ } ++}; ++ ++int ath11k_vendor_register(struct ath11k *ar) ++{ ++ ar->hw->wiphy->vendor_commands = ath11k_vendor_commands; ++ ar->hw->wiphy->n_vendor_commands = ARRAY_SIZE(ath11k_vendor_commands); ++ ++ return 0; ++} +--- /dev/null ++++ b/drivers/net/wireless/ath/ath11k/vendor.h +@@ -0,0 +1,83 @@ ++/* SPDX-License-Identifier: ISC */ ++/* ++ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. ++ */ ++ ++#ifndef ATH11K_VENDOR_H ++#define ATH11K_VENDOR_H ++ ++#define QCA_NL80211_VENDOR_ID 0x001374 ++ ++enum qca_nl80211_vendor_subcmds { ++ /* 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 ++ * enum qca-vendor_attr_btcoex_config. ++ */ ++ QCA_NL80211_VENDOR_SUBCMD_BTCOEX_CONFIG = 182, ++}; ++ ++/* ++ * enum qca_wlan_priority_type - priority mask ++ * This enum defines priority mask that user can configure ++ * over BT traffic type which can be passed through ++ * QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY attribute. ++ * ++ * @QCA_WLAN_PRIORITY_BE: Bit mask for WLAN Best effort traffic ++ * @QCA_WLAN_PRIORITY_BK: Bit mask for WLAN Background traffic ++ * @QCA_WLAN_PRIORITY_VI: Bit mask for WLAN Video traffic ++ * @QCA_WLAN_PRIORITY_VO: Bit mask for WLAN Voice traffic ++ * @QCA_WLAN_PRIORITY_BEACON: Bit mask for WLAN BEACON frame ++ * @QCA_WLAN_PRIORITY_MGMT: Bit mask for WLAN Management frame ++*/ ++enum qca_wlan_priority_type { ++ QCA_WLAN_PRIORITY_BE = BIT(0), ++ QCA_WLAN_PRIORITY_BK = BIT(1), ++ QCA_WLAN_PRIORITY_VI = BIT(2), ++ QCA_WLAN_PRIORITY_VO = BIT(3), ++ QCA_WLAN_PRIORITY_BEACON = BIT(4), ++ QCA_WLAN_PRIORITY_MGMT = BIT(5), ++}; ++ ++/** ++ * enum qca_wlan_vendor_attr_wlan_prio - Used to configure ++ * WLAN priority mask and its respective weight value. ++ * @QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK - This is u8 attribute ++ * used to pass traffic type mask value see %qca_wlan_priority_type ++ * @QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT - This is u8 attribute ++ * accepts value between 0 and 255 and used to configure weight for ++ * traffic type mentioned in %QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK. ++ */ ++enum qca_wlan_vendor_attr_wlan_prio { ++ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_INVALID = 0, ++ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK = 1, ++ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT = 2, ++ ++ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_LAST, ++ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MAX = ++ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_LAST - 1, ++}; ++ ++ ++ ++/** ++ * enum qca_wlan_vendor_attr_btcoex_config - Used by the vendor command ++ * The use can enable/disable BTCOEX and configure WLAN priority for ++ * different traffic type over BT. ++ * QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE, enable/disable BTCOEX ++ * QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY, This is a nested ++ * attribute pass the attributes in %qca_wlan_vendor_attr_wlan_prio. ++ */ ++enum qca_wlan_vendor_attr_btcoex_config { ++ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_INVALID = 0, ++ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE = 1, ++ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY = 2, ++ ++ /* keep last */ ++ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_LAST, ++ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_MAX = ++ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_LAST - 1 ++}; ++ ++int ath11k_vendor_register(struct ath11k *ar); ++#endif /* QCA_VENDOR_H */ +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -1697,6 +1697,71 @@ int ath11k_wmi_vdev_set_param_cmd(struct + return ret; + } + ++static void ath11k_wmi_copy_coex_config(struct ath11k *ar, struct wmi_coex_config_cmd *cmd, ++ struct coex_config_arg *coex_config) ++{ ++ if (coex_config->config_type == WMI_COEX_CONFIG_BTC_ENABLE) { ++ cmd->coex_enable = coex_config->coex_enable; ++ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, ++ "WMI coex config type %u vdev id %d coex_enable %u\n", ++ coex_config->config_type, coex_config->vdev_id, ++ coex_config->coex_enable); ++ } ++ ++ if (coex_config->config_type == WMI_COEX_CONFIG_WLAN_PKT_PRIORITY) { ++ cmd->wlan_pkt_type = coex_config->wlan_pkt_type; ++ cmd->wlan_pkt_weight = coex_config->wlan_pkt_weight; ++ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, ++ "WMI coex config type %u vdev id %d wlan pkt type 0x%x wlan pkt weight %u\n", ++ coex_config->config_type, coex_config->vdev_id, ++ coex_config->wlan_pkt_type, coex_config->wlan_pkt_weight); ++ } ++ ++ if (coex_config->config_type == WMI_COEX_CONFIG_PTA_INTERFACE) { ++ cmd->pta_num = coex_config->pta_num; ++ cmd->coex_mode = coex_config->coex_mode; ++ cmd->bt_txrx_time = coex_config->bt_txrx_time; ++ cmd->bt_priority_time = coex_config->bt_priority_time; ++ cmd->pta_algorithm = coex_config->pta_algorithm; ++ cmd->pta_priority = coex_config->pta_priority; ++ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, ++ "WMI coex config type %u vdev id %d pta num %u coex mode %u bt_txrx_time %u bt_priority_time %u pta alogrithm %u pta priority %u\n", ++ coex_config->config_type, coex_config->vdev_id, ++ coex_config->pta_num, coex_config->coex_mode, ++ coex_config->bt_txrx_time, coex_config->bt_priority_time, ++ coex_config->pta_algorithm, coex_config->pta_priority); ++ } ++} ++ ++int ath11k_send_coex_config_cmd(struct ath11k *ar, ++ struct coex_config_arg *coex_config) ++{ ++ struct ath11k_pdev_wmi *wmi = ar->wmi; ++ struct wmi_coex_config_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_coex_config_cmd *)skb->data; ++ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_COEX_CONFIG_CMD) | ++ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); ++ ++ cmd->vdev_id = coex_config->vdev_id; ++ cmd->config_type = coex_config->config_type; ++ ath11k_wmi_copy_coex_config(ar, cmd, coex_config); ++ ++ ret = ath11k_wmi_cmd_send(wmi, skb, WMI_COEX_CONFIG_CMDID); ++ if (ret) { ++ ath11k_warn(ar->ab, "failed to send WMI_COEX_CONFIG_CMD cmd\n"); ++ dev_kfree_skb(skb); ++ } ++ ++ return ret; ++} ++ + int ath11k_wmi_send_stats_request_cmd(struct ath11k *ar, + struct stats_request_params *param) + { +--- a/drivers/net/wireless/ath/ath11k/wmi.h ++++ b/drivers/net/wireless/ath/ath11k/wmi.h +@@ -5303,6 +5303,79 @@ struct wmi_wmm_params_arg { + u8 no_ack; + }; + ++enum wmi_coex_config_type { ++ WMI_COEX_CONFIG_PAGE_P2P_TDM = 1, ++ WMI_COEX_CONFIG_PAGE_STA_TDM = 2, ++ WMI_COEX_CONFIG_PAGE_SAP_TDM = 3, ++ WMI_COEX_CONFIG_DURING_WLAN_CONN = 4, ++ WMI_COEX_CONFIG_BTC_ENABLE = 5, ++ WMI_COEX_CONFIG_COEX_DBG = 6, ++ WMI_COEX_CONFIG_PAGE_P2P_STA_TDM = 7, ++ WMI_COEX_CONFIG_INQUIRY_P2P_TDM = 8, ++ WMI_COEX_CONFIG_INQUIRY_STA_TDM = 9, ++ WMI_COEX_CONFIG_INQUIRY_SAP_TDM = 10, ++ WMI_COEX_CONFIG_INQUIRY_P2P_STA_TDM = 11, ++ WMI_COEX_CONFIG_TX_POWER = 12, ++ WMI_COEX_CONFIG_PTA_CONFIG = 13, ++ WMI_COEX_CONFIG_AP_TDM = 14, ++ WMI_COEX_CONFIG_WLAN_SCAN_PRIORITY = 15, ++ WMI_COEX_CONFIG_WLAN_PKT_PRIORITY = 16, ++ WMI_COEX_CONFIG_PTA_INTERFACE = 17, ++}; ++ ++struct coex_config_arg { ++ u32 vdev_id; ++ u32 config_type; ++ union { ++ struct { ++ u32 coex_enable; ++ }; ++ ++ struct { ++ u32 pta_num; ++ u32 coex_mode; ++ u32 bt_txrx_time; ++ u32 bt_priority_time; ++ u32 pta_algorithm; ++ u32 pta_priority; ++ }; ++ ++ struct { ++ u32 wlan_pkt_type; ++ u32 wlan_pkt_type_continued; ++ u32 wlan_pkt_weight; ++ u32 bt_pkt_weight; ++ }; ++ }; ++}; ++ ++struct wmi_coex_config_cmd { ++ u32 tlv_header; ++ u32 vdev_id; ++ u32 config_type; ++ union { ++ struct { ++ u32 coex_enable; ++ } __packed; ++ ++ struct { ++ u32 pta_num; ++ u32 coex_mode; ++ u32 bt_txrx_time; ++ u32 bt_priority_time; ++ u32 pta_algorithm; ++ u32 pta_priority; ++ } __packed; ++ ++ struct { ++ u32 wlan_pkt_type; ++ u32 wlan_pkt_type_continued; ++ u32 wlan_pkt_weight; ++ u32 bt_pkt_weight; ++ } __packed; ++ } __packed; ++} __packed; ++ + struct wmi_vdev_set_wmm_params_cmd { + u32 tlv_header; + u32 vdev_id; +@@ -6520,6 +6593,8 @@ int ath11k_wmi_pdev_non_srg_obss_color_e + u32 *bitmap); + int ath11k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(struct ath11k *ar, + u32 *bitmap); ++int ath11k_send_coex_config_cmd(struct ath11k *ar, ++ struct coex_config_arg *coex_config); + 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/903-002-ath11k-add-support-for-ext-vdev-in-NSS-for-AP_VLAN-vif-handling.patch b/package/kernel/mac80211/patches/ath11k_nss/903-002-ath11k-add-support-for-ext-vdev-in-NSS-for-AP_VLAN-vif-handling.patch new file mode 100644 index 00000000000000..6f5fffe596172b --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/903-002-ath11k-add-support-for-ext-vdev-in-NSS-for-AP_VLAN-vif-handling.patch @@ -0,0 +1,784 @@ +From 83c2a029a5300b2aaeaa9855011668b407d142c2 Mon Sep 17 00:00:00 2001 +From: Sathishkumar Muruganandam +Date: Fri, 20 Nov 2020 11:41:11 +0530 +Subject: [PATCH 2/3] ath11k: add support for ext vdev in NSS for AP_VLAN vif + handling + +- add ext vdev NSS API callbacks required for AP_VLAN vif +- invoke ieee80211_rx_nss_notify_4addr on WDS Rx path for 4addr frames until + ext vdev interface is UP +- do ext vdev down of all AP_VLAN vifs upon vdev down of associated AP vif + +Signed-off-by: Sathishkumar Muruganandam +--- + drivers/net/wireless/ath/ath11k/nss.c | 452 ++++++++++++++++++++++++++++++++-- + drivers/net/wireless/ath/ath11k/nss.h | 57 +++++ + 2 files changed, 495 insertions(+), 14 deletions(-) + +--- 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 + 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; ++ case NSS_WIFILI_PEER_4ADDR_EVENT_MSG: ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, "nss wifili peer 4addr event received %d response %d error %d\n", ++ msg_type, response, error); ++ break; + 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 + return 0; + } + +-static void ath11k_nss_wds_type_rx(struct ath11k *ar, u8* src_mac, u8 is_sa_valid, +- u8 addr4_valid, u16 peer_id) ++static void ath11k_nss_wds_type_rx(struct ath11k *ar, struct net_device *dev, ++ u8* src_mac, u8 is_sa_valid, u8 addr4_valid, ++ u16 peer_id, bool *drop) + { + 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 + if (!is_sa_valid) { + ath11k_peer_add_ast(ar, ta_peer, src_mac, + ATH11K_AST_TYPE_WDS); +- ath11k_nss_add_wds_peer(ar, ta_peer, +- src_mac, ATH11K_AST_TYPE_WDS); ++ if (!ta_peer->nss.ext_vdev_up) ++ ieee80211_rx_nss_notify_4addr(dev, ta_peer->addr); + } else { + if (!ast_entry) { + ath11k_peer_add_ast(ar, ta_peer, src_mac, + ATH11K_AST_TYPE_WDS); +- ath11k_nss_add_wds_peer(ar, ta_peer, src_mac, +- ATH11K_AST_TYPE_WDS); +- } else { ++ if (!ta_peer->nss.ext_vdev_up) ++ ieee80211_rx_nss_notify_4addr(dev, ta_peer->addr); ++ } else if (ast_entry->type == ATH11K_AST_TYPE_WDS) { + ath11k_peer_update_ast(ar, ta_peer, ast_entry); + ath11k_nss_update_wds_peer(ar, ta_peer, src_mac); + } + } ++ ++ if (!ta_peer->nss.ext_vdev_up) ++ *drop = true; + } + + spin_unlock_bh(&ab->base_lock); +@@ -678,7 +686,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, +- struct nss_wifi_vdev_wds_per_packet_metadata *wds_metadata) ++ struct nss_wifi_vdev_wds_per_packet_metadata *wds_metadata, ++ bool *drop) + { + struct ath11k *ar = arvif->ar; + struct ath11k_base *ab = ar->ab; +@@ -699,8 +708,8 @@ static void ath11k_nss_vdev_spl_receive_ + + switch (wds_type) { + case NSS_WIFI_VDEV_WDS_TYPE_RX: +- ath11k_nss_wds_type_rx(ar, src_mac, is_sa_valid, +- addr4_valid, peer_id); ++ ath11k_nss_wds_type_rx(ar, skb->dev, src_mac, is_sa_valid, ++ addr4_valid, peer_id, drop); + 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 + struct ieee80211_vif *vif; + struct ath11k_vif *arvif; + struct ath11k_base *ab; ++ bool drop = false; + bool eth_decap = false; + int data_offs = 0; + int ret = 0; +@@ -822,10 +832,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, +- wds_metadata); ++ wds_metadata, &drop); + } + +- ath11k_nss_deliver_rx(arvif->vif, skb, eth_decap, data_offs, napi); ++ if (!drop) ++ ath11k_nss_deliver_rx(arvif->vif, skb, eth_decap, data_offs, napi); + } + + static void +@@ -888,6 +899,68 @@ ath11k_nss_vdev_data_receive(struct net_ + ath11k_nss_deliver_rx(arvif->vif, skb, eth_decap, data_offs, napi); + } + ++static void ++ath11k_nss_ext_vdev_special_data_receive(struct net_device *dev, ++ struct sk_buff *skb, ++ __attribute__((unused)) struct napi_struct *napi) ++{ ++ dev_kfree_skb_any(skb); ++} ++ ++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) { ++ 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; ++ if (!arvif) { ++ dev_kfree_skb_any(skb); ++ return; ++ } ++ ++ 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); ++} ++ + 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 + ath11k_nss_tx_encap_nwifi(skb); + + send: +- ath11k_dbg_dump(ar->ab, ATH11K_DBG_DP_TX, "", "nss tx msdu: ", +- skb->data, skb->len); +- +- status = nss_wifi_vdev_tx_buf(arvif->ar->nss.ctx, skb, arvif->nss.if_num); ++ 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) ++ 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); + + 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 + struct nss_wifi_vdev_msg *vdev_msg = NULL; + struct nss_wifi_vdev_enable_msg *vdev_en; + struct ath11k *ar = arvif->ar; ++ struct ath11k_vif *ap_vlan_arvif, *tmp; + nss_tx_status_t status; + int ret = 0; + +@@ -1285,6 +1365,12 @@ int ath11k_nss_vdev_up(struct ath11k_vif + } + + ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss vdev up tx msg success\n"); ++ ++ if (arvif->vif->type == NL80211_IFTYPE_AP) ++ list_for_each_entry_safe(ap_vlan_arvif, tmp, &arvif->ap_vlan_arvifs, ++ list) ++ if (ap_vlan_arvif->nss.added) ++ ath11k_nss_ext_vdev_up(ap_vlan_arvif); + free: + kfree(vdev_msg); + return ret; +@@ -1294,6 +1380,7 @@ int ath11k_nss_vdev_down(struct ath11k_v + { + struct nss_wifi_vdev_msg *vdev_msg = NULL; + struct ath11k *ar = arvif->ar; ++ struct ath11k_vif *ap_vlan_arvif, *tmp; + nss_tx_status_t status; + int ret = 0; + +@@ -1321,11 +1408,362 @@ int ath11k_nss_vdev_down(struct ath11k_v + } + + ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss vdev down tx msg success\n"); ++ ++ if (arvif->vif->type == NL80211_IFTYPE_AP) ++ list_for_each_entry_safe(ap_vlan_arvif, tmp, &arvif->ap_vlan_arvifs, ++ list) ++ ath11k_nss_ext_vdev_down(ap_vlan_arvif); + free: + kfree(vdev_msg); + return ret; + } + ++int ath11k_nss_ext_vdev_cfg_wds_peer(struct ath11k_vif *arvif, ++ u8 *wds_addr, u32 wds_peer_id) ++{ ++ struct ath11k *ar = arvif->ar; ++ struct nss_wifi_ext_vdev_msg *ext_vdev_msg = NULL; ++ struct nss_wifi_ext_vdev_wds_msg *cfg_wds_msg = NULL; ++ nss_tx_status_t status; ++ int ret; ++ ++ if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN) ++ return -EINVAL; ++ ++ ext_vdev_msg = kzalloc(sizeof(struct nss_wifi_ext_vdev_msg), GFP_ATOMIC); ++ if (!ext_vdev_msg) ++ return -ENOMEM; ++ ++ 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); ++ ++ nss_wifi_ext_vdev_msg_init(ext_vdev_msg, arvif->nss.if_num, ++ NSS_WIFI_EXT_VDEV_MSG_CONFIGURE_WDS, ++ sizeof(struct nss_wifi_ext_vdev_wds_msg), ++ NULL, arvif); ++ ++ status = nss_wifi_ext_vdev_tx_msg_sync(arvif->nss.ctx, ext_vdev_msg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "failed to configure wds peer nss_err:%d\n", ++ status); ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ ret = 0; ++free: ++ kfree(ext_vdev_msg); ++ ++ return ret; ++} ++ ++int ath11k_nss_ext_vdev_wds_4addr_allow(struct ath11k_vif *arvif, ++ u32 wds_peer_id) ++{ ++ struct ath11k *ar = arvif->ar; ++ struct nss_wifili_peer_wds_4addr_allow_msg *cfg_4addr_msg = NULL; ++ nss_wifili_msg_callback_t msg_cb; ++ struct nss_wifili_msg *wlmsg; ++ nss_tx_status_t status; ++ ++ if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN) ++ return -EINVAL; ++ ++ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); ++ if (!wlmsg) ++ return -ENOMEM; ++ ++ cfg_4addr_msg = &wlmsg->msg.wpswm; ++ cfg_4addr_msg->peer_id = wds_peer_id; ++ cfg_4addr_msg->if_num = arvif->nss.if_num; ++ cfg_4addr_msg->enable = true; ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ nss_cmn_msg_init(&wlmsg->cm, ar->ab->nss.if_num, ++ NSS_WIFILI_PEER_4ADDR_EVENT_MSG, ++ sizeof(struct nss_wifili_peer_wds_4addr_allow_msg), ++ msg_cb, NULL); ++ ++ status = nss_wifili_tx_msg(ar->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "nss wds 4addr allow if_num %d, peer_id %d cfg fail: %d\n", ++ arvif->nss.if_num, wds_peer_id, status); ++ goto free; ++ } ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS_WDS, "nss wds 4addr allow if_num %d, peer_id %d cfg complete\n", ++ arvif->nss.if_num, wds_peer_id); ++free: ++ kfree(wlmsg); ++ return status; ++} ++ ++int ath11k_nss_ext_vdev_configure(struct ath11k_vif *arvif) ++{ ++ struct ath11k *ar = arvif->ar; ++ struct ath11k_vif *ap_vif = arvif->nss.ap_vif; ++ struct nss_wifi_ext_vdev_msg *ext_vdev_msg = NULL; ++ struct nss_wifi_ext_vdev_configure_if_msg *ext_vdev_cfg = NULL; ++ nss_tx_status_t status; ++ int ret; ++ ++ if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN) ++ return -EINVAL; ++ ++ ext_vdev_msg = kzalloc(sizeof(struct nss_wifi_ext_vdev_msg), GFP_ATOMIC); ++ if (!ext_vdev_msg) ++ return -ENOMEM; ++ ++ ext_vdev_cfg = &ext_vdev_msg->msg.cmsg; ++ ++ ext_vdev_cfg->radio_ifnum = ar->nss.if_num; ++ ext_vdev_cfg->pvap_ifnum = ap_vif->nss.if_num; ++ ++ ether_addr_copy(ext_vdev_cfg->mac_addr, arvif->vif->addr); ++ ++ nss_wifi_ext_vdev_msg_init(ext_vdev_msg, arvif->nss.if_num, ++ NSS_WIFI_EXT_VDEV_MSG_CONFIGURE_IF, ++ sizeof(struct nss_wifi_ext_vdev_configure_if_msg), ++ NULL, arvif); ++ ++ status = nss_wifi_ext_vdev_tx_msg_sync(arvif->ar->nss.ctx, ext_vdev_msg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "failed to configure nss ext vdev nss_err:%d\n", ++ status); ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ ret = 0; ++free: ++ kfree(ext_vdev_msg); ++ ++ return ret; ++} ++ ++void ath11k_nss_ext_vdev_unregister(struct ath11k_vif *arvif) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ ++ if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN) ++ return; ++ ++ nss_wifi_ext_vdev_unregister_if(arvif->nss.if_num); ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, "unregistered nss vdev %d \n", ++ arvif->nss.if_num); ++} ++ ++static int ath11k_nss_ext_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; ++ enum nss_dynamic_interface_type di_type; ++ u32 features = 0; ++ ++ if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN || arvif->nss.ctx) ++ return -EINVAL; ++ ++ di_type = NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_WDS; ++ ++ 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, ++ NULL, netdev, features, ++ arvif); ++ ++ if (!arvif->nss.ctx) { ++ ath11k_warn(ab, "failed to register nss vdev if_num %d nss_err:%d\n", ++ arvif->nss.if_num, status); ++ return -EINVAL; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, "registered nss ext vdev if_num %d\n", ++ arvif->nss.if_num); ++ return 0; ++} ++ ++static void ath11k_nss_ext_vdev_free(struct ath11k_vif *arvif) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ nss_tx_status_t status; ++ ++ if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN) ++ return; ++ ++ status = nss_dynamic_interface_dealloc_node( ++ arvif->nss.if_num, ++ NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_WDS); ++ if (status != NSS_TX_SUCCESS) ++ ath11k_warn(ab, "failed to free nss ext vdev err:%d\n", ++ status); ++ else ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, ++ "nss ext vdev interface deallocated\n"); ++} ++ ++static int ath11k_nss_ext_vdev_alloc(struct ath11k_vif *arvif) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ enum nss_dynamic_interface_type di_type; ++ int if_num; ++ ++ di_type = NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_WDS; ++ ++ if_num = nss_dynamic_interface_alloc_node(di_type); ++ if (if_num < 0) { ++ ath11k_warn(ab, "failed to allocate nss ext vdev\n"); ++ return -EINVAL; ++ } ++ ++ arvif->nss.if_num = if_num; ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, ++ "nss ext vdev interface %pM allocated if_num %d\n", ++ arvif->vif->addr, if_num); ++ ++ return 0; ++} ++ ++int ath11k_nss_ext_vdev_create(struct ath11k_vif *arvif) ++{ ++ struct ath11k *ar = arvif->ar; ++ struct ath11k_base *ab = ar->ab; ++ struct wireless_dev *wdev; ++ int ret; ++ ++ if (!ab->nss.enabled) ++ return 0; ++ ++ if (arvif->nss.created) ++ return 0; ++ ++ wdev = ieee80211_vif_to_wdev_relaxed(arvif->vif); ++ if (!wdev) { ++ ath11k_warn(ab, "ath11k_nss: ext wdev is null\n"); ++ return -EINVAL; ++ } ++ ++ if (!wdev->netdev) { ++ ath11k_warn(ab, "ath11k_nss: ext netdev is null\n"); ++ return -EINVAL; ++ } ++ ++ ret = ath11k_nss_ext_vdev_alloc(arvif); ++ if (ret) ++ return ret; ++ ++ ret = ath11k_nss_ext_vdev_register(arvif, wdev->netdev); ++ if (ret) ++ goto free_ext_vdev; ++ ++ arvif->nss.created = true; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, ++ "nss ext vdev interface created ctx %pK, ifnum %d\n", ++ arvif->nss.ctx, arvif->nss.if_num); ++ ++ return ret; ++ ++free_ext_vdev: ++ ath11k_nss_ext_vdev_free(arvif); ++ ++ return ret; ++} ++ ++void ath11k_nss_ext_vdev_delete(struct ath11k_vif *arvif) ++{ ++ if (!arvif->ar->ab->nss.enabled) ++ return; ++ ++ if (!arvif->nss.created) ++ return; ++ ++ ath11k_dbg(arvif->ar->ab, ATH11K_DBG_NSS_WDS, ++ "nss ext vdev interface delete ctx %pK, ifnum %d\n", ++ arvif->nss.ctx, arvif->nss.if_num); ++ ++ ath11k_nss_ext_vdev_unregister(arvif); ++ ++ ath11k_nss_ext_vdev_free(arvif); ++ ++ arvif->nss.created = false; ++} ++ ++int ath11k_nss_ext_vdev_up(struct ath11k_vif *arvif) ++{ ++ struct nss_wifi_ext_vdev_msg *ext_vdev_msg = NULL; ++ struct ath11k *ar = arvif->ar; ++ nss_tx_status_t status; ++ int ret = 0; ++ ++ if (!ar->ab->nss.enabled) ++ return 0; ++ ++ if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN) ++ return -EINVAL; ++ ++ if (arvif->nss.ext_vdev_up) ++ return 0; ++ ++ ext_vdev_msg = kzalloc(sizeof(struct nss_wifi_vdev_msg), GFP_ATOMIC); ++ if (!ext_vdev_msg) ++ return -ENOMEM; ++ ++ nss_wifi_ext_vdev_msg_init(ext_vdev_msg, arvif->nss.if_num, NSS_IF_OPEN, ++ sizeof(struct nss_if_open), NULL, arvif); ++ ++ status = nss_wifi_ext_vdev_tx_msg_sync(arvif->nss.ctx, ext_vdev_msg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "nss ext vdev up tx msg error %d\n", status); ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS_WDS, "nss ext vdev up tx msg success\n"); ++ arvif->nss.ext_vdev_up = true; ++free: ++ kfree(ext_vdev_msg); ++ return ret; ++} ++ ++int ath11k_nss_ext_vdev_down(struct ath11k_vif *arvif) ++{ ++ struct nss_wifi_ext_vdev_msg *ext_vdev_msg = NULL; ++ struct ath11k *ar = arvif->ar; ++ nss_tx_status_t status; ++ int ret = 0; ++ ++ if (!ar->ab->nss.enabled) ++ return 0; ++ ++ if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN) ++ return -EINVAL; ++ ++ ext_vdev_msg = kzalloc(sizeof(struct nss_wifi_ext_vdev_msg), GFP_ATOMIC); ++ if (!ext_vdev_msg) ++ return -ENOMEM; ++ ++ nss_wifi_ext_vdev_msg_init(ext_vdev_msg, arvif->nss.if_num, NSS_IF_CLOSE, ++ sizeof(struct nss_if_close), NULL, arvif); ++ ++ status = nss_wifi_ext_vdev_tx_msg_sync(arvif->nss.ctx, ext_vdev_msg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "nss ext vdev down tx msg error %d\n", status); ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS_WDS, "nss ext vdev down tx msg success\n"); ++ ++ arvif->nss.ext_vdev_up = false; ++free: ++ kfree(ext_vdev_msg); ++ return ret; ++} ++ + /*----------------------------Peer Setup/Config -----------------------------*/ + + int ath11k_nss_set_peer_sec_type(struct ath11k *ar, +@@ -1419,22 +1857,22 @@ free: + return status; + } + +-void ath11k_nss_update_sta_stats(struct station_info *sinfo, +- struct ieee80211_sta *sta, +- struct ath11k_sta *arsta) ++void ath11k_nss_update_sta_stats(struct ath11k_vif *arvif, ++ struct station_info *sinfo, ++ struct ieee80211_sta *sta) + { + struct sta_info *stainfo; + struct ath11k_peer *peer; +- struct ath11k *ar = arsta->arvif->ar; ++ struct ath11k *ar = arvif->ar; + struct ath11k_base *ab = ar->ab; + +- if (!ab->nss.enabled) ++ if (!ab->nss.stats_enabled) + return; + + spin_lock_bh(&ab->base_lock); +- peer = ath11k_peer_find_by_addr(arsta->arvif->ar->ab, sta->addr); ++ peer = ath11k_peer_find_by_addr(ab, sta->addr); + if (!peer) { +- ath11k_dbg(ab, ATH11K_DBG_NSS, "unable to find peer %pM\n", ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "sta stats: unable to find peer %pM\n", + sta->addr); + goto exit; + } +@@ -1506,13 +1944,13 @@ void ath11k_nss_update_sta_rxrate(struct + struct ath11k_peer *peer, + struct hal_rx_user_status *user_stats) + { +- struct ath11k_sta *arsta = (struct ath11k_sta *)peer->sta->drv_priv; + u16 ath11k_hal_rx_legacy_rates[] = + { 10, 20, 55, 60, 90, 110, 120, 180, 240, 360, 480, 540 }; + u16 rate = 0; + u32 preamble_type; + u8 mcs, nss; +- struct ath11k *ar = arsta->arvif->ar; ++ struct ath11k_vif *arvif = ath11k_vif_to_arvif(peer->vif); ++ struct ath11k *ar = arvif->ar; + struct ath11k_base *ab = ar->ab; + + if (!ab->nss.enabled) +@@ -1816,8 +2254,8 @@ int ath11k_nss_add_wds_peer(struct ath11 + } + + ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, +- "nss add wds peer success peer mac:%pM dest mac:%pM peer_id:%d\n", +- wds_peer_msg->peer_mac, wds_peer_msg->dest_mac, wds_peer_msg->peer_id); ++ "nss add wds peer success pdev:%d peer mac:%pM dest mac:%pM peer_id:%d\n", ++ wds_peer_msg->pdev_id, wds_peer_msg->peer_mac, wds_peer_msg->dest_mac, wds_peer_msg->peer_id); + + msg_free: + kfree(wlmsg); +@@ -1862,8 +2300,8 @@ int ath11k_nss_update_wds_peer(struct at + } + + ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, +- "nss update wds peer success peer mac:%pM dest mac:%pM peer_id:%d\n", +- wds_peer_msg->peer_mac, wds_peer_msg->dest_mac, wds_peer_msg->peer_id); ++ "nss update wds peer success pdev:%d peer mac:%pM dest mac:%pM peer_id:%d\n", ++ wds_peer_msg->pdev_id, wds_peer_msg->peer_mac, wds_peer_msg->dest_mac, wds_peer_msg->peer_id); + + msg_free: + 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 { + struct ath11k_nss_peer { + uint32_t *vaddr; + dma_addr_t paddr; ++ bool ext_vdev_up; + struct peer_stats *nss_stats; + struct completion complete; + }; +@@ -168,6 +169,16 @@ struct arvif_nss { + int encap; + /* Keep the copy of decap type for nss */ + int decap; ++ /* AP_VLAN vif context obtained on ext vdev register */ ++ void* ctx; ++ /* Parent AP vif stored in case of AP_VLAN vif */ ++ struct ath11k_vif *ap_vif; ++ /* Flag to notify if vlan arvif object is added to arvif list*/ ++ bool added; ++ /* Flag to notify if ext vdev is up/down */ ++ bool ext_vdev_up; ++ /* WDS cfg should be done only once for ext vdev */ ++ bool wds_cfg_done; + bool created; + }; + +@@ -223,11 +234,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); ++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, ++ u32 wds_peer_id); ++int ath11k_nss_ext_vdev_create(struct ath11k_vif *arvif); ++int ath11k_nss_ext_vdev_configure(struct ath11k_vif *arvif); ++void ath11k_nss_ext_vdev_unregister(struct ath11k_vif *arvif); ++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); + 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, +- struct ieee80211_sta *sta, +- struct ath11k_sta *arsta); ++void ath11k_nss_update_sta_stats(struct ath11k_vif *arvif, ++ struct station_info *sinfo, ++ struct ieee80211_sta *sta); + 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 + { + } + +-static inline void ath11k_nss_update_sta_stats(struct station_info *sinfo, +- struct ieee80211_sta *sta, +- struct ath11k_sta *arsta) ++static inline void ath11k_nss_update_sta_stats(struct ath11k_vif *arvif, ++ struct station_info *sinfo, ++ struct ieee80211_sta *sta) + { + return; + } +@@ -319,6 +340,43 @@ static inline int ath11k_nss_peer_create + return 0; + } + ++static inline int ath11k_nss_ext_vdev_cfg_wds_peer(struct ath11k_vif *arvif, ++ u8 *wds_addr, u32 wds_peer_id) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_ext_vdev_wds_4addr_allow(struct ath11k_vif *arvif, ++ u32 wds_peer_id) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_ext_vdev_create(struct ath11k_vif *arvif) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_ext_vdev_configure(struct ath11k_vif *arvif) ++{ ++ return 0; ++} ++ ++static inline void ath11k_nss_ext_vdev_unregister(struct ath11k_vif *arvif) ++{ ++ return; ++} ++ ++static inline int ath11k_nss_ext_vdev_up(struct ath11k_vif *arvif) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_ext_vdev_down(struct ath11k_vif *arvif) ++{ ++ return 0; ++} ++ + static inline void ath11k_nss_peer_stats_enable(struct ath11k *ar) + { + return; +@@ -340,6 +398,11 @@ static inline int ath11k_nss_setup(struc + return 0; + } + ++static inline void ath11k_nss_ext_vdev_delete(struct ath11k_vif *arvif) ++{ ++ return; ++} ++ + static inline int ath11k_nss_teardown(struct ath11k_base *ab) + { + 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/ath11k_nss/903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch new file mode 100644 index 00000000000000..86714fea844e81 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch @@ -0,0 +1,575 @@ +From 730f568af3fac2f31467ea0ff374ea442ddc379f Mon Sep 17 00:00:00 2001 +From: Sathishkumar Muruganandam +Date: Fri, 20 Nov 2020 11:57:36 +0530 +Subject: [PATCH 3/3] ath11k: add AP_VLAN vif support for WDS offload in NSS + offload + +- AP_VLAN vif support is required for WDS offload to interop with mac80211 + based 4addr STA and also for multicast-to-unicast conversion of 3addr + multicast to 4addr frames for each associated 4addr STA. + +- For each associated 4addr STA, corresponding AP_VLAN vif having same MAC + address as AP vif is created from hostapd upon 4addr rx_notify from NSS RX. + +- AP_VLAN vif support is added to add/remove interface mac80211 callbacks only + for NSS ext vdev handling and vdev_id, FW vdev operations are not needed. + +- mac80211 advertises AP_VLAN vif for sta_use_4addr drv callback in case of + NSS offload. Extending ath11k_mac_op_sta_use_4addr to invoke ext vdev NSS + APIs required for AP WDS handling. + +- Maintain AP_VLAN vif(s) list on corresponding AP vif and vice versa required + for ext vdev operations (VDEV_DOWN, DELETE, CONFIGURE_IF). + +- NSS require ENABLE_NAWDS and WDS_BACKHAUL to be configured for AP_VLAN + support via ext vdev. + +Signed-off-by: Sathishkumar Muruganandam +--- + drivers/net/wireless/ath/ath11k/core.h | 1 + + drivers/net/wireless/ath/ath11k/mac.c | 156 +++++++++++++++++++++++++++++++-- + drivers/net/wireless/ath/ath11k/wmi.h | 2 + + 3 files changed, 154 insertions(+), 5 deletions(-) + +--- 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 + struct arvif_nss nss; +-#endif ++ struct list_head ap_vlan_arvifs; + }; + + struct ath11k_vif_iter { +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -4739,6 +4739,11 @@ static void ath11k_sta_rc_update_wk(stru + arvif = arsta->arvif; + ar = arvif->ar; + ++ if (ar->ab->nss.enabled && ++ arsta->arvif->vif->type == NL80211_IFTYPE_AP_VLAN && ++ arsta->use_4addr_set) ++ arvif = arvif->nss.ap_vif; ++ + if (WARN_ON(ath11k_mac_vif_chan(arvif->vif, &def))) + return; + +@@ -4910,17 +4915,28 @@ err_rc_bw_changed: + static void ath11k_sta_set_4addr_wk(struct work_struct *wk) + { + struct ath11k *ar; +- struct ath11k_vif *arvif; ++ struct ath11k_vif *arvif, *ap_vlan_arvif = NULL; ++ struct ieee80211_vif *vif; + struct ath11k_sta *arsta; + struct ieee80211_sta *sta; ++ struct ath11k_base *ab; ++ struct ath11k_peer *wds_peer; ++ u8 wds_addr[ETH_ALEN]; ++ u32 wds_peer_id; + int ret = 0; + + arsta = container_of(wk, struct ath11k_sta, set_4addr_wk); + sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv); + arvif = arsta->arvif; + ar = arvif->ar; ++ ab = ar->ab; + +- ath11k_dbg(ar->ab, ATH11K_DBG_MAC, ++ if (ab->nss.enabled && arvif->vif->type == NL80211_IFTYPE_AP_VLAN) { ++ ap_vlan_arvif = arsta->arvif; ++ arvif = ap_vlan_arvif->nss.ap_vif; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_MAC, + "setting USE_4ADDR for peer %pM\n", sta->addr); + + ret = ath11k_wmi_set_peer_param(ar, sta->addr, +@@ -4928,8 +4944,93 @@ static void ath11k_sta_set_4addr_wk(stru + WMI_PEER_USE_4ADDR, 1); + + if (ret) +- ath11k_warn(ar->ab, "failed to set peer %pM 4addr capability: %d\n", ++ ath11k_warn(ab, "failed to set 4addr for STA %pM: %d\n", + sta->addr, ret); ++ ++ if (!ab->nss.enabled || !ap_vlan_arvif) ++ return; ++ ++ vif = ap_vlan_arvif->vif; ++ ++ spin_lock_bh(&ab->base_lock); ++ wds_peer = ath11k_peer_find_by_addr(ab, sta->addr); ++ if (!wds_peer) { ++ spin_unlock_bh(&ab->base_lock); ++ ath11k_warn(ab, "mac sta use 4addr failed to find peer %pM\n", ++ sta->addr); ++ return; ++ } ++ ++ wds_peer_id = wds_peer->peer_id; ++ ether_addr_copy(wds_addr, wds_peer->addr); ++ spin_unlock_bh(&ab->base_lock); ++ ++ /* skip NSS ext vdev registration if already done */ ++ if (ap_vlan_arvif->nss.wds_cfg_done) ++ goto skip_nss_ext; ++ ++ ret = ath11k_nss_ext_vdev_configure(ap_vlan_arvif); ++ if (ret) { ++ ath11k_warn(ab, "failed to nss cfg ext vdev %pM: %d\n", ++ vif->addr, ret); ++ goto ext_vdev_delete; ++ } ++ ++ ap_vlan_arvif->nss.wds_cfg_done = true; ++ ++skip_nss_ext: ++ ++ ret = ath11k_nss_ext_vdev_cfg_wds_peer(ap_vlan_arvif, ++ wds_addr, wds_peer_id); ++ if (ret) { ++ ath11k_warn(ab, "failed to nss cfg_wds_peer %pM on %pM: %d\n", ++ sta->addr, vif->addr, ret); ++ goto ext_vdev_delete; ++ } ++ ++ ret = ath11k_nss_ext_vdev_wds_4addr_allow(ap_vlan_arvif, ++ wds_peer_id); ++ if (ret) { ++ ath11k_warn(ab, "failed to nss 4addr allow %pM: %d\n", ++ vif->addr, ret); ++ goto ext_vdev_delete; ++ } ++ ++ ret = ath11k_nss_ext_vdev_up(ap_vlan_arvif); ++ if (ret) { ++ ath11k_warn(ab, "failed to nss ext vdev up %pM: %d\n", ++ vif->addr, ret); ++ goto ext_vdev_delete; ++ } ++ ++ spin_lock_bh(&ab->base_lock); ++ wds_peer->nss.ext_vdev_up = true; ++ wds_peer->nss.ext_vif = vif; ++ spin_unlock_bh(&ab->base_lock); ++ ++ /* NAWDS and CFG_WDS_BACKHAUL configs should be done on corresponding ++ * AP vif of the AP_VLAN vif ++ */ ++ ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, ++ WMI_VDEV_PARAM_AP_ENABLE_NAWDS, ++ MIN_IDLE_INACTIVE_TIME_SECS); ++ if (ret) { ++ ath11k_warn(ab, "failed to set vdev %i nawds parameters: %d\n", ++ arvif->vdev_id, ret); ++ goto ext_vdev_down; ++ } ++ ++ return; ++ ++ext_vdev_down: ++ ath11k_nss_ext_vdev_down(ap_vlan_arvif); ++ext_vdev_delete: ++ ath11k_nss_ext_vdev_delete(ap_vlan_arvif); ++ ++ spin_lock_bh(&ar->data_lock); ++ list_del(&ap_vlan_arvif->list); ++ spin_unlock_bh(&ar->data_lock); ++ ap_vlan_arvif->nss.added = false; + } + + static int ath11k_mac_inc_num_stations(struct ath11k_vif *arvif, +@@ -5278,9 +5379,32 @@ static void ath11k_mac_op_sta_set_4addr( + struct ieee80211_sta *sta, bool enabled) + { + struct ath11k *ar = hw->priv; ++ struct ath11k_vif *arvif = (void *)vif->drv_priv; + struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); ++ struct ath11k_vif *ap_arvif = NULL; + + if (enabled && !arsta->use_4addr_set) { ++ if (ar->ab->nss.enabled && vif->type == NL80211_IFTYPE_AP_VLAN) { ++ /* 4addr STA is initially associated to AP vif, change ++ * it to AP_VLAN vif and add AP_VLAN vif to AP vifs list ++ */ ++ ap_arvif = arsta->arvif; ++ arvif->nss.ap_vif = ap_arvif; ++ ++ /* Check if the vlan arvif object was already present in the ++ * list. We can receive this path multiple times for the same ++ * vlan vif for different sta objects ++ */ ++ if (!arvif->nss.added) { ++ spin_lock_bh(&ar->data_lock); ++ list_add(&arvif->list, &ap_arvif->ap_vlan_arvifs); ++ spin_unlock_bh(&ar->data_lock); ++ arvif->nss.added = true; ++ } ++ ++ arsta->arvif = arvif; ++ } ++ + 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 + u32 param_id, param_value; + int ret; + ++ if (ab->nss.enabled && vif->type == NL80211_IFTYPE_AP_VLAN) ++ return 0; ++ + 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 + goto err; + } + +- if (ar->num_created_vdevs > (TARGET_NUM_VDEVS(ab) - 1)) { ++ if (vif->type != NL80211_IFTYPE_AP_VLAN && ++ ar->num_created_vdevs > (TARGET_NUM_VDEVS(ab) - 1)) { + 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 + arvif->vif = vif; + + INIT_LIST_HEAD(&arvif->list); ++ ++ if ((vif->type == NL80211_IFTYPE_AP_VLAN || ++ vif->type == NL80211_IFTYPE_STATION) && ab->nss.enabled) { ++ if (ath11k_frame_mode == ATH11K_HW_TXRX_ETHERNET && ++ ieee80211_set_hw_80211_encap(vif, true)) { ++ vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR; ++ arvif->nss.encap = ATH11K_HW_TXRX_ETHERNET; ++ arvif->nss.decap = ATH11K_HW_TXRX_ETHERNET; ++ } ++ ++ if (vif->type == NL80211_IFTYPE_AP_VLAN) { ++ ret = ath11k_nss_ext_vdev_create(arvif); ++ if (ret) { ++ ath11k_warn(ab, "failed to create ext vdev %pM: %d\n", ++ vif->addr, ret); ++ goto err; ++ } ++ mutex_unlock(&ar->conf_mutex); ++ return ret; ++ } ++ } ++ + 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 + fallthrough; + case NL80211_IFTYPE_AP: + arvif->vdev_type = WMI_VDEV_TYPE_AP; ++ INIT_LIST_HEAD(&arvif->ap_vlan_arvifs); + break; + case NL80211_IFTYPE_MONITOR: + arvif->vdev_type = WMI_VDEV_TYPE_MONITOR; +@@ -7164,13 +7315,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; ++ struct ath11k_vif *ap_vlan_arvif, *tmp; + int ret; + int i; + +- cancel_delayed_work_sync(&arvif->connection_loss_work); +- + mutex_lock(&ar->conf_mutex); + ++ if (vif->type == NL80211_IFTYPE_AP_VLAN) { ++ ath11k_nss_ext_vdev_delete(arvif); ++ ++ /* In case the vlan vif never got added into the ap vlan arvifs ++ * list, avoid removal here ++ */ ++ if (!arvif->nss.added) ++ goto unlock; ++ ++ spin_lock_bh(&ar->data_lock); ++ list_del(&arvif->list); ++ spin_unlock_bh(&ar->data_lock); ++ ++ goto unlock; ++ } ++ ++ cancel_delayed_work_sync(&arvif->connection_loss_work); ++ + 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 + if (ret) + ath11k_warn(ab, "failed to submit AP self-peer removal on vdev %d: %d\n", + arvif->vdev_id, ret); ++ ++ list_for_each_entry_safe(ap_vlan_arvif, tmp, &arvif->ap_vlan_arvifs, ++ list) { ++ ath11k_nss_ext_vdev_delete(ap_vlan_arvif); ++ spin_lock_bh(&ar->data_lock); ++ list_del(&ap_vlan_arvif->list); ++ spin_unlock_bh(&ar->data_lock); ++ } + } + + ret = ath11k_mac_vdev_delete(ar, arvif); +@@ -7230,8 +7406,7 @@ err_vdev_del: + + ath11k_debugfs_remove_interface(arvif); + +- /* TODO: recal traffic pause state based on the available vdevs */ +- ++unlock: + mutex_unlock(&ar->conf_mutex); + } + +@@ -7291,16 +7466,17 @@ static int ath11k_mac_op_ampdu_action(st + struct ieee80211_ampdu_params *params) + { + struct ath11k *ar = hw->priv; ++ struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); + int ret = -EINVAL; + + mutex_lock(&ar->conf_mutex); + + switch (params->action) { + case IEEE80211_AMPDU_RX_START: +- ret = ath11k_dp_rx_ampdu_start(ar, params); ++ ret = ath11k_dp_rx_ampdu_start(arvif, params); + break; + case IEEE80211_AMPDU_RX_STOP: +- ret = ath11k_dp_rx_ampdu_stop(ar, params); ++ ret = ath11k_dp_rx_ampdu_stop(arvif, params); + break; + case IEEE80211_AMPDU_TX_START: + case IEEE80211_AMPDU_TX_STOP_CONT: +@@ -8823,6 +8999,7 @@ static void ath11k_mac_op_sta_statistics + { + struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); + struct ath11k *ar = arsta->arvif->ar; ++ struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); + 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 + ATH11K_DEFAULT_NOISE_FLOOR; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); + +- ath11k_nss_update_sta_stats(sinfo, sta, arsta); ++ if (arvif->ar->ab->nss.enabled) ++ ath11k_nss_update_sta_stats(arvif, sinfo, sta); + } + + #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 { + WMI_VDEV_SUBTYPE_MESH_11S, + }; + ++#define MIN_IDLE_INACTIVE_TIME_SECS 256 ++ + enum wmi_sta_powersave_param { + WMI_STA_PS_PARAM_RX_WAKE_POLICY = 0, + 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: + return ret; + } + +-int ath11k_dp_rx_ampdu_start(struct ath11k *ar, ++int ath11k_dp_rx_ampdu_start(struct ath11k_vif *arvif, + struct ieee80211_ampdu_params *params) + { ++ struct ath11k *ar = arvif->ar; + struct ath11k_base *ab = ar->ab; + struct ath11k_sta *arsta = ath11k_sta_to_arsta(params->sta); +- int vdev_id = arsta->arvif->vdev_id; ++ int vdev_id = arvif->vdev_id; + 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 + return ret; + } + +-int ath11k_dp_rx_ampdu_stop(struct ath11k *ar, ++int ath11k_dp_rx_ampdu_stop(struct ath11k_vif *arvif, + struct ieee80211_ampdu_params *params) + { ++ struct ath11k *ar = arvif->ar; + struct ath11k_base *ab = ar->ab; + struct ath11k_peer *peer; +- struct ath11k_sta *arsta = ath11k_sta_to_arsta(params->sta); +- int vdev_id = arsta->arvif->vdev_id; ++ int vdev_id = arvif->vdev_id; + dma_addr_t paddr; + bool active; + 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; + +-int ath11k_dp_rx_ampdu_start(struct ath11k *ar, ++int ath11k_dp_rx_ampdu_start(struct ath11k_vif *arvif, + struct ieee80211_ampdu_params *params); +-int ath11k_dp_rx_ampdu_stop(struct ath11k *ar, ++int ath11k_dp_rx_ampdu_stop(struct ath11k_vif *arvif, + struct ieee80211_ampdu_params *params); + int ath11k_dp_peer_rx_pn_replay_config(struct ath11k_vif *arvif, + 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 + return NULL; + } + ++struct ath11k_ast_entry *ath11k_peer_ast_find_by_pdev_idx(struct ath11k *ar, ++ u8* addr) ++{ ++ struct ath11k_base *ab = ar->ab; ++ struct ath11k_ast_entry *ast_entry; ++ struct ath11k_peer *peer; ++ ++ lockdep_assert_held(&ab->base_lock); ++ ++ list_for_each_entry(peer, &ab->peers, list) ++ list_for_each_entry(ast_entry, &peer->ast_entry_list, ase_list) ++ if (ether_addr_equal(ast_entry->addr, addr) && ++ ast_entry->pdev_idx == ar->pdev_idx) ++ return ast_entry; ++ ++ return NULL; ++} ++ + 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 + } + + if (type != ATH11K_AST_TYPE_STATIC) { +- ast_entry = ath11k_peer_ast_find_by_addr(ab, mac_addr); +- if (ast_entry) { ++ ast_entry = ath11k_peer_ast_find_by_pdev_idx(ar, mac_addr); ++ if (ast_entry && ast_entry->type != ATH11K_AST_TYPE_STATIC) { + 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 + 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); + +- flush_work(&ast_entry->wds_wmi_wk); + 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 * + + peer = ast_entry->peer; + +- ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_del_ast peer %pM ast_entry %pM\n", +- peer->addr, ast_entry->addr); ++ ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_del_ast pdev:%d peer %pM ast_entry %pM\n", ++ ar->pdev->pdev_id, peer->addr, ast_entry->addr); + + if (ast_entry->is_mapped) + list_del(&ast_entry->ase_list); +--- a/drivers/net/wireless/ath/ath11k/peer.h ++++ b/drivers/net/wireless/ath/ath11k/peer.h +@@ -34,6 +34,7 @@ enum ath11k_ast_entry_type { + enum ath11k_wds_wmi_action { + ATH11K_WDS_WMI_ADD = 1, + ATH11K_WDS_WMI_UPDATE, ++ ATH11K_WDS_WMI_REMOVE, + + ATH11K_WDS_WMI_MAX + }; +@@ -126,6 +127,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); ++struct ath11k_ast_entry *ath11k_peer_ast_find_by_pdev_idx(struct ath11k *ar, ++ u8* addr); + 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 + { + return NULL; + } ++ ++static inline struct ath11k_ast_entry *ath11k_peer_ast_find_by_pdev_idx(struct ath11k *ar, ++ u8* addr) ++{ ++ return NULL; ++} + + static inline int ath11k_peer_add_ast(struct ath11k *ar, struct ath11k_peer *peer, + 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 + + peer->nss.nss_stats->tx_failed += tx_dropped; + +- ATH11K_NSS_TXRX_NETDEV_STATS(tx, peer->vif, tx_bytes, tx_packets); ++ if (peer->nss.ext_vdev_up) ++ ATH11K_NSS_TXRX_NETDEV_STATS(tx, peer->nss.ext_vif, tx_bytes, tx_packets); ++ else ++ ATH11K_NSS_TXRX_NETDEV_STATS(tx, peer->vif, tx_bytes, tx_packets); + + 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 + 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); ++ 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 + case ATH11K_NSS_WIFI_VDEV_DECAP_TYPE_CMD: + cmd = NSS_WIFI_VDEV_DECAP_TYPE_CMD; + break; ++ case ATH11K_NSS_WIFI_VDEV_CFG_WDS_BACKHAUL_CMD: ++ cmd = NSS_WIFI_VDEV_CFG_WDS_BACKHAUL_CMD; ++ break; + default: + return -EINVAL; + } +--- 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 { + 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 { + uint32_t *vaddr; + dma_addr_t paddr; + bool ext_vdev_up; ++ struct ieee80211_vif *ext_vif; + struct peer_stats *nss_stats; + struct completion complete; + }; 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/ath11k_nss/904-002-ath11k-extend-ext-vdev-in-NSS-for-dynamic-VLAN-handling.patch new file mode 100644 index 00000000000000..c97edcd605d7f1 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/904-002-ath11k-extend-ext-vdev-in-NSS-for-dynamic-VLAN-handling.patch @@ -0,0 +1,213 @@ +From 6f51430f2614ca2fb2a1e45cc81464c6d7a29f03 Mon Sep 17 00:00:00 2001 +From: Sathishkumar Muruganandam +Date: Fri, 8 Jan 2021 00:34:09 +0530 +Subject: [PATCH 2/3] ath11k: extend ext vdev in NSS for dynamic VLAN handling + +- add ext vdev NSS API callbacks required for dynamic AP_VLAN vif +- existing ext vdev NSS API callbacks are used for both WDS and + dynamic VLAN di_types. + +Signed-off-by: Sathishkumar Muruganandam +--- + drivers/net/wireless/ath/ath11k/nss.c | 101 +++++++++++++++++++++++++++++++--- + drivers/net/wireless/ath/ath11k/nss.h | 17 ++++++ + 2 files changed, 109 insertions(+), 9 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/nss.c ++++ b/drivers/net/wireless/ath/ath11k/nss.c +@@ -1483,14 +1483,11 @@ static int ath11k_nss_ext_vdev_register( + struct ath11k *ar = arvif->ar; + struct ath11k_base *ab = ar->ab; + nss_tx_status_t status; +- enum nss_dynamic_interface_type di_type; + u32 features = 0; + + if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN || arvif->nss.ctx) + return -EINVAL; + +- di_type = NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_WDS; +- + 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, +@@ -1518,7 +1515,8 @@ static void ath11k_nss_ext_vdev_free(str + + status = nss_dynamic_interface_dealloc_node( + arvif->nss.if_num, +- NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_WDS); ++ arvif->nss.di_type); ++ + if (status != NSS_TX_SUCCESS) + ath11k_warn(ab, "failed to free nss ext vdev err:%d\n", + status); +@@ -1527,14 +1525,19 @@ static void ath11k_nss_ext_vdev_free(str + "nss ext vdev interface deallocated\n"); + } + +-static int ath11k_nss_ext_vdev_alloc(struct ath11k_vif *arvif) ++static int ath11k_nss_ext_vdev_alloc(struct ath11k_vif *arvif, ++ struct wireless_dev *wdev) + { + struct ath11k_base *ab = arvif->ar->ab; + enum nss_dynamic_interface_type di_type; + int if_num; + +- di_type = NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_WDS; ++ if (wdev->use_4addr) ++ di_type = NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_WDS; ++ else ++ di_type = NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_VLAN; + ++ arvif->nss.di_type = di_type; + if_num = nss_dynamic_interface_alloc_node(di_type); + if (if_num < 0) { + ath11k_warn(ab, "failed to allocate nss ext vdev\n"); +@@ -1543,8 +1546,8 @@ static int ath11k_nss_ext_vdev_alloc(str + + arvif->nss.if_num = if_num; + ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, +- "nss ext vdev interface %pM allocated if_num %d\n", +- arvif->vif->addr, if_num); ++ "nss ext vdev interface %pM di_type %d allocated if_num %d\n", ++ arvif->vif->addr, di_type, if_num); + + return 0; + } +@@ -1573,7 +1576,7 @@ int ath11k_nss_ext_vdev_create(struct at + return -EINVAL; + } + +- ret = ath11k_nss_ext_vdev_alloc(arvif); ++ ret = ath11k_nss_ext_vdev_alloc(arvif, wdev); + if (ret) + return ret; + +@@ -1684,6 +1687,86 @@ free: + return ret; + } + ++int ath11k_nss_ext_vdev_cfg_dyn_vlan(struct ath11k_vif *arvif, u16 vlan_id) ++{ ++ struct ath11k *ar = arvif->ar; ++ struct nss_wifi_ext_vdev_msg *ext_vdev_msg = NULL; ++ struct nss_wifi_ext_vdev_vlan_msg *cfg_dyn_vlan_msg = NULL; ++ nss_tx_status_t status; ++ int ret; ++ ++ if (!ar->ab->nss.enabled) ++ return 0; ++ ++ if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN) ++ return -EINVAL; ++ ++ ext_vdev_msg = kzalloc(sizeof(struct nss_wifi_ext_vdev_msg), GFP_ATOMIC); ++ if (!ext_vdev_msg) ++ return -ENOMEM; ++ ++ cfg_dyn_vlan_msg = &ext_vdev_msg->msg.vmsg; ++ cfg_dyn_vlan_msg->vlan_id = vlan_id; ++ ++ nss_wifi_ext_vdev_msg_init(ext_vdev_msg, arvif->nss.if_num, ++ NSS_WIFI_EXT_VDEV_MSG_CONFIGURE_VLAN, ++ sizeof(struct nss_wifi_ext_vdev_vlan_msg), ++ NULL, arvif); ++ ++ status = nss_wifi_ext_vdev_tx_msg_sync(arvif->nss.ctx, ext_vdev_msg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "failed to configure dyn vlan nss_err:%d\n", ++ status); ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ ret = 0; ++free: ++ kfree(ext_vdev_msg); ++ ++ return ret; ++} ++ ++int ath11k_nss_dyn_vlan_set_group_key(struct ath11k_vif *arvif, u16 vlan_id, ++ u16 group_key) ++{ ++ struct nss_wifi_vdev_msg *vdev_msg = NULL; ++ struct nss_wifi_vdev_set_vlan_group_key *vlan_group_key; ++ struct ath11k *ar = arvif->ar; ++ nss_tx_status_t status; ++ int ret = 0; ++ ++ if (!ar->ab->nss.enabled) ++ return 0; ++ ++ vdev_msg = kzalloc(sizeof(struct nss_wifi_vdev_msg), GFP_ATOMIC); ++ if (!vdev_msg) ++ return -ENOMEM; ++ ++ vlan_group_key = &vdev_msg->msg.vlan_group_key; ++ vlan_group_key->vlan_id = vlan_id; ++ vlan_group_key->group_key = group_key; ++ ++ nss_wifi_vdev_msg_init(vdev_msg, arvif->nss.if_num, ++ NSS_WIFI_VDEV_SET_GROUP_KEY, ++ sizeof(struct nss_wifi_vdev_set_vlan_group_key), ++ NULL, NULL); ++ ++ status = nss_wifi_vdev_tx_msg(ar->nss.ctx, vdev_msg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "nss vdev set vlan group key error %d\n", status); ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS_WDS, "nss vdev set vlan group key success\n"); ++free: ++ kfree(vdev_msg); ++ return ret; ++ ++} ++ + /*----------------------------Peer Setup/Config -----------------------------*/ + + 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 +@@ -150,6 +150,10 @@ struct arvif_nss { + bool added; + /* Flag to notify if ext vdev is up/down */ + bool ext_vdev_up; ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ /* Keep the copy of di_type for nss */ ++ enum nss_dynamic_interface_type di_type; ++#endif + /* WDS cfg should be done only once for ext vdev */ + bool wds_cfg_done; + bool created; +@@ -215,6 +217,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); ++int ath11k_nss_ext_vdev_cfg_dyn_vlan(struct ath11k_vif *arvif, u16 vlan_id); ++int ath11k_nss_dyn_vlan_set_group_key(struct ath11k_vif *arvif, u16 vlan_id, ++ u16 group_key); + 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, +@@ -343,6 +348,18 @@ static inline int ath11k_nss_ext_vdev_do + { + return 0; + } ++ ++static inline int ath11k_nss_ext_vdev_cfg_dyn_vlan(struct ath11k_vif *arvif, ++ u16 vlan_id) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_dyn_vlan_set_group_key(struct ath11k_vif *arvif, ++ u16 vlan_id, u16 group_key) ++{ ++ return 0; ++} + + static inline void ath11k_nss_peer_stats_enable(struct ath11k *ar) + { 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/ath11k_nss/904-003-ath11k-add-dynamic-VLAN-support-in-NSS-offload.patch new file mode 100644 index 00000000000000..2361523d394ac4 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/904-003-ath11k-add-dynamic-VLAN-support-in-NSS-offload.patch @@ -0,0 +1,557 @@ +From da432fe6dda831c867416d338def3e277c989287 Mon Sep 17 00:00:00 2001 +From: Sathishkumar Muruganandam +Date: Fri, 8 Jan 2021 00:39:47 +0530 +Subject: [PATCH 3/3] ath11k: add dynamic VLAN support in NSS offload + +Driver should advertise NL80211_EXT_FEATURE_VLAN_OFFLOAD to enable +vlan offload in hostapd. + +Group Key for multiple vlan interfaces are configured with the help +of group key index as NSS uses this index to get the corresponding +group key during transmission. + +Each dynamic AP-VLAN interface choose unique group key index which +will be sent to NSS along with VLAN ID for dynamic VLAN ext vdev +configuration. + +ath11k_mac_op_set_key() does the NSS ext vdev config upon receiving +VLAN ID on group key. + +ath11k_mac_op_sta_state() does the STA assignment from AP vif to +AP_VLAN vif in NSS after mac80211. + +Currently, the firmware supports upto 128 group keys for an AP +interface. The multiple group key support can be enabled during +resource config. + +Co-Developed-by: Seevalamuthu Mariappan +Signed-off-by: Seevalamuthu Mariappan +Signed-off-by: Sathishkumar Muruganandam +--- + drivers/net/wireless/ath/ath11k/core.h | 8 ++ + drivers/net/wireless/ath/ath11k/mac.c | 237 ++++++++++++++++++++++++++++++--- + drivers/net/wireless/ath/ath11k/wmi.c | 5 + + drivers/net/wireless/ath/ath11k/wmi.h | 2 + + 4 files changed, 233 insertions(+), 19 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -98,6 +98,11 @@ enum ath11k_crypt_mode { + ATH11K_CRYPT_MODE_SW, + }; + ++#define ATH11K_GROUP_KEYS_NUM_MAX 128 ++#define ATH11K_FREE_GROUP_IDX_MAP_BITS (BITS_PER_BYTE * (sizeof(long))) ++#define ATH11K_FREE_GROUP_IDX_MAP_MAX (ATH11K_GROUP_KEYS_NUM_MAX / \ ++ ATH11K_FREE_GROUP_IDX_MAP_BITS) ++ + 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 { + u32 tx_compl_fail[ATH11K_STATS_MGMT_FRM_TYPE_MAX]; + }; + ++/** ++ *struct ath11k_dyn_vlan_cfg - dynamic vlan config state info container. ++ * will be used during ieee80211_reconfig ++ * nss offload case ++ *@arvif: driver's data for the corresponding AP_VLAN ieee80211_vif ++ *@sta: ieee80211_sta which is getting associated to AP_VLAN ++ *@cfg_list: list to hold all associated sta's state ++ */ ++struct ath11k_dyn_vlan_cfg { ++ struct ath11k_vif *arvif; ++ struct ieee80211_sta *sta; ++ struct list_head cfg_list; ++}; ++ + 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; + struct arvif_nss nss; + struct list_head ap_vlan_arvifs; ++ /* list required by Dynamic VLAN during fw_recovery */ ++ struct list_head dyn_vlan_cfg; ++ /* VLAN keyidx map required for Dynamic VLAN */ ++ u16 *vlan_keyid_map; ++ DECLARE_BITMAP(free_groupidx_map, ATH11K_GROUP_KEYS_NUM_MAX); + }; + + 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 + return ret; + } + ++static int ath11k_mac_cfg_dyn_vlan(struct ath11k_base *ab, ++ struct ath11k_vif *ap_vlan_arvif, ++ struct ieee80211_sta *sta); ++ + u8 ath11k_mac_bw_to_mac80211_bw(u8 bw) + { + u8 ret = 0; +@@ -720,6 +724,33 @@ u8 ath11k_mac_get_target_pdev_id(struct + return ar->ab->target_pdev_ids[0].pdev_id; + } + ++struct ath11k_vif *ath11k_mac_get_ap_arvif_by_addr(struct ath11k_base *ab, ++ const u8 *addr) ++{ ++ int i; ++ struct ath11k_pdev *pdev; ++ struct ath11k_vif *arvif; ++ struct ath11k *ar; ++ ++ for (i = 0; i < ab->num_radios; i++) { ++ pdev = rcu_dereference(ab->pdevs_active[i]); ++ if (pdev && pdev->ar) { ++ ar = pdev->ar; ++ ++ spin_lock_bh(&ar->data_lock); ++ list_for_each_entry(arvif, &ar->arvifs, list) { ++ if (arvif->vif->type == NL80211_IFTYPE_AP && ++ ether_addr_equal(arvif->vif->addr, addr)) { ++ spin_unlock_bh(&ar->data_lock); ++ return arvif; ++ } ++ } ++ spin_unlock_bh(&ar->data_lock); ++ } ++ } ++ return NULL; ++} ++ + 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 + if (test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags)) + return 0; + ++ if (key->vlan_id) ++ arg.group_key_idx = key->hw_key_idx; ++ + 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 + return first_errno; + } + ++static int ath11k_get_vlan_groupkey_index(struct ath11k_vif *arvif, ++ struct ieee80211_key_conf *key) ++{ ++ struct ath11k *ar = arvif->ar; ++ int map_idx = 0; ++ int free_bit; ++ ++ for (map_idx = 0; map_idx < ATH11K_FREE_GROUP_IDX_MAP_MAX; map_idx++) ++ if (arvif->free_groupidx_map[map_idx] != 0) ++ break; ++ ++ if (map_idx == ATH11K_FREE_GROUP_IDX_MAP_MAX) ++ return -ENOSPC; ++ ++ spin_lock_bh(&ar->data_lock); ++ /* select the first free key index */ ++ free_bit = __ffs64(arvif->free_groupidx_map[map_idx]); ++ key->hw_key_idx = (map_idx * ATH11K_FREE_GROUP_IDX_MAP_BITS) + free_bit; ++ /* clear the selected bit from free index map */ ++ clear_bit(key->hw_key_idx, arvif->free_groupidx_map); ++ spin_unlock_bh(&ar->data_lock); ++ ++ return 0; ++} ++ + static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) + { + struct ath11k *ar = hw->priv; + struct ath11k_base *ab = ar->ab; +- struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); ++ struct ath11k_vif *arvif, *ap_vlan_arvif = NULL; + struct ath11k_peer *peer; +- struct ath11k_sta *arsta; ++ struct ath11k_sta *arsta = NULL; + const u8 *peer_addr; + int ret = 0; + u32 flags = 0; +@@ -4288,17 +4347,38 @@ static int ath11k_mac_op_set_key(struct + if (key->keyidx > WMI_MAX_KEY_INDEX) + return -ENOSPC; + +- mutex_lock(&ar->conf_mutex); ++ arvif = ath11k_vif_to_arvif(vif); + +- if (sta) ++ mutex_lock(&ar->conf_mutex); ++ if (sta) { + peer_addr = sta->addr; +- else if (arvif->vdev_type == WMI_VDEV_TYPE_STA) ++ arsta = (struct ath11k_sta *)sta->drv_priv; ++ } else if (arvif->vdev_type == WMI_VDEV_TYPE_STA) { + peer_addr = vif->bss_conf.bssid; +- else ++ } else { + peer_addr = vif->addr; ++ } + + key->hw_key_idx = key->keyidx; + ++ if (ab->nss.enabled && vif->type == NL80211_IFTYPE_AP_VLAN) { ++ ap_vlan_arvif = arvif; ++ if (arsta) { ++ ap_vlan_arvif->nss.ap_vif = arsta->arvif; ++ arvif = arsta->arvif; ++ } else { ++ rcu_read_lock(); ++ arvif = ath11k_mac_get_ap_arvif_by_addr(ab, peer_addr); ++ if (!arvif) { ++ rcu_read_unlock(); ++ ret = -EINVAL; ++ goto exit; ++ } ++ ap_vlan_arvif->nss.ap_vif = arvif; ++ rcu_read_unlock(); ++ } ++ } ++ + /* 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 + goto exit; + } + ++ /* VLAN ID is updated non-zero only for AP_VLAN vif */ ++ if (key->vlan_id && !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE) && ++ ap_vlan_arvif) { ++ if (arvif->vlan_keyid_map) ++ key->hw_key_idx = arvif->vlan_keyid_map[key->vlan_id]; ++ else ++ key->hw_key_idx = 0; ++ switch (cmd) { ++ case SET_KEY: ++ /* If the group key idx is already available, ++ * no need to find the free index again. ++ * This happens during GTK rekey. It uses ++ * the same index after rekey also. ++ */ ++ if (!key->hw_key_idx) ++ ret = ath11k_get_vlan_groupkey_index(arvif, key); ++ break; ++ case DISABLE_KEY: ++ /* If the group key idx is already 0, ++ * no need of freeing the index. ++ */ ++ if (key->hw_key_idx) { ++ spin_lock_bh(&ar->data_lock); ++ /* make the group index as available */ ++ set_bit(key->hw_key_idx, arvif->free_groupidx_map); ++ spin_unlock_bh(&ar->data_lock); ++ } ++ break; ++ default: ++ ret = -EINVAL; ++ } ++ ++ if (ret) { ++ ath11k_warn(ab, "failed to set group key index for vlan %u : %d\n", ++ key->vlan_id, ret); ++ goto exit; ++ } ++ ++ ret = ath11k_nss_ext_vdev_configure(ap_vlan_arvif); ++ if (ret) { ++ ath11k_warn(ab, "failed to nss cfg ext vdev %pM: %d\n", ++ ap_vlan_arvif->vif->addr, ret); ++ goto exit; ++ } ++ ++ ret = ath11k_nss_ext_vdev_cfg_dyn_vlan(ap_vlan_arvif, ++ key->vlan_id); ++ if (ret) { ++ ath11k_warn(ab, "failed to cfg dynamic vlan %d\n", ret); ++ goto exit; ++ } ++ ++ ret = ath11k_nss_dyn_vlan_set_group_key(ap_vlan_arvif->nss.ap_vif, ++ key->vlan_id, ++ key->hw_key_idx); ++ if (ret) { ++ ath11k_warn(ab, "failed to set dynamic vlan group key %d\n", ++ ret); ++ goto exit; ++ } ++ ++ ret = ath11k_nss_ext_vdev_up(ap_vlan_arvif); ++ if (ret) { ++ ath11k_warn(ab, "failed to set dyn vlan UP %d\n", ret); ++ goto exit; ++ } ++ } ++ + 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 + goto unlock; + } + ++ spin_unlock_bh(&ar->ab->base_lock); ++ if (ap_vlan_arvif && ar->state == ATH11K_STATE_RESTARTED) { ++ /* Keys are getting installed during ieee80211_reconfig(). Configuring ++ * dynamic vlan is pending and the state is saved in the ap_vlan ++ * arvif dyn_vlan_cfg list. We will configure it now since nss peer is authorised */ ++ struct ath11k_dyn_vlan_cfg *dyn_vlan_cfg, *tmp; ++ ++ list_for_each_entry_safe(dyn_vlan_cfg, tmp, &ap_vlan_arvif->dyn_vlan_cfg, cfg_list) { ++ struct ieee80211_sta *vlan_sta = dyn_vlan_cfg->sta; ++ ++ ret = ath11k_mac_cfg_dyn_vlan(ar->ab, ap_vlan_arvif, vlan_sta); ++ if (ret) ++ ath11k_warn(ar->ab, "failed to cfg dyn vlan for peer %pM: %d\n", ++ vlan_sta->addr, ret); ++ /* Configuration is used. Free up space */ ++ list_del(&dyn_vlan_cfg->cfg_list); ++ kfree(dyn_vlan_cfg); ++ } ++ } ++ ++ spin_lock_bh(&ar->ab->base_lock); + 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 + peer->mcast_keyidx = key->keyidx; + peer->sec_type_grp = ath11k_dp_tx_get_encrypt_type(key->cipher); + } ++ /* storing group key idx which will be used during rekey */ ++ if (key->vlan_id) ++ arvif->vlan_keyid_map[key->vlan_id] = key->hw_key_idx; + } else if (peer && cmd == DISABLE_KEY) { + peer->keys[key->keyidx] = NULL; + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) + peer->ucast_keyidx = 0; + else + peer->mcast_keyidx = 0; +- } else if (!peer) ++ if (key->vlan_id) ++ arvif->vlan_keyid_map[key->vlan_id] = 0; ++ } else if (!peer) { + /* impossible unless FW goes crazy */ + ath11k_warn(ab, "peer %pM disappeared!\n", peer_addr); ++ } + +- if (sta) { +- arsta = ath11k_sta_to_arsta(sta); ++ if (arsta) { + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_TKIP: +@@ -5186,6 +5360,33 @@ static u32 ath11k_mac_ieee80211_sta_bw_t + return bw; + } + ++static int ath11k_mac_cfg_dyn_vlan(struct ath11k_base *ab, ++ struct ath11k_vif *ap_vlan_arvif, ++ struct ieee80211_sta *sta) ++{ ++ struct ath11k_peer *peer; ++ int peer_id, ret; ++ ++ spin_lock_bh(&ab->base_lock); ++ peer = ath11k_peer_find_by_addr(ab, sta->addr); ++ if (!peer) { ++ ath11k_warn(ab, "failed to find peer for %pM\n", sta->addr); ++ spin_unlock_bh(&ab->base_lock); ++ return -EINVAL; ++ } ++ peer_id = peer->peer_id; ++ spin_unlock_bh(&ab->base_lock); ++ ++ ret = ath11k_nss_ext_vdev_wds_4addr_allow(ap_vlan_arvif, peer_id); ++ if (ret) { ++ ath11k_warn(ab, "failed to set 4addr allow for %pM:%d\n", ++ sta->addr, ret); ++ return ret; ++ } ++ ++ return ret; ++} ++ + 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 + 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) { +@@ -7045,7 +7274,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 && +- ieee80211_set_hw_80211_encap(vif, true)) { ++ (vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)) { + 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 + vif->addr, ret); + goto err; + } ++ INIT_LIST_HEAD(&arvif->dyn_vlan_cfg); + mutex_unlock(&ar->conf_mutex); + return ret; + } +@@ -7082,6 +7312,20 @@ static int ath11k_mac_op_add_interface(s + arvif->vdev_id = bit; + arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE; + ++ spin_lock_bh(&ar->data_lock); ++ /* Configure vlan specific parameters */ ++ for (i = 0; i < ATH11K_FREE_GROUP_IDX_MAP_MAX; i++) ++ arvif->free_groupidx_map[i] = 0xFFFFFFFFL; ++ /* Group idx 0 is not valid for VLAN*/ ++ arvif->free_groupidx_map[0] &= ~(1L); ++ spin_unlock_bh(&ar->data_lock); ++ ++ arvif->vlan_keyid_map = kzalloc(4096, GFP_KERNEL); ++ if (!arvif->vlan_keyid_map) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ + switch (vif->type) { + case NL80211_IFTYPE_UNSPECIFIED: + case NL80211_IFTYPE_STATION: +@@ -7122,7 +7366,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); +- goto err; ++ goto err_keyid; + } + + ar->num_created_vdevs++; +@@ -7281,7 +7525,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); +- goto err; ++ goto err_keyid; + } + } + +@@ -7292,6 +7536,8 @@ err_vdev_del: + list_del(&arvif->list); + spin_unlock_bh(&ar->data_lock); + ++err_keyid: ++ kfree(arvif->vlan_keyid_map); + err: + mutex_unlock(&ar->conf_mutex); + +@@ -7389,6 +7635,7 @@ err_vdev_del: + list_del(&arvif->list); + spin_unlock_bh(&ar->data_lock); + ++ kfree(arvif->vlan_keyid_map); + ath11k_peer_cleanup(ar, arvif->vdev_id); + + idr_for_each(&ar->txmgmt_idr, +@@ -10113,8 +10360,11 @@ static int __ath11k_mac_register(struct + ab->hw_params.bios_sar_capa) + ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa; + +- if (ab->nss.enabled) ++ if (ab->nss.enabled) { + ieee80211_hw_set(ar->hw, SUPPORTS_NSS_OFFLOAD); ++ wiphy_ext_feature_set(ar->hw->wiphy, ++ NL80211_EXT_FEATURE_VLAN_OFFLOAD); ++ } + + ret = ieee80211_register_hw(ar->hw); + 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 + cmd->key_len = arg->key_len; + cmd->key_txmic_len = arg->key_txmic_len; + cmd->key_rxmic_len = arg->key_rxmic_len; ++ cmd->group_key_id = arg->group_key_idx; + + 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 + 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; ++ wmi_cfg->max_num_group_keys = tg_cfg->max_num_group_keys; + } + + static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi, +@@ -4497,6 +4499,9 @@ int ath11k_wmi_cmd_init(struct ath11k_ba + memset(&init_param, 0, sizeof(init_param)); + memset(&config, 0, sizeof(config)); + ++ if (ab->nss.enabled) ++ config.max_num_group_keys = ATH11K_GROUP_KEYS_NUM_MAX; ++ + ab->hw_params.hw_ops->wmi_init_config(ab, &config); + + 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 { + u32 vdev_id; + const u8 *macaddr; + u32 key_idx; ++ u32 group_key_idx; + u32 key_flags; + u32 key_cipher; + u32 key_len; +@@ -5846,6 +5847,7 @@ struct target_resource_config { + u32 bpf_instruction_size; + u32 max_bssid_rx_filters; + u32 use_pdev_id; ++ u32 max_num_group_keys; + u32 peer_map_unmap_v2_support; + u32 sched_params; + u32 twt_ap_pdev_count; diff --git a/target/linux/qualcommax/patches-6.6/9999-add-btcoex-dts.patch b/target/linux/qualcommax/patches-6.6/9999-add-btcoex-dts.patch new file mode 100644 index 00000000000000..83825b782c1b7f --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/9999-add-btcoex-dts.patch @@ -0,0 +1,30 @@ +--- linux-6.1.71/arch/arm64/boot/dts/qcom/ipq8074.dtsi 2024-01-07 01:44:56.908138962 -0500 ++++ linux-6.1.71/arch/arm64/boot/dts/qcom/ipq8074.dtsi 2024-01-07 01:44:58.908138962 -0500 +@@ -1170,7 +1170,14 @@ + wifi: wifi@c0000000 { + compatible = "qcom,ipq8074-wifi"; + reg = <0xc000000 0x2000000>; +- ++ qcom,hw-mode-id = <1>; ++ #ifdef __IPQ_MEM_PROFILE_256_MB__ ++ qcom,tgt-mem-mode = <2>; ++ #elif __IPQ_MEM_PROFILE_512_MB__ ++ qcom,tgt-mem-mode = <1>; ++ #else ++ qcom,tgt-mem-mode = <0>; ++ #endif + interrupts = , + , + , +@@ -1276,6 +1283,12 @@ + "tcl2host-status-ring"; + qcom,rproc = <&q6v5_wcss>; + status = "disabled"; ++ qcom,pta-num = <0>; ++ qcom,coex-mode = <0x2>; ++ qcom,bt-active-time = <0x12>; ++ qcom,bt-priority-time = <0x0c>; ++ qcom,coex-algo = <0x2>; ++ qcom,pta-priority = <0x80800505>; + }; + }; From da54f8be7b14b2129325786c97d86bf89759aca9 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 7 Jan 2024 18:59:36 -0500 Subject: [PATCH 193/225] feeds: update to use personal fork of nss-packages --- feeds.conf.default | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/feeds.conf.default b/feeds.conf.default index 4699f733f878e2..741b14a875d234 100644 --- a/feeds.conf.default +++ b/feeds.conf.default @@ -2,7 +2,8 @@ src-git packages https://git.openwrt.org/feed/packages.git src-git luci https://git.openwrt.org/project/luci.git src-git routing https://git.openwrt.org/feed/routing.git src-git telephony https://git.openwrt.org/feed/telephony.git -src-git nss_packages https://github.com/dimfishr/nss-packages.git +src-git nss_packages https://github.com/qosmio/nss-packages.git;NSS-12.4-K6.1 +src-git sqm_scripts_nss https://github.com/rickkdotnet/sqm-scripts-nss.git #src-git video https://github.com/openwrt/video.git #src-git targets https://github.com/openwrt/targets.git #src-git oldpackages http://git.openwrt.org/packages.git From 483ffd363c889a1cc1d92cb891c66d74d23220a7 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 7 Jan 2024 22:41:14 -0500 Subject: [PATCH 194/225] ath11k_nss: handle qca-nss-drv symbol dependancies --- package/kernel/mac80211/ath.mk | 2 ++ .../199-001-mac80211-add-nss-support.patch | 2 +- ...th11k-Add-support-for-beacon-tx-mode.patch | 4 +-- ...ow-fast-rx-by-bypassing-stats-update.patch | 2 +- ...-fix-clear-peer-keys-during-disassoc.patch | 4 +-- ...unused-RX_FLAGS-from-mac80211_rx_fla.patch | 4 +-- .../640-006-mac80211-add-eht-radiotap.patch | 8 ++--- .../patches/ath11k_nss/900-fix-build.patch | 22 ++++++------- ...N-iftype-support-on-NSS-offload-case.patch | 4 +-- ...-dynamic-VLAN-support-on-NSS-offload.patch | 4 +-- ...-support-on-NSS-offload-for-STA-mode.patch | 32 +++++++++---------- ...02-ath11k-add-HE-stats-in-peer-stats.patch | 18 +++++------ .../902-ath11k-add-btcoex-config.patch | 16 +++++----- ...pport-for-WDS-offload-in-NSS-offload.patch | 2 +- ...dev-in-NSS-for-dynamic-VLAN-handling.patch | 18 +++++------ 15 files changed, 72 insertions(+), 70 deletions(-) diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk index 6795818446ace6..30a8e96f0dd1c4 100644 --- a/package/kernel/mac80211/ath.mk +++ b/package/kernel/mac80211/ath.mk @@ -327,6 +327,8 @@ define KernelPackage/ath11k/config config ATH11K_NSS_SUPPORT bool "Enable NSS WiFi offload" + select NSS_DRV_WIFI_ENABLE + select NSS_DRV_WIFI_EXT_VDEV_ENABLE default y if TARGET_qualcommax config ATH11K_MEM_PROFILE_512M diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch b/package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch index 0b017ec97ad24d..f25def295537ca 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch @@ -225,7 +225,7 @@ Signed-off-by: Sriram R return -EINVAL; --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c -@@ -2379,6 +2379,9 @@ sta_get_last_rx_stats(struct sta_info *s +@@ -2380,6 +2380,9 @@ sta_get_last_rx_stats(struct sta_info *s struct ieee80211_sta_rx_stats *stats = &sta->deflink.rx_stats; int cpu; 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 index a95308a74ed223..5d5a83911d8519 100644 --- 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 @@ -19,7 +19,7 @@ Signed-off-by: Maharaja Kennadyrajan --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -3483,7 +3483,10 @@ static void ath11k_mac_op_bss_info_chang +@@ -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; @@ -31,7 +31,7 @@ Signed-off-by: Maharaja Kennadyrajan ret = ath11k_wmi_pdev_set_param(ar, param_id, param_value, ar->pdev->pdev_id); if (ret) -@@ -3491,8 +3494,9 @@ static void ath11k_mac_op_bss_info_chang +@@ -3489,8 +3492,9 @@ static void ath11k_mac_op_bss_info_chang arvif->vdev_id); else ath11k_dbg(ar->ab, ATH11K_DBG_MAC, 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/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch index bb46abada6b9e3..b0f6b03f750f9e 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch @@ -395,7 +395,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 -@@ -5197,6 +5197,14 @@ static int ath11k_mac_op_sta_state(struc +@@ -5201,6 +5201,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/357-ath11k-fix-clear-peer-keys-during-disassoc.patch b/package/kernel/mac80211/patches/ath11k_nss/357-ath11k-fix-clear-peer-keys-during-disassoc.patch index 5050192acc64ae..414cb06d87bd4b 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/357-ath11k-fix-clear-peer-keys-during-disassoc.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/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 -@@ -4708,12 +4708,6 @@ static int ath11k_station_disassoc(struc +@@ -4712,12 +4712,6 @@ static int ath11k_station_disassoc(struc return ret; } @@ -30,7 +30,7 @@ Signed-off-by: Karthikeyan Kathirvel return 0; } -@@ -5176,6 +5170,17 @@ static int ath11k_mac_op_sta_state(struc +@@ -5180,6 +5174,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/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch b/package/kernel/mac80211/patches/ath11k_nss/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch index 2d1fbc097df375..14fd82cbeaa853 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/ath11k_nss/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 -@@ -1385,8 +1385,6 @@ ieee80211_tx_info_clear_status(struct ie +@@ -1387,8 +1387,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 -@@ -1458,22 +1456,21 @@ enum mac80211_rx_flags { +@@ -1460,22 +1458,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), 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 index b8d2b614dd4759..79146df5447b8b 100644 --- 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 @@ -321,7 +321,7 @@ Signed-off-by: P Praneesh */ --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -1439,7 +1439,11 @@ ieee80211_tx_info_clear_status(struct ie +@@ -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) @@ -333,7 +333,7 @@ Signed-off-by: P Praneesh enum mac80211_rx_flags { RX_FLAG_MMIC_ERROR = BIT(0), RX_FLAG_DECRYPTED = BIT(1), -@@ -1471,6 +1475,8 @@ enum mac80211_rx_flags { +@@ -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), @@ -342,7 +342,7 @@ Signed-off-by: P Praneesh }; /** -@@ -1538,6 +1544,7 @@ enum mac80211_rx_encoding { +@@ -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_\* @@ -350,7 +350,7 @@ Signed-off-by: P Praneesh * @encoding: &enum mac80211_rx_encoding * @bw: &enum rate_info_bw * @enc_flags: uses bits from &enum mac80211_rx_encoding_flags -@@ -1591,6 +1598,7 @@ struct ieee80211_rx_status { +@@ -1593,6 +1600,7 @@ struct ieee80211_rx_status { u8 ampdu_delimiter_crc; u8 zero_length_psdu_type; u8 link_valid:1, link_id:4; diff --git a/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch b/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch index 67d6e5285bdd94..180fb7feab2e49 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch @@ -56,7 +56,7 @@ if (rxcb->is_mcbc) { --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -9224,7 +9224,7 @@ void cfg80211_bss_flush(struct wiphy *wi +@@ -9228,7 +9228,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 +65,7 @@ enum nl80211_commands cmd, u8 count, u64 color_bitmap); -@@ -9234,9 +9234,9 @@ int cfg80211_bss_color_notify(struct net +@@ -9238,9 +9238,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 +77,7 @@ 0, color_bitmap); } -@@ -9250,7 +9250,7 @@ static inline int cfg80211_obss_color_co +@@ -9254,7 +9254,7 @@ static inline int cfg80211_obss_color_co static inline int cfg80211_color_change_started_notify(struct net_device *dev, u8 count) { @@ -86,7 +86,7 @@ count, 0); } -@@ -9262,7 +9262,7 @@ static inline int cfg80211_color_change_ +@@ -9266,7 +9266,7 @@ static inline int cfg80211_color_change_ */ static inline int cfg80211_color_change_aborted_notify(struct net_device *dev) { @@ -95,7 +95,7 @@ 0, 0); } -@@ -9274,7 +9274,7 @@ static inline int cfg80211_color_change_ +@@ -9278,7 +9278,7 @@ static inline int cfg80211_color_change_ */ static inline int cfg80211_color_change_notify(struct net_device *dev) { @@ -106,7 +106,7 @@ } --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -5239,6 +5239,10 @@ void ieee80211_tx_status_ext(struct ieee +@@ -5241,6 +5241,10 @@ void ieee80211_tx_status_ext(struct ieee * (NULL for multicast packets) * @info: tx status information */ @@ -119,7 +119,7 @@ struct ieee80211_tx_info *info) --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -4775,7 +4775,7 @@ void ieee80211_color_collision_detection +@@ -4777,7 +4777,7 @@ void ieee80211_color_collision_detection struct ieee80211_sub_if_data *sdata = link->sdata; sdata_lock(sdata); @@ -141,7 +141,7 @@ sdata->debugfs.subdir_stations = debugfs_create_dir("stations", --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c -@@ -1406,18 +1406,6 @@ static void __sta_info_destroy_part2(str +@@ -1407,18 +1407,6 @@ static void __sta_info_destroy_part2(str WARN_ON_ONCE(ret); } @@ -195,7 +195,7 @@ struct sta_info *sta = container_of(pubsta, struct sta_info, sta); --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -19406,7 +19406,7 @@ void cfg80211_ch_switch_started_notify(s +@@ -19414,7 +19414,7 @@ void cfg80211_ch_switch_started_notify(s } EXPORT_SYMBOL(cfg80211_ch_switch_started_notify); @@ -204,7 +204,7 @@ enum nl80211_commands cmd, u8 count, u64 color_bitmap) { -@@ -19420,7 +19420,7 @@ int cfg80211_bss_color_notify(struct net +@@ -19428,7 +19428,7 @@ int cfg80211_bss_color_notify(struct net trace_cfg80211_bss_color_notify(dev, cmd, count, color_bitmap); @@ -213,7 +213,7 @@ if (!msg) return -ENOMEM; -@@ -19443,7 +19443,7 @@ int cfg80211_bss_color_notify(struct net +@@ -19451,7 +19451,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/902-000-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch b/package/kernel/mac80211/patches/ath11k_nss/902-000-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch index f0fc8c14ec1efd..7dc88faed71f9f 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/ath11k_nss/902-000-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 -@@ -5100,6 +5100,17 @@ void ieee80211_sta_pspoll(struct ieee802 +@@ -5102,6 +5102,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 -@@ -2176,7 +2176,13 @@ static int ieee80211_change_station(stru +@@ -2177,7 +2177,13 @@ static int ieee80211_change_station(stru rcu_assign_pointer(vlansdata->u.vlan.sta, sta); __ieee80211_check_fast_rx_iface(vlansdata); 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/ath11k_nss/902-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch index 143191f6a9bca9..33eb5d2001db91 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/902-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/902-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 -@@ -2089,6 +2089,8 @@ enum ieee80211_key_flags { +@@ -2091,6 +2091,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) -@@ -2108,6 +2110,7 @@ struct ieee80211_key_conf { +@@ -2110,6 +2112,7 @@ struct ieee80211_key_conf { u8 hw_key_idx; s8 keyidx; u16 flags; 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/ath11k_nss/902-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch index 12d42ddaa9ba9c..0e6c0d92d2abde 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/ath11k_nss/902-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 -@@ -655,6 +655,7 @@ struct ath11k { +@@ -634,6 +634,7 @@ struct ath11k { struct ath11k_pdev_wmi *wmi; #ifdef CPTCFG_ATH11K_NSS_SUPPORT struct ath11k_nss nss; @@ -34,7 +34,7 @@ Signed-off-by: Sathishkumar Muruganandam #endif struct ath11k_pdev_dp dp; u8 mac_addr[ETH_ALEN]; -@@ -1065,6 +1066,8 @@ struct ath11k_base { +@@ -1042,6 +1043,8 @@ struct ath11k_base { u32 rx_hash; bool stats_disable; @@ -45,7 +45,7 @@ Signed-off-by: Sathishkumar Muruganandam }; --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h -@@ -1181,13 +1181,16 @@ struct htt_t2h_peer_map_event { +@@ -1142,13 +1142,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 +66,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 -@@ -1890,6 +1890,8 @@ void ath11k_dp_htt_htc_t2h_msg_handler(s +@@ -1756,6 +1756,8 @@ void ath11k_dp_htt_htc_t2h_msg_handler(s u16 peer_mac_h16; u16 ast_hash; u16 hw_peer_id; @@ -75,7 +75,7 @@ Signed-off-by: Sathishkumar Muruganandam ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "dp_htt rx msg type :0x%0x\n", type); -@@ -1925,15 +1927,29 @@ void ath11k_dp_htt_htc_t2h_msg_handler(s +@@ -1791,15 +1793,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); @@ -630,9 +630,9 @@ Signed-off-by: Sathishkumar Muruganandam if (sta) { --- a/drivers/net/wireless/ath/ath11k/peer.h +++ b/drivers/net/wireless/ath/ath11k/peer.h -@@ -18,6 +18,47 @@ struct ppdu_user_delayba { - u32 resp_rate_flags; - }; +@@ -7,6 +7,47 @@ + #ifndef ATH11K_PEER_H + #define ATH11K_PEER_H +enum ath11k_ast_entry_type { + ATH11K_AST_TYPE_NONE, /* static ast entry for connected peer */ @@ -678,7 +678,7 @@ Signed-off-by: Sathishkumar Muruganandam struct ath11k_peer { struct list_head list; struct ieee80211_sta *sta; -@@ -29,6 +70,10 @@ struct ath11k_peer { +@@ -18,6 +59,10 @@ struct ath11k_peer { u8 pdev_idx; u16 hw_peer_id; struct ath11k_nss_peer nss; @@ -689,7 +689,7 @@ Signed-off-by: Sathishkumar Muruganandam /* protected by ab->data_lock */ struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; -@@ -54,8 +99,13 @@ struct ath11k_peer { +@@ -41,8 +86,13 @@ struct ath11k_peer { }; void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id); @@ -703,7 +703,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, -@@ -72,4 +122,71 @@ struct ath11k_peer *ath11k_peer_find_by_ +@@ -59,4 +109,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); @@ -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) { -@@ -6484,6 +6530,36 @@ static int ath11k_pull_peer_assoc_conf_e +@@ -6419,6 +6465,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) { -@@ -7399,6 +7475,7 @@ static int ath11k_wmi_tlv_rdy_parse(stru +@@ -7334,6 +7410,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: -@@ -8870,6 +8947,22 @@ static void ath11k_wmi_gtk_offload_statu +@@ -8805,6 +8882,22 @@ static void ath11k_wmi_gtk_offload_statu kfree(tb); } @@ -905,7 +905,7 @@ 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; -@@ -9000,6 +9093,9 @@ static void ath11k_wmi_tlv_op_rx(struct +@@ -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); break; @@ -961,7 +961,7 @@ Signed-off-by: Sathishkumar Muruganandam /* * PDEV statistics */ -@@ -6503,6 +6533,9 @@ int ath11k_wmi_set_sta_ps_param(struct a +@@ -6430,6 +6460,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/902-ath11k-add-HE-stats-in-peer-stats.patch b/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-HE-stats-in-peer-stats.patch index edb60ac18bef10..4831424fa40810 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-HE-stats-in-peer-stats.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-HE-stats-in-peer-stats.patch @@ -363,7 +363,7 @@ Signed-off-by: Miles Hu /* HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG Message * * details: -@@ -1312,6 +1351,19 @@ enum htt_ppdu_stats_gi { +@@ -1315,6 +1354,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) -@@ -1339,6 +1391,12 @@ enum htt_ppdu_stats_gi { +@@ -1342,6 +1394,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) -@@ -1442,6 +1500,21 @@ struct htt_ppdu_stats_usr_cmpltn_ack_ba_ +@@ -1445,6 +1503,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; -@@ -1455,14 +1528,16 @@ struct htt_ppdu_stats_usr_cmn_array { +@@ -1458,14 +1531,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 { -@@ -1471,7 +1546,7 @@ struct htt_ppdu_stats { +@@ -1474,7 +1549,7 @@ struct htt_ppdu_stats { }; struct htt_ppdu_stats_info { @@ -748,9 +748,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 -@@ -7,6 +7,17 @@ - #ifndef ATH11K_PEER_H - #define ATH11K_PEER_H +@@ -48,6 +48,17 @@ struct ath11k_ast_entry { + struct list_head ase_list; + }; +struct ppdu_user_delayba { + u8 reserved0; @@ -766,7 +766,7 @@ Signed-off-by: Miles Hu struct ath11k_peer { struct list_head list; struct ieee80211_sta *sta; -@@ -38,6 +49,8 @@ struct ath11k_peer { +@@ -83,6 +94,8 @@ struct ath11k_peer { u16 sec_type_grp; bool is_authorized; bool dp_setup_done; diff --git a/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-btcoex-config.patch b/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-btcoex-config.patch index 18bc4384094eca..495245f9662462 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-btcoex-config.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-btcoex-config.patch @@ -29,7 +29,7 @@ struct ath11k { struct ath11k_base *ab; struct ath11k_pdev *pdev; -@@ -759,6 +769,8 @@ struct ath11k { +@@ -760,6 +770,8 @@ struct ath11k { struct ath11k_per_peer_tx_stats cached_stats; u32 last_ppdu_id; u32 cached_ppdu_id; @@ -56,7 +56,7 @@ #include "nss.h" #define CHAN2G(_channel, _freq, _flags) { \ -@@ -9282,6 +9284,91 @@ err_fallback: +@@ -9286,6 +9288,91 @@ err_fallback: return 0; } @@ -148,7 +148,7 @@ static const struct ieee80211_ops ath11k_ops = { .tx = ath11k_mac_op_tx, .wake_tx_queue = ieee80211_handle_wake_tx_queue, -@@ -9521,6 +9608,56 @@ static int ath11k_mac_setup_iface_combin +@@ -9525,6 +9612,56 @@ static int ath11k_mac_setup_iface_combin return 0; } @@ -205,7 +205,7 @@ static const u8 ath11k_if_types_ext_capa[] = { [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT, -@@ -9782,6 +9919,7 @@ static int __ath11k_mac_register(struct +@@ -9786,6 +9923,7 @@ static int __ath11k_mac_register(struct ar->hw->wiphy->ema_max_profile_periodicity = TARGET_EMA_MAX_PROFILE_PERIOD; ath11k_reg_init(ar); @@ -213,7 +213,7 @@ if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) { ar->hw->netdev_features = NETIF_F_HW_CSUM; -@@ -9944,6 +10082,7 @@ int ath11k_mac_allocate(struct ath11k_ba +@@ -9948,6 +10086,7 @@ int ath11k_mac_allocate(struct ath11k_ba */ ath11k_wmi_pdev_attach(ab, i); @@ -447,7 +447,7 @@ +#endif /* QCA_VENDOR_H */ --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -1697,6 +1697,71 @@ int ath11k_wmi_vdev_set_param_cmd(struct +@@ -1743,6 +1743,71 @@ int ath11k_wmi_vdev_set_param_cmd(struct return ret; } @@ -521,7 +521,7 @@ { --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h -@@ -5303,6 +5303,79 @@ struct wmi_wmm_params_arg { +@@ -5333,6 +5333,79 @@ struct wmi_wmm_params_arg { u8 no_ack; }; @@ -601,7 +601,7 @@ struct wmi_vdev_set_wmm_params_cmd { u32 tlv_header; u32 vdev_id; -@@ -6520,6 +6593,8 @@ int ath11k_wmi_pdev_non_srg_obss_color_e +@@ -6553,6 +6626,8 @@ int ath11k_wmi_pdev_non_srg_obss_color_e u32 *bitmap); int ath11k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(struct ath11k *ar, u32 *bitmap); 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/ath11k_nss/903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch index 86714fea844e81..de7bc77ef53456 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/ath11k_nss/903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch @@ -489,7 +489,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 -@@ -34,6 +34,7 @@ enum ath11k_ast_entry_type { +@@ -23,6 +23,7 @@ enum ath11k_ast_entry_type { enum ath11k_wds_wmi_action { ATH11K_WDS_WMI_ADD = 1, ATH11K_WDS_WMI_UPDATE, 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/ath11k_nss/904-002-ath11k-extend-ext-vdev-in-NSS-for-dynamic-VLAN-handling.patch index c97edcd605d7f1..14274b6a72680a 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/ath11k_nss/904-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 -@@ -1483,14 +1483,11 @@ static int ath11k_nss_ext_vdev_register( +@@ -1570,14 +1570,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, -@@ -1518,7 +1515,8 @@ static void ath11k_nss_ext_vdev_free(str +@@ -1605,7 +1602,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); -@@ -1527,14 +1525,19 @@ static void ath11k_nss_ext_vdev_free(str +@@ -1614,14 +1612,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"); -@@ -1543,8 +1546,8 @@ static int ath11k_nss_ext_vdev_alloc(str +@@ -1630,8 +1633,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; } -@@ -1573,7 +1576,7 @@ int ath11k_nss_ext_vdev_create(struct at +@@ -1660,7 +1663,7 @@ int ath11k_nss_ext_vdev_create(struct at return -EINVAL; } @@ -82,7 +82,7 @@ Signed-off-by: Sathishkumar Muruganandam if (ret) return ret; -@@ -1684,6 +1687,86 @@ free: +@@ -1773,6 +1776,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 -@@ -150,6 +150,10 @@ struct arvif_nss { +@@ -179,6 +179,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; -@@ -215,6 +217,9 @@ void ath11k_nss_ext_vdev_unregister(stru +@@ -246,6 +250,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, -@@ -343,6 +348,18 @@ static inline int ath11k_nss_ext_vdev_do +@@ -378,6 +385,18 @@ static inline int ath11k_nss_ext_vdev_do { return 0; } From aac591741e357f2e7e2e3d97174c318ecd20d0fe Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 8 Jan 2024 03:08:03 -0500 Subject: [PATCH 195/225] ath11k_nss: fix ordering of sysctl values `dev.nss.n2hcfg.n2h_wifi_pool_buf` must be set BEFORE setting `dev.nss.n2hcfg.n2h_high_water_core0`, otherwise it resets the value. --- .../mac80211/files/etc/init.d/qca-nss-pbuf | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf index 40f05c46fb28fb..11604d15dc5c47 100755 --- a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf +++ b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf @@ -18,16 +18,23 @@ START=20 apply_sysctl() { [ $(sysctl -n -e dev.nss.general.redirect) = "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. + extra_pbuf_core0=$(sysctl -n -e dev.nss.n2hcfg.extra_pbuf_core0) - 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 - - 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 > /dev/null 2> /dev/null + if [ "$extra_pbuf_core0" = "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 + else + logger -t ath11k_nss "Sysctl key 'extra_pbuf_core0' already set to '"$extra_pbuf_core0"'. Skipping applying wifi nss configs" + fi 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 > /dev/null 2> /dev/null + 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 + } apply_nss_config() { @@ -51,7 +58,7 @@ apply_nss_config() { qnap,301w | \ xiaomi,ax9000 | \ zyxel,nbg7815) - extra_pbuf_core0=10000000 n2h_high_water_core0=72512 n2h_wifi_pool_buf=36864 apply_sysctl + extra_pbuf_core0=9000000 n2h_high_water_core0=67392 n2h_wifi_pool_buf=40960 apply_sysctl ;; # 512MB profile edimax,cax1800 | \ @@ -79,13 +86,5 @@ start() { exit 1 fi - # 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. - extra_pbuf_core0=$(sysctl -n -e dev.nss.n2hcfg.extra_pbuf_core0) - - if [ "$extra_pbuf_core0" = "0" ]; then - apply_nss_config - else - logger -t ath11k_nss "Sysctl key 'extra_pbuf_core0' already set to '"$extra_pbuf_core0"'. Skipping applying wifi nss configs" - fi + apply_nss_config } From b84b8b3893b285cce38ecd0df90b2d332db75abe Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 8 Jan 2024 18:55:20 -0500 Subject: [PATCH 196/225] qualcommax: add nss-macsec dt support --- .../patches-6.6/9999-add-nss-macsec.patch | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.6/9999-add-nss-macsec.patch diff --git a/target/linux/qualcommax/patches-6.6/9999-add-nss-macsec.patch b/target/linux/qualcommax/patches-6.6/9999-add-nss-macsec.patch new file mode 100644 index 00000000000000..1be086be21789f --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/9999-add-nss-macsec.patch @@ -0,0 +1,13 @@ +--- a/arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi 2024-01-08 16:04:51.957322224 -0500 ++++ b/arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi 2024-01-08 16:09:29.079630738 -0500 +@@ -268,4 +268,10 @@ + }; + }; + }; ++ nss-macsec1 { ++ compatible = "qcom,nss-macsec"; ++ phy_addr = <0x1c>; ++ phy_access_mode = <0x00>; ++ mdiobus = <&mdio>; ++ }; + }; From 6f1915aad4a664e3bb89ef6aaf64fcb3ef8e3f91 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Tue, 9 Jan 2024 01:07:01 -0500 Subject: [PATCH 197/225] ath11k_nss: bugfix overwriting high watermark ath11k_nss: bugfix change start order value 'dev.nss.n2hcfg.n2h_wifi_pool_buf' was not getting set, wait till after qca-nss-drv is loaded. ath11k_nss: finally fix n2hcfg values not being set --- .../kernel/mac80211/files/etc/init.d/qca-nss-pbuf | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf index 11604d15dc5c47..50f13b33e89429 100755 --- a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf +++ b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf @@ -14,23 +14,24 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # -START=20 +START=71 apply_sysctl() { - [ $(sysctl -n -e dev.nss.general.redirect) = "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. - extra_pbuf_core0=$(sysctl -n -e dev.nss.n2hcfg.extra_pbuf_core0) - - if [ "$extra_pbuf_core0" = "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 else 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 + 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 > /dev/null 2> /dev/null + 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 From 72e016c2e3ab32046add2eb3237c473e6cdcb721 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Wed, 10 Jan 2024 21:01:36 -0500 Subject: [PATCH 198/225] ath11k_nss: Handle 256/512/1G boards automatically --- package/kernel/mac80211/ath.mk | 45 ++++++--- .../mac80211/files/etc/init.d/qca-nss-pbuf | 9 +- ...07-ath11k-Enable-256_512MB-profiles.patch} | 95 +++++++++++++++---- ...11k-Disable-rx_header-tlv-for-2K-SKB.patch | 26 +++-- ...ow-fast-rx-by-bypassing-stats-update.patch | 2 +- 5 files changed, 139 insertions(+), 38 deletions(-) rename package/kernel/mac80211/patches/ath11k_nss/{207-ath11k-Enable-512MB-profile-in-ath11k.patch => 207-ath11k-Enable-256_512MB-profiles.patch} (77%) diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk index 30a8e96f0dd1c4..af60c499ddde7c 100644 --- a/package/kernel/mac80211/ath.mk +++ b/package/kernel/mac80211/ath.mk @@ -14,9 +14,10 @@ PKG_CONFIG_DEPENDS += \ CONFIG_ATH10K_THERMAL \ CONFIG_ATH11K_THERMAL \ CONFIG_ATH_USER_REGD \ + CONFIG_ATH11K_MEM_PROFILE_1G \ CONFIG_ATH11K_MEM_PROFILE_512M \ - CONFIG_ATH11K_NSS_SUPPORT \ - CONFIG_ATH11K_SMART_ANT_ALG + CONFIG_ATH11K_MEM_PROFILE_256M \ + CONFIG_ATH11K_NSS_SUPPORT ifdef CONFIG_PACKAGE_MAC80211_DEBUGFS config-y += \ @@ -59,9 +60,10 @@ config-$(CONFIG_ATH9K_UBNTHSR) += ATH9K_UBNTHSR config-$(CONFIG_ATH10K_LEDS) += ATH10K_LEDS config-$(CONFIG_ATH10K_THERMAL) += ATH10K_THERMAL config-$(CONFIG_ATH11K_THERMAL) += ATH11K_THERMAL +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_SMART_ANT_ALG) += ATH11K_SMART_ANT_ALG config-$(call config_package,ath9k-htc) += ATH9K_HTC config-$(call config_package,ath10k,regular) += ATH10K ATH10K_PCI @@ -327,20 +329,41 @@ define KernelPackage/ath11k/config config ATH11K_NSS_SUPPORT bool "Enable NSS WiFi offload" + select ATH11K_MEM_PROFILE_512M if (TARGET_qualcommax_ipq807x_DEVICE_edimax_cax1800 || \ + TARGET_qualcommax_ipq807x_DEVICE_compex_wpq873 || \ + TARGET_qualcommax_ipq807x_DEVICE_linksys_mx4200v1 || \ + 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 - config ATH11K_MEM_PROFILE_512M - bool "Use limits for the 512MB memory size" - default n + choice + prompt "ATH11K Memory Profile" + default ATH11K_MEM_PROFILE_1G + help + This option allows you to select the memory profile. + It should correspond to the total RAM of your board. + + config ATH11K_MEM_PROFILE_1G + bool "Use 1G memory profile" + help + This allows configuring ath11k for boards with 1GB+ memory. + + config ATH11K_MEM_PROFILE_512M + bool "Use 512MB memory profile" help - This allows selecting the ath11k memory size profile to be used. + This allows configuring ath11k for boards with 512M memory. + The default is 1GB if not selected - config ATH11K_SMART_ANT_ALG - bool "Enable smart antenna" - depends on PACKAGE_ATH_DEBUG - default n + config ATH11K_MEM_PROFILE_256M + bool "Use 256MB memory profile" + help + This allows configuring ath11k for boards with 256M memory. + The default is 1GB if not selected + endchoice endef define KernelPackage/ath11k-ahb diff --git a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf index 50f13b33e89429..260726fb12d871 100755 --- a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf +++ b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf @@ -47,24 +47,29 @@ apply_nss_config() { case "$board" in # 1GB+ profile + arcadyan,aw1000 | \ buffalo,wxr-5950ax12 | \ dynalink,dl-wrx36 | \ edgecore,eap102 | \ - linksys,mx5300 | \ linksys,mx4200v2 | \ + linksys,mx5300 | \ netgear,rax120v2 | \ netgear,wax620 | \ netgear,wax630 | \ prpl,haze | \ qnap,301w | \ xiaomi,ax9000 | \ + yuncore,ax880 | \ zyxel,nbg7815) extra_pbuf_core0=9000000 n2h_high_water_core0=67392 n2h_wifi_pool_buf=40960 apply_sysctl ;; # 512MB profile edimax,cax1800 | \ + compex,wpq873 | \ linksys,mx4200v1 | \ - xiaomi,ax3600) # 512MB profile + redmi,ax6 | \ + xiaomi,ax3600 | \ + zte,mf269) # 512MB profile extra_pbuf_core0=3100000 n2h_high_water_core0=30624 n2h_wifi_pool_buf=8192 apply_sysctl ;; # 256MB profile diff --git a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-512MB-profile-in-ath11k.patch b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch similarity index 77% rename from package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-512MB-profile-in-ath11k.patch rename to package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch index 0e7ddb8539a207..a4c063ce69ba49 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-512MB-profile-in-ath11k.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch @@ -22,7 +22,7 @@ Signed-off-by: Ramya Gnanasekar --- a/drivers/net/wireless/ath/ath11k/Kconfig +++ b/drivers/net/wireless/ath/ath11k/Kconfig -@@ -23,6 +23,13 @@ config ATH11K_NSS_SUPPORT +@@ -23,6 +23,20 @@ config ATH11K_NSS_SUPPORT If unsure, say Y to enable NSS offload support. @@ -32,36 +32,59 @@ Signed-off-by: Ramya Gnanasekar + default n + ---help--- + Enables 512MB memory profile for ath11k ++ ++config ATH11K_MEM_PROFILE_256M ++ bool "ath11k enable 256MB memory profile" ++ depends on ATH11K ++ default n ++ ---help--- ++ Enables 256MB memory profile for ath11k + config ATH11K_AHB tristate "Atheros ath11k AHB support" depends on m --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h -@@ -11,11 +11,30 @@ +@@ -11,11 +11,43 @@ #include "wmi.h" /* Target configuration defines */ -+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M - ++#if defined(CPTCFG_ATH11K_MEM_PROFILE_256M) ++#define TARGET_NUM_VDEVS 8 ++#define TARGET_NUM_PEERS_PDEV (128 + TARGET_NUM_VDEVS) ++/* Max num of stations (per radio) */ ++#define TARGET_NUM_STATIONS 128 ++#define ATH11K_QMI_TARGET_MEM_MODE ATH11K_QMI_TARGET_MEM_MODE_512M ++#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) +#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) - - #define TARGET_NUM_PEERS_PDEV(ab) (ab->hw_params.num_peers + TARGET_NUM_VDEVS(ab)) +-#define TARGET_NUM_VDEVS(ab) (ab->hw_params.num_vdevs) +- +-#define TARGET_NUM_PEERS_PDEV(ab) (ab->hw_params.num_peers + TARGET_NUM_VDEVS(ab)) ++#define TARGET_NUM_VDEVS(ab) (ab->hw_params.num_vdevs_peers[ab->qmi.target_mem_mode].num_vdevs) ++#define TARGET_NUM_PEERS_PDEV(ab) (ab->hw_params.num_vdevs_peers[ab->qmi.target_mem_mode].num_peers + TARGET_NUM_VDEVS(ab)) +/* Max num of stations (per radio) */ -+#define TARGET_NUM_STATIONS(ab) (ab->hw_params.num_peers) ++#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 @@ -69,7 +92,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 +45,6 @@ +@@ -26,9 +58,6 @@ /* Num of peers for DBS_SBS */ #define TARGET_NUM_PEERS_DBS_SBS(ab) (3 * TARGET_NUM_PEERS_PDEV(ab)) @@ -79,6 +102,14 @@ 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 { + u32 tx_ring_size; + bool smp2p_wow_exit; + bool support_fw_mac_sequence; ++ const struct ath11k_num_vdevs_peers *num_vdevs_peers; + }; + + struct ath11k_hw_ops { --- a/drivers/net/wireless/ath/ath11k/qmi.h +++ b/drivers/net/wireless/ath/ath11k/qmi.h @@ -29,6 +29,12 @@ @@ -107,14 +138,21 @@ Signed-off-by: Ramya Gnanasekar #endif --- a/local-symbols +++ b/local-symbols -@@ -171,6 +171,7 @@ ATH11K= +@@ -171,12 +171,13 @@ ATH11K= ATH11K_AHB= ATH11K_PCI= ATH11K_NSS_SUPPORT= ++ATH11K_MEM_PROFILE_256M= +ATH11K_MEM_PROFILE_512M= ATH11K_DEBUG= ATH11K_DEBUGFS= ATH11K_TRACING= + ATH11K_SPECTRAL= + ATH11K_THERMAL= +-ATH11K_MEM_PROFILE_512M= + ATH12K= + ATH12K_DEBUG= + ATH12K_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 { @@ -226,7 +264,13 @@ Signed-off-by: Ramya Gnanasekar static struct ath11k_hw_params ath11k_hw_params[] = { { .hw_rev = ATH11K_HW_IPQ8074, -@@ -100,6 +104,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -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), @@ -234,7 +278,22 @@ Signed-off-by: Ramya Gnanasekar .supports_regdb = false, .fix_l1ss = true, .credit_flow = false, -@@ -177,7 +182,7 @@ static struct ath11k_hw_params ath11k_hw +- .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,7 +131,9 @@ 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, + .name = "ipq6018 hw1.0", +@@ -177,7 +183,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = true, .coldboot_cal_ftm = true, .cbcal_restart_fw = true, @@ -243,7 +302,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = false, -@@ -259,7 +264,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -259,7 +265,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -252,7 +311,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -426,7 +431,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -426,7 +432,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -261,7 +320,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -509,7 +514,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -509,7 +515,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -270,7 +329,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -593,7 +598,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -593,7 +599,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = true, .coldboot_cal_ftm = true, .cbcal_restart_fw = false, @@ -279,7 +338,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = false, -@@ -672,7 +677,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -672,7 +678,7 @@ static struct ath11k_hw_params ath11k_hw .supports_monitor = false, .supports_sta_ps = false, .supports_shadow_regs = false, @@ -288,7 +347,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_regdb = false, -@@ -710,7 +715,23 @@ static struct ath11k_hw_params ath11k_hw +@@ -710,7 +716,23 @@ static struct ath11k_hw_params ath11k_hw }, }; diff --git a/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch b/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch index 0b9d559a4857ae..87314bc425d3d1 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch @@ -754,10 +754,24 @@ Signed-off-by: Ramya Gnanasekar --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h -@@ -22,6 +22,11 @@ +@@ -22,7 +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 @@ -765,8 +779,8 @@ Signed-off-by: Ramya Gnanasekar +#define ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE 1816 #else /* Num VDEVS per radio */ - #define TARGET_NUM_VDEVS(ab) (ab->hw_params.num_vdevs) -@@ -34,6 +39,8 @@ + #define TARGET_NUM_VDEVS(ab) (ab->hw_params.num_vdevs_peers[ab->qmi.target_mem_mode].num_vdevs) +@@ -47,6 +55,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 @@ -775,7 +789,7 @@ Signed-off-by: Ramya Gnanasekar #endif /* Num of peers for Single Radio mode */ -@@ -129,6 +136,8 @@ enum ath11k_bus { +@@ -142,6 +152,8 @@ enum ath11k_bus { struct hal_rx_desc; struct hal_tcl_data_cmd; @@ -784,7 +798,7 @@ Signed-off-by: Ramya Gnanasekar struct ath11k_hw_ring_mask { u8 tx[ATH11K_EXT_IRQ_GRP_NUM_MAX]; -@@ -218,6 +227,7 @@ struct ath11k_hw_params { +@@ -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; @@ -792,7 +806,7 @@ Signed-off-by: Ramya Gnanasekar bool supports_rssi_stats; bool fw_wmi_diag_event; bool current_cc_support; -@@ -285,6 +295,16 @@ struct ath11k_hw_ops { +@@ -299,6 +312,16 @@ 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); 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/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch index b0f6b03f750f9e..9bc2b50f7cbd45 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch @@ -385,7 +385,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 -@@ -270,6 +270,7 @@ struct ath11k_hw_ops { +@@ -287,6 +287,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); From 168a70e6a82d638c1b1d5ef9856cf57c34b9c40c Mon Sep 17 00:00:00 2001 From: Qosmio Date: Wed, 10 Jan 2024 21:02:52 -0500 Subject: [PATCH 199/225] ath11k_nss: 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 --- .../905-ath11k-add-support-memory-stats.patch | 946 ++++++++++++++++++ 1 file changed, 946 insertions(+) create mode 100644 package/kernel/mac80211/patches/ath11k_nss/905-ath11k-add-support-memory-stats.patch 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 new file mode 100644 index 00000000000000..f4f4389960bd74 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/905-ath11k-add-support-memory-stats.patch @@ -0,0 +1,946 @@ +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, ++ 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); + } + From c4e0ac9d11f46488296458efcb52f704b3b77fe7 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Wed, 10 Jan 2024 22:19:51 -0500 Subject: [PATCH 200/225] ath11k_nss: allow specifying pbuf 'memory_profile' In case you want to specify the memory profile to use rather than letting it autodetect. The following new uci option is introduced. pbuf. config general opt option memory_profile '' choices are 1gb, 512mb, 256mb. Delete option to let it autodetect. NOTE: You must reboot after changing these settings, for it to autoapply. ath11k_nss: fix compilation and rename some patches --- .../mac80211/files/etc/init.d/qca-nss-pbuf | 29 +++++++++++++++---- package/kernel/mac80211/files/pbuf.uci | 5 ++++ .../199-003-ath11k-add-nss-support.patch | 2 +- ...c80211-Add-support-for-dynamic-vlan.patch} | 0 ...ncapsulation-of-EAPOL-frames-if-OFFL.patch | 9 ++++++ ...=> 902-020-ath11k-add-btcoex-config.patch} | 0 ...9-ath11k-add-HE-stats-in-peer-stats.patch} | 0 .../905-ath11k-add-support-memory-stats.patch | 2 +- 8 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 package/kernel/mac80211/files/pbuf.uci rename package/kernel/mac80211/patches/ath11k_nss/{207-ath11k-Add-support-for-dynamic-vlan.patch => 207-mac80211-Add-support-for-dynamic-vlan.patch} (100%) rename package/kernel/mac80211/patches/ath11k_nss/{902-ath11k-add-btcoex-config.patch => 902-020-ath11k-add-btcoex-config.patch} (100%) rename package/kernel/mac80211/patches/ath11k_nss/{902-ath11k-add-HE-stats-in-peer-stats.patch => 902-069-ath11k-add-HE-stats-in-peer-stats.patch} (100%) diff --git a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf index 260726fb12d871..be89de061ce8b1 100755 --- a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf +++ b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf @@ -43,7 +43,23 @@ apply_nss_config() { 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 - board=$(board_name) + local memory_profile + if memory_profile=$(uci_get pbuf.opt.memory_profile); then + case "$memory_profile" in + 1g*|512m*|256m*) + board=$memory_profile + logger -t ath11k_nss "Using custom memory profile - $board" + ;; + *) + logger -s -t ath11k_nss -p user.error "Unknown profile $memory_profile. Choose 1gb, 512mb, or 256mb" + board=$(board_name) + logger -s -t ath11k_nss -p user.warn "Falling back to: $board" + ;; + esac + else + board=$(board_name) + logger -t ath11k_nss "Setting n2hcfg values for board: $board" + fi case "$board" in # 1GB+ profile @@ -60,7 +76,8 @@ apply_nss_config() { qnap,301w | \ xiaomi,ax9000 | \ yuncore,ax880 | \ - zyxel,nbg7815) + zyxel,nbg7815 | \ + 1g*) extra_pbuf_core0=9000000 n2h_high_water_core0=67392 n2h_wifi_pool_buf=40960 apply_sysctl ;; # 512MB profile @@ -69,11 +86,13 @@ apply_nss_config() { linksys,mx4200v1 | \ redmi,ax6 | \ xiaomi,ax3600 | \ - zte,mf269) # 512MB profile + zte,mf269 | \ + 512m*) extra_pbuf_core0=3100000 n2h_high_water_core0=30624 n2h_wifi_pool_buf=8192 apply_sysctl ;; # 256MB profile - netgear,wax218) + netgear,wax218 | \ + 256m*) extra_pbuf_core0=3100000 n2h_high_water_core0=30258 n2h_wifi_pool_buf=4096 apply_sysctl ;; esac @@ -88,7 +107,7 @@ start() { enable_nss_offload=$(cat /sys/module/ath11k/parameters/nss_offload) if [ "$enable_nss_offload" = "0" ]; then - logger -t ath11k_nss "Module parameter 'nss_offload=0'. Skipping applying wifi nss configs" + logger -t ath11k_nss -s user.warn "Module parameter 'nss_offload=0'. Skipping applying wifi nss configs" exit 1 fi diff --git a/package/kernel/mac80211/files/pbuf.uci b/package/kernel/mac80211/files/pbuf.uci new file mode 100644 index 00000000000000..ac4fadbc4f5e63 --- /dev/null +++ b/package/kernel/mac80211/files/pbuf.uci @@ -0,0 +1,5 @@ +config general opt + # to bypass board autodetection, uncomment ONE of the options below + # option memory_profile '1gb' + # option memory_profile '512mb' + # option memory_profile '256mb' diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch b/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch index cfe11083939837..ffae0a9448ef8b 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch @@ -1069,7 +1069,7 @@ Signed-off-by: Sriram R /* create list containing all the subframes */ ieee80211_amsdu_to_8023s(skb, &subframe_list, NULL, - vif->type, 0, NULL, NULL); -+ vif->type, 0, NULL, NULL, false); ++ vif->type, 0, NULL, NULL, 0); /* This shouldn't happen, indicating error during defragmentation */ if (skb_queue_empty(&subframe_list)) diff --git a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch b/package/kernel/mac80211/patches/ath11k_nss/207-mac80211-Add-support-for-dynamic-vlan.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch rename to package/kernel/mac80211/patches/ath11k_nss/207-mac80211-Add-support-for-dynamic-vlan.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch b/package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch index b64643140a14b1..70e2603c8cc02b 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch @@ -66,6 +66,15 @@ Signed-off-by: Aaradhana Sahu rcu_read_unlock(); return; } +@@ -4374,7 +4378,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); + ieee80211_xmit(sdata, sta, skb); @@ -4657,19 +4663,29 @@ static bool ieee80211_tx_8023(struct iee static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, diff --git a/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-btcoex-config.patch b/package/kernel/mac80211/patches/ath11k_nss/902-020-ath11k-add-btcoex-config.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-btcoex-config.patch rename to package/kernel/mac80211/patches/ath11k_nss/902-020-ath11k-add-btcoex-config.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-HE-stats-in-peer-stats.patch b/package/kernel/mac80211/patches/ath11k_nss/902-069-ath11k-add-HE-stats-in-peer-stats.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/902-ath11k-add-HE-stats-in-peer-stats.patch rename to package/kernel/mac80211/patches/ath11k_nss/902-069-ath11k-add-HE-stats-in-peer-stats.patch 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 index f4f4389960bd74..734b6fb8c4b160 100644 --- 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 @@ -251,7 +251,7 @@ Signed-off-by: Maharaja Kennadyrajan + +static ssize_t +ath11k_debug_write_enable_memory_stats(struct file *file, -+ char __user *ubuf, ++ const char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct ath11k_base *ab = file->private_data; From 9e279d46a8740e399d2111107b9558bba2582bf5 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 13 Jan 2024 08:19:32 -0500 Subject: [PATCH 201/225] ath11k_nss: ath11k support dynamic vlan also support offload for the following: mac80211: * vlan * mesh (partial) ath11k: * vlan --- ...-ath11k-Add-support-for-dynamic-vlan.patch | 381 ++++ ...00-mac80211-nss-mesh-offload-support.patch | 1241 +++++++++++++ ...TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch | 80 + ...TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch | 45 + .../336-mac80211-Mesh-Fast-rx-support.patch | 208 +++ ...rning-with-monitor-interface-restart.patch | 33 + ...interface-combination-advertisement-.patch | 1594 +++++++++++++++++ .../829-mac80211-fix-mesh-ping-issue.patch | 113 ++ .../902-022-ath11k-add-ap-ps-support.patch | 324 ++++ ...x-memory-corruption-during-mesh-beac.patch | 68 + ...04-300-ath11k-nss_get_arvif_from_dev.patch | 113 ++ ...07-068-ath11k-add-rx-histogram-stats.patch | 608 +++++++ ...ul-ofdma-ru-allocation-in-peer-stats.patch | 452 +++++ ...11k-remove-error-on-soc-debugfs-fail.patch | 146 ++ .../908-301-ath11k-nss-mcbc-exception.patch | 253 +++ ...30-ath11k-sync-wds_ast_entry-updates.patch | 522 ++++++ ...ct-ast-index-assignment-for-wds-peer.patch | 96 + 17 files changed, 6277 insertions(+) create mode 100644 package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/335-0003-ath11k-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/335-0003-mac80211-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/336-mac80211-Mesh-Fast-rx-support.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/353-mac80211-fix-dynamic-vlan-warning-with-monitor-interface-restart.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/675-01-cfg80211-Extend-interface-combination-advertisement-.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/829-mac80211-fix-mesh-ping-issue.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/902-022-ath11k-add-ap-ps-support.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/902-wifi-mac80211-Fix-memory-corruption-during-mesh-beac.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/904-300-ath11k-nss_get_arvif_from_dev.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/907-068-ath11k-add-rx-histogram-stats.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/907-ath11k-remove-error-on-soc-debugfs-fail.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/908-330-ath11k-sync-wds_ast_entry-updates.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/908-362-ath11k-fix-incorrect-ast-index-assignment-for-wds-peer.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch new file mode 100644 index 00000000000000..b17b9fb419745d --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch @@ -0,0 +1,381 @@ +From 71add81f4a3f1ea505f498d789e7a1721c4d7a6e Mon Sep 17 00:00:00 2001 +From: Seevalamuthu Mariappan +Date: Mon, 4 Sep 2023 12:48:19 +0530 +Subject: [PATCH] ath11k: Add support for dynamic vlan + +This patch adds support for dynamic vlan. VLAN group traffics +are encrypted in software. vlan unicast packets shall be taking +8023 xmit path if encap offload is enabled and mcast/bcast will +be using 80211 xmit path. + +Metadata info in dp_tx added to notify firmware that the +multicast/broadcast packets are encrypted in sw. + +Signed-off-by: Seevalamuthu Mariappan +--- + drivers/net/wireless/ath/ath11k/core.h | 1 + + drivers/net/wireless/ath/ath11k/dp_tx.c | 80 +++++++++- + drivers/net/wireless/ath/ath11k/dp_tx.h | 198 ++++++++++++++++++++++++ + drivers/net/wireless/ath/ath11k/mac.c | 3 + + 4 files changed, 279 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -116,6 +116,7 @@ struct ath11k_skb_cb { + u32 cipher; + struct ath11k *ar; + struct ieee80211_vif *vif; ++ u32 pkt_offset; + } __packed; + + struct ath11k_skb_rxcb { +--- a/drivers/net/wireless/ath/ath11k/dp_tx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_tx.c +@@ -79,6 +79,43 @@ enum hal_encrypt_type ath11k_dp_tx_get_e + } + } + ++#define HTT_META_DATA_ALIGNMENT 0x8 ++ ++static int ath11k_dp_metadata_align_skb(struct sk_buff *skb, u8 align_len) ++{ ++ if (unlikely(skb_cow_head(skb, align_len))) ++ return -ENOMEM; ++ ++ skb_push(skb, align_len); ++ memset(skb->data, 0, align_len); ++ return 0; ++} ++ ++static int ath11k_dp_prepare_htt_metadata(struct sk_buff *skb, ++ u8 *htt_metadata_size) ++{ ++ u8 htt_desc_size; ++ /* Size rounded of multiple of 8 bytes */ ++ u8 htt_desc_size_aligned; ++ int ret; ++ struct htt_tx_msdu_desc_ext *desc_ext; ++ ++ htt_desc_size = sizeof(struct htt_tx_msdu_desc_ext); ++ htt_desc_size_aligned = ALIGN(htt_desc_size, HTT_META_DATA_ALIGNMENT); ++ ++ ret = ath11k_dp_metadata_align_skb(skb, htt_desc_size_aligned); ++ if (unlikely(ret)) ++ return ret; ++ ++ desc_ext = (struct htt_tx_msdu_desc_ext *)skb->data; ++ desc_ext->valid_encrypt_type = 1; ++ desc_ext->encrypt_type = 0; ++ desc_ext->host_tx_desc_pool = 1; ++ *htt_metadata_size = htt_desc_size_aligned; ++ ++ return 0; ++} ++ + int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif, + struct ath11k_sta *arsta, struct sk_buff *skb) + { +@@ -96,7 +133,8 @@ int ath11k_dp_tx(struct ath11k *ar, stru + int ret; + u32 ring_selector = 0; + u8 ring_map = 0; +- bool tcl_ring_retry; ++ bool tcl_ring_retry, is_diff_encap = false; ++ u8 align_pad, htt_meta_size = 0; + + if (unlikely(test_bit(ATH11K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags))) + return -ESHUTDOWN; +@@ -189,7 +227,10 @@ tcl_ring_sel: + + switch (ti.encap_type) { + case HAL_TCL_ENCAP_TYPE_NATIVE_WIFI: +- ath11k_dp_tx_encap_nwifi(skb); ++ if (arvif->vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) ++ is_diff_encap = true; ++ else ++ ath11k_dp_tx_encap_nwifi(skb); + break; + case HAL_TCL_ENCAP_TYPE_RAW: + if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) { +@@ -208,6 +249,33 @@ tcl_ring_sel: + goto fail_remove_idr; + } + ++ /* Add metadata for sw encrypted vlan group traffic */ ++ if ((!test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) && ++ !(info->control.flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && ++ !info->control.hw_key && ieee80211_has_protected(hdr->frame_control)) || ++ (skb->protocol == cpu_to_be16(ETH_P_PAE) && is_diff_encap)) { ++ /* HW requirement is that metadata should always point to a ++ * 8-byte aligned address. So we add alignment pad to start of ++ * buffer. HTT Metadata should be ensured to be multiple of 8-bytes ++ * to get 8-byte aligned start address along with align_pad added ++ */ ++ align_pad = ((unsigned long)skb->data) & (HTT_META_DATA_ALIGNMENT - 1); ++ ret = ath11k_dp_metadata_align_skb(skb, align_pad); ++ if (unlikely(ret)) ++ goto fail_remove_idr; ++ ++ ti.pkt_offset += align_pad; ++ ret = ath11k_dp_prepare_htt_metadata(skb, &htt_meta_size); ++ if (unlikely(ret)) ++ goto fail_remove_idr; ++ ++ ti.pkt_offset += htt_meta_size; ++ ti.meta_data_flags |= HTT_TCL_META_DATA_VALID_HTT; ++ ti.flags0 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_TO_FW, 1); ++ ti.encap_type = HAL_TCL_ENCAP_TYPE_RAW; ++ ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN; ++ } ++ + 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); +@@ -216,7 +284,8 @@ tcl_ring_sel: + goto fail_remove_idr; + } + +- ti.data_len = skb->len; ++ ti.data_len = skb->len - ti.pkt_offset; ++ skb_cb->pkt_offset = ti.pkt_offset; + skb_cb->paddr = ti.paddr; + skb_cb->vif = arvif->vif; + skb_cb->ar = ar; +@@ -272,6 +341,8 @@ fail_unmap_dma: + dma_unmap_single(ab->dev, ti.paddr, ti.data_len, DMA_TO_DEVICE); + + fail_remove_idr: ++ if (ti.pkt_offset) ++ skb_pull(skb, ti.pkt_offset); + spin_lock_bh(&tx_ring->tx_idr_lock); + idr_remove(&tx_ring->txbuf_idr, + FIELD_GET(DP_TX_DESC_ID_MSDU_ID, ti.desc_id)); +@@ -358,6 +429,9 @@ ath11k_dp_tx_htt_tx_complete_buf(struct + flags = skb_cb->flags; + vif = skb_cb->vif; + ++ if (skb_cb->pkt_offset) ++ skb_pull(msdu, skb_cb->pkt_offset); /* removing the alignment and htt meta data */ ++ + memset(&info->status, 0, sizeof(info->status)); + + if (ts->acked) { +--- a/drivers/net/wireless/ath/ath11k/dp_tx.h ++++ b/drivers/net/wireless/ath/ath11k/dp_tx.h +@@ -16,6 +16,204 @@ struct ath11k_dp_htt_wbm_tx_status { + u16 peer_id; + }; + ++/* htt_tx_msdu_desc_ext ++ * ++ * valid_pwr ++ * if set, tx pwr spec is valid ++ * ++ * valid_mcs_mask ++ * if set, tx MCS mask is valid ++ * ++ * valid_nss_mask ++ * if set, tx Nss mask is valid ++ * ++ * valid_preamble_type ++ * if set, tx preamble spec is valid ++ * ++ * valid_retries ++ * if set, tx retries spec is valid ++ * ++ * valid_bw_info ++ * if set, tx dyn_bw and bw_mask are valid ++ * ++ * valid_guard_interval ++ * if set, tx guard intv spec is valid ++ * ++ * valid_chainmask ++ * if set, tx chainmask is valid ++ * ++ * valid_encrypt_type ++ * if set, encrypt type is valid ++ * ++ * valid_key_flags ++ * if set, key flags is valid ++ * ++ * valid_expire_tsf ++ * if set, tx expire TSF spec is valid ++ * ++ * valid_chanfreq ++ * if set, chanfreq is valid ++ * ++ * is_dsrc ++ * if set, MSDU is a DSRC frame ++ * ++ * guard_interval ++ * 0.4us, 0.8us, 1.6us, 3.2us ++ * ++ * encrypt_type ++ * 0 = NO_ENCRYPT, ++ * 1 = ENCRYPT, ++ * 2 ~ 3 - Reserved ++ * ++ * retry_limit ++ * Specify the maximum number of transmissions, including the ++ * initial transmission, to attempt before giving up if no ack ++ * is received. ++ * If the tx rate is specified, then all retries shall use the ++ * same rate as the initial transmission. ++ * If no tx rate is specified, the target can choose whether to ++ * retain the original rate during the retransmissions, or to ++ * fall back to a more robust rate. ++ * ++ * use_dcm_11ax ++ * If set, Use Dual subcarrier modulation. ++ * Valid only for 11ax preamble types HE_SU ++ * and HE_EXT_SU ++ * ++ * ltf_subtype_11ax ++ * Takes enum values of htt_11ax_ltf_subtype_t ++ * Valid only for 11ax preamble types HE_SU ++ * and HE_EXT_SU ++ * ++ * dyn_bw ++ * 0 = static bw, 1 = dynamic bw ++ * ++ * bw_mask ++ * Valid only if dyn_bw == 0 (static bw). ++ * ++ * host_tx_desc_pool ++ * If set, Firmware allocates tx_descriptors ++ * in WAL_BUFFERID_TX_HOST_DATA_EXP,instead ++ * of WAL_BUFFERID_TX_TCL_DATA_EXP. ++ * Use cases: ++ * Any time firmware uses TQM-BYPASS for Data ++ * TID, firmware expect host to set this bit. ++ * ++ * power ++ * unit of the power field is 0.5 dbm ++ * signed value ranging from -64dbm to 63.5 dbm ++ * ++ * mcs_mask ++ * mcs bit mask of 0 ~ 11 ++ * Setting more than one MCS isn't currently ++ * supported by the target (but is supported ++ * in the interface in case in the future ++ * the target supports specifications of ++ * a limited set of MCS values. ++ * ++ * nss_mask ++ * Nss bit mask 0 ~ 7 ++ * Setting more than one Nss isn't currently ++ * supported by the target (but is supported ++ * in the interface in case in the future ++ * the target supports specifications of ++ * a limited set of Nss values. ++ * ++ * pream_type ++ * Preamble types ++ * ++ * update_peer_cache ++ * When set these custom values will be ++ * used for all packets, until the next ++ * update via this ext header. ++ * This is to make sure not all packets ++ * need to include this header. ++ * ++ * chain_mask ++ * specify which chains to transmit from ++ * ++ * key_flags ++ * Key Index and related flags - used in mesh mode ++ * ++ * chanfreq ++ * Channel frequency: This identifies the desired channel ++ * frequency (in MHz) for tx frames. This is used by FW to help ++ * determine when it is safe to transmit or drop frames for ++ * off-channel operation. ++ * The default value of zero indicates to FW that the corresponding ++ * VDEV's home channel (if there is one) is the desired channel ++ * frequency. ++ * ++ * expire_tsf_lo ++ * tx expiry time (TSF) LSBs ++ * ++ * expire_tsf_hi ++ * tx expiry time (TSF) MSBs ++ * ++ * learning_frame ++ * When this flag is set, this frame will be dropped by FW ++ * rather than being enqueued to the Transmit Queue Manager (TQM) HW. ++ * ++ * send_as_standalone ++ * This will indicate if the msdu needs to be sent as a singleton PPDU, ++ * i.e. with no A-MSDU or A-MPDU aggregation. ++ * The scope is extended to other use-cases. ++ * ++ * is_host_opaque_valid ++ * set this bit to 1 if the host_opaque_cookie is populated ++ * with valid information. ++ * ++ * host_opaque_cookie ++ * Host opaque cookie for special frames ++ */ ++ ++struct htt_tx_msdu_desc_ext { ++ u32 ++ valid_pwr : 1, ++ valid_mcs_mask : 1, ++ valid_nss_mask : 1, ++ valid_preamble_type : 1, ++ valid_retries : 1, ++ valid_bw_info : 1, ++ valid_guard_interval : 1, ++ valid_chainmask : 1, ++ valid_encrypt_type : 1, ++ valid_key_flags : 1, ++ valid_expire_tsf : 1, ++ valid_chanfreq : 1, ++ is_dsrc : 1, ++ guard_interval : 2, ++ encrypt_type : 2, ++ retry_limit : 4, ++ use_dcm_11ax : 1, ++ ltf_subtype_11ax : 2, ++ dyn_bw : 1, ++ bw_mask : 6, ++ host_tx_desc_pool : 1; ++ u32 ++ power : 8, ++ mcs_mask : 12, ++ nss_mask : 8, ++ pream_type : 3, ++ update_peer_cache : 1; ++ u32 ++ chain_mask : 8, ++ key_flags : 8, ++ chanfreq : 16; ++ ++ u32 expire_tsf_lo; ++ u32 expire_tsf_hi; ++ ++ u32 ++ learning_frame : 1, ++ send_as_standalone : 1, ++ is_host_opaque_valid : 1, ++ rsvd0 : 29; ++ u32 ++ host_opaque_cookie : 16, ++ rsvd1 : 16; ++} __packed; ++ + void ath11k_dp_tx_update_txcompl(struct ath11k *ar, struct hal_tx_status *ts); + int ath11k_dp_tx_htt_h2t_ver_req_msg(struct ath11k_base *ab); + 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 + */ + ar->hw->wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MONITOR); + ++ ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); ++ ar->hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_AP_VLAN); ++ + /* Apply the regd received during initialization */ + ret = ath11k_regd_update(ar); + if (ret) { diff --git a/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch b/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch new file mode 100644 index 00000000000000..7233913ee6f0f7 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch @@ -0,0 +1,1241 @@ +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 +Signed-off-by: Gautham Kumar Senthilkumaran +--- + include/net/mac80211.h | 106 ++ + net/mac80211/cfg.c | 19 +- + net/mac80211/debug.h | 10 + + net/mac80211/debugfs.c | 1 + + net/mac80211/driver-ops.c | 20 + + net/mac80211/driver-ops.h | 7 + + net/mac80211/mesh.h | 5 + + net/mac80211/mesh_hwmp.c | 273 +++++ + net/mac80211/mesh_pathtbl.c | 167 ++- + net/mac80211/rx.c | 8 +- + 10 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/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -145,6 +145,9 @@ + */ + struct device; + ++struct ieee80211_mesh_path_offld; ++enum ieee80211_mesh_path_offld_cmd; ++ + /** + * enum ieee80211_max_queues - maximum number of queues + * +@@ -387,11 +390,17 @@ enum ieee80211_bss_change { + * to indicate which NSS BSS parameter changed. + * + * @BSS_CHANGED_NSS_AP_ISOLATE: AP Isolate feature in NSS mode ++ * @BSS_CHANGED_NSS_MESH_TTL: TTL update in NSS mesh mode ++ * @BSS_CHANGED_NSS_MESH_REFRESH_TIME: Mesh refresh time in NSS mesh mode ++ * @BSS_CHANGED_NSS_MESH_FWD_ENABLED: NSS offload mesh forward enabled + * + */ + + enum ieee80211_nss_bss_change { + BSS_CHANGED_NSS_AP_ISOLATE = BIT(0), ++ BSS_CHANGED_NSS_MESH_TTL = BIT(1), ++ BSS_CHANGED_NSS_MESH_REFRESH_TIME = BIT(2), ++ BSS_CHANGED_NSS_MESH_FWD_ENABLED = BIT(3), + }; + + /* +@@ -794,6 +803,11 @@ struct ieee80211_bss_conf { + bool eht_mu_beamformer; + bool nss_ap_isolate; + enum nl80211_beacon_tx_mode beacon_tx_mode; ++ ++ /* Mesh configuration for nss offload */ ++ u8 nss_offld_ttl; ++ bool nss_offld_mesh_forward_enabled; ++ u32 nss_offld_mpath_refresh_time; + }; + + /** +@@ -1273,6 +1287,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. ++ * @mpdu_succ: Number of mpdus successfully transmitted ++ * @mpdu_fail: Number of mpdus failed + */ + struct ieee80211_tx_status { + struct ieee80211_sta *sta; +@@ -1283,6 +1299,8 @@ struct ieee80211_tx_status { + u8 n_rates; + + struct list_head *free_list; ++ u32 mpdu_succ; ++ u32 mpdu_fail; + }; + + /** +@@ -1775,6 +1793,7 @@ struct ieee80211_channel_switch { + * this is not pure P2P vif. + * @IEEE80211_VIF_DISABLE_SMPS_OVERRIDE: disable user configuration of + * SMPS mode via debugfs. ++ * @IEEE80211_HW_NSS_OFFLOAD_DEBUG_MODE: It enables the debug mode of nss offload. + */ + enum ieee80211_vif_flags { + IEEE80211_VIF_BEACON_FILTER = BIT(0), +@@ -1782,6 +1801,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), ++ IEEE80211_VIF_NSS_OFFLOAD_DEBUG_MODE = BIT(5), + }; + + +@@ -2765,6 +2785,7 @@ enum ieee80211_hw_flags { + IEEE80211_HW_DETECTS_COLOR_COLLISION, + IEEE80211_HW_MLO_MCAST_MULTI_LINK_TX, + IEEE80211_HW_SUPPORTS_NSS_OFFLOAD, ++ IEEE80211_HW_SUPPORTS_MESH_NSS_OFFLOAD, + + /* keep last, obviously */ + NUM_IEEE80211_HW_FLAGS +@@ -4265,6 +4286,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 ++ * @config_mesh_offload_path: Configure mesh path table when driver supports mesh offload. ++ * This calback must be atomic. + * @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 { + void (*sta_set_decap_offload)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, bool enabled); ++#ifdef CPTCFG_MAC80211_MESH ++ void (*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); ++#endif + 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 + void ieee80211_set_active_links_async(struct ieee80211_vif *vif, + u16 active_links); + ++/* Defines for Mesh NSS offload */ ++ ++enum ieee80211_mesh_path_offld_cmd { ++ IEEE80211_MESH_PATH_OFFLD_CMD_ADD_MPATH, ++ IEEE80211_MESH_PATH_OFFLD_CMD_UPDATE_MPATH, ++ IEEE80211_MESH_PATH_OFFLD_CMD_DELETE_MPATH, ++ IEEE80211_MESH_PATH_OFFLD_CMD_ADD_MPP, ++ IEEE80211_MESH_PATH_OFFLD_CMD_UPDATE_MPP, ++ IEEE80211_MESH_PATH_OFFLD_CMD_DELETE_MPP, ++}; ++ ++enum ieee80211_mesh_path_offld_action { ++ IEEE80211_MESH_PATH_OFFLD_ACTION_MPATH_REFRESH = BIT(0), ++ IEEE80211_MESH_PATH_OFFLD_ACTION_MPATH_DEL = BIT(1), ++ IEEE80211_MESH_PATH_OFFLD_ACTION_MPATH_EXP = BIT(2), ++ IEEE80211_MESH_PATH_OFFLD_ACTION_MPP_LEARN = BIT(3), ++ IEEE80211_MESH_PATH_OFFLD_ACTION_MPP_ADD = BIT(4), ++ IEEE80211_MESH_PATH_OFFLD_ACTION_MPP_UPDATE = BIT(5), ++ IEEE80211_MESH_PATH_OFFLD_ACTION_PATH_NOT_FOUND = BIT(6), ++}; ++ ++/* Duplicate defines to make it available to driver */ ++enum ieee80211_mesh_path_flags { ++ IEEE80211_MESH_PATH_ACTIVE = BIT(0), ++ IEEE80211_MESH_PATH_RESOLVING = BIT(1), ++ IEEE80211_MESH_PATH_SN_VALID = BIT(2), ++ IEEE80211_MESH_PATH_FIXED = BIT(3), ++ IEEE80211_MESH_PATH_RESOLVED = BIT(4), ++ IEEE80211_MESH_PATH_REQ_QUEUED = BIT(5), ++ IEEE80211_MESH_PATH_DELETED = BIT(6), ++}; ++ ++struct ieee80211_mesh_path_offld { ++ u8 mesh_da[ETH_ALEN]; ++ u8 da[ETH_ALEN]; ++ u8 next_hop[ETH_ALEN]; ++ u8 old_next_hop[ETH_ALEN]; ++ u8 ta[ETH_ALEN]; ++ u32 metric; ++ unsigned long exp_time; ++ u8 hop_count; ++ u16 flags; /* See &enum ieee80211_mesh_path_flags */ ++ u8 mesh_gate; ++ u8 block_mesh_fwd; ++ u8 metadata_type; ++}; ++ ++#ifdef CPTCFG_MAC80211_MESH ++/** ieee80211_mesh_path_offld_change_notify - Notify mesh path change event. ++ * @vif: Mesh interface on which the event is being reported. ++ * @path: Mesh path which got changed. Please note not all the entries in the ++ * path will have valid information. Based on the action code, it will be ++ * processed. ++ * @action: Type of the event. ++ */ ++int ieee80211_mesh_path_offld_change_notify(struct ieee80211_vif *vif, ++ struct ieee80211_mesh_path_offld *path, ++ enum ieee80211_mesh_path_offld_action action); ++ ++/** ieee80211s_update_metric_ppdu - Upate tx PPDU stats for 11s metric computation ++ * ++ * @hw: the hardware the frame was transmitted by ++ * @st: tx status information ++*/ ++void ieee80211s_update_metric_ppdu(struct ieee80211_hw *hw, ++ struct ieee80211_tx_status *st); ++ ++/** mesh_nss_offld_proxy_path_exp_update - update the expiry time from nss ++ * @vif Mesh interface on which the event is being reported. ++ * @mac: dest_mac_addr of the mesh proxy path ++ * @time_diff: This is the time diff since the mesh peer is active ++ */ ++void mesh_nss_offld_proxy_path_exp_update(struct ieee80211_vif *vif, u8* da, ++ u8* mesh_da, u32 time_diff); ++#else ++static inline int ++ieee80211_mesh_path_offld_change_notify(struct ieee80211_vif *vif, ++ struct ieee80211_mesh_path_offld *path, ++ enum ieee80211_mesh_path_offld_action action) ++{ ++ return 0; ++} ++ ++static inline void ++ieee80211s_update_metric_ppdu(struct ieee80211_hw *hw, ++ struct ieee80211_tx_status *st) ++{ ++} ++ ++static inline void ++mesh_nss_offld_proxy_path_exp_update(struct ieee80211_vif *vif, u8* da, ++ u8* mesh_da, u32 time_diff) ++{ ++} ++#endif ++ + #endif /* MAC80211_H */ +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -2514,6 +2514,7 @@ static int ieee80211_update_mesh_config( + struct mesh_config *conf; + struct ieee80211_sub_if_data *sdata; + struct ieee80211_if_mesh *ifmsh; ++ u32 nss_changed = 0; + + sdata = IEEE80211_DEV_TO_SUB_IF(dev); + ifmsh = &sdata->u.mesh; +@@ -2530,8 +2531,11 @@ static int ieee80211_update_mesh_config( + conf->dot11MeshMaxPeerLinks = nconf->dot11MeshMaxPeerLinks; + if (_chg_mesh_attr(NL80211_MESHCONF_MAX_RETRIES, mask)) + conf->dot11MeshMaxRetries = nconf->dot11MeshMaxRetries; +- if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask)) ++ if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask)) { + conf->dot11MeshTTL = nconf->dot11MeshTTL; ++ sdata->vif.bss_conf.nss_offld_ttl = nconf->dot11MeshTTL; ++ nss_changed |= BSS_CHANGED_NSS_MESH_TTL; ++ } + 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( + if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, mask)) + conf->dot11MeshHWMPmaxPREQretries = + nconf->dot11MeshHWMPmaxPREQretries; +- if (_chg_mesh_attr(NL80211_MESHCONF_PATH_REFRESH_TIME, mask)) ++ if (_chg_mesh_attr(NL80211_MESHCONF_PATH_REFRESH_TIME, mask)) { + conf->path_refresh_time = nconf->path_refresh_time; ++ sdata->vif.bss_conf.nss_offld_mpath_refresh_time = ++ nconf->path_refresh_time; ++ nss_changed |= BSS_CHANGED_NSS_MESH_REFRESH_TIME; ++ } + 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( + if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask)) + conf->dot11MeshHWMPRannInterval = + nconf->dot11MeshHWMPRannInterval; +- if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask)) ++ if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask)) { + conf->dot11MeshForwarding = nconf->dot11MeshForwarding; ++ sdata->vif.bss_conf.nss_offld_mesh_forward_enabled = ++ nconf->dot11MeshForwarding; ++ nss_changed |= BSS_CHANGED_NSS_MESH_FWD_ENABLED; ++ } + 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( + conf->dot11MeshConnectedToAuthServer = + nconf->dot11MeshConnectedToAuthServer; + ieee80211_mbss_info_change_notify(sdata, BSS_CHANGED_BEACON); ++ ieee80211_nss_bss_info_change_notify(sdata, nss_changed); + return 0; + } + +--- a/net/mac80211/debug.h ++++ b/net/mac80211/debug.h +@@ -67,6 +67,12 @@ + #define MAC80211_MESH_PS_DEBUG 0 + #endif + ++#ifdef CPTCFG_MAC80211_MESH_OFFLOAD_DEBUG ++#define MAC80211_MESH_OFFLOAD_DEBUG 1 ++#else ++#define MAC80211_MESH_OFFLOAD_DEBUG 0 ++#endif ++ + #ifdef CPTCFG_MAC80211_TDLS_DEBUG + #define MAC80211_TDLS_DEBUG 1 + #else +@@ -215,6 +221,10 @@ do { \ + _sdata_dbg(MAC80211_MESH_PS_DEBUG, \ + sdata, fmt, ##__VA_ARGS__) + ++#define moffld_dbg(sdata, fmt, ...) \ ++ _sdata_dbg(MAC80211_MESH_OFFLOAD_DEBUG, \ ++ sdata, fmt, ##__VA_ARGS__) ++ + #define tdls_dbg(sdata, fmt, ...) \ + _sdata_dbg(MAC80211_TDLS_DEBUG, \ + sdata, fmt, ##__VA_ARGS__) +--- a/net/mac80211/debugfs.c ++++ b/net/mac80211/debugfs.c +@@ -497,6 +497,7 @@ static const char *hw_flag_names[] = { + FLAG(DETECTS_COLOR_COLLISION), + FLAG(MLO_MCAST_MULTI_LINK_TX), + FLAG(SUPPORTS_NSS_OFFLOAD), ++ FLAG(SUPPORTS_MESH_NSS_OFFLOAD), + #undef FLAG + }; + +--- a/net/mac80211/driver-ops.c ++++ b/net/mac80211/driver-ops.c +@@ -569,3 +569,23 @@ int drv_change_sta_links(struct ieee8021 + + return 0; + } ++ ++#ifdef CPTCFG_MAC80211_MESH ++void drv_config_mesh_offload_path(struct ieee80211_local *local, ++ struct ieee80211_sub_if_data *sdata, ++ enum ieee80211_mesh_path_offld_cmd cmd, ++ struct ieee80211_mesh_path_offld *path) ++{ ++ if (!check_sdata_in_driver(sdata)) ++ return; ++ ++ if (!ieee80211_hw_check(&local->hw, SUPPORTS_MESH_NSS_OFFLOAD)) ++ return; ++ ++ if (local->ops->config_mesh_offload_path) ++ local->ops->config_mesh_offload_path(&local->hw, ++ &sdata->vif, cmd, path); ++ ++ /* TODO: trace event */ ++} ++#endif +--- a/net/mac80211/driver-ops.h ++++ b/net/mac80211/driver-ops.h +@@ -1567,4 +1567,10 @@ int drv_change_sta_links(struct ieee8021 + struct ieee80211_sta *sta, + u16 old_links, u16 new_links); + ++#ifdef CPTCFG_MAC80211_MESH ++void drv_config_mesh_offload_path(struct ieee80211_local *local, ++ struct ieee80211_sub_if_data *sdata, ++ enum ieee80211_mesh_path_offld_cmd cmd, ++ struct ieee80211_mesh_path_offld *path); ++#endif /* CPTCFG_MAC80211_MESH */ + #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 + struct ieee80211_mgmt *mgmt, size_t len); + struct mesh_path * + mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst); ++struct mesh_path *__mesh_path_add(struct ieee80211_sub_if_data *sdata, ++ const u8 *dst); ++int __mpp_path_add(struct ieee80211_sub_if_data *sdata, ++ const u8 *dst, const u8 *mpp); + + 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 + void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata); + + bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt); ++void mesh_nss_offld_path_update(struct mesh_path *mpath, bool is_mpath, u8 *old_next_hop_addr); + struct ieee80211_mesh_fast_tx * + mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, + struct ieee80211_mesh_fast_tx_key *key); +--- a/net/mac80211/mesh_hwmp.c ++++ b/net/mac80211/mesh_hwmp.c +@@ -365,6 +365,13 @@ u32 airtime_link_metric_get(struct ieee8 + return (u32)result; + } + ++static inline struct sta_info * ++next_hop_deref_protected(struct mesh_path *mpath) ++{ ++ return rcu_dereference_protected(mpath->next_hop, ++ lockdep_is_held(&mpath->state_lock)); ++} ++ + /** + * hwmp_route_info_get - Update routing info to originator and transmitter + * +@@ -388,9 +395,10 @@ static u32 hwmp_route_info_get(struct ie + { + struct ieee80211_local *local = sdata->local; + struct mesh_path *mpath; +- struct sta_info *sta; ++ struct sta_info *sta, *next_hop; + bool fresh_info; + const u8 *orig_addr, *ta; ++ u8 old_next_hop_addr[ETH_ALEN] = {0}; + u32 orig_sn, orig_metric; + unsigned long orig_lifetime, exp_time; + u32 last_hop_metric, new_metric; +@@ -492,7 +500,10 @@ static u32 hwmp_route_info_get(struct ie + } + + if (fresh_info) { +- if (rcu_access_pointer(mpath->next_hop) != sta) { ++ next_hop = rcu_dereference(mpath->next_hop); ++ if (next_hop) ++ ether_addr_copy(old_next_hop_addr, next_hop->sta.addr); ++ if (next_hop != sta) { + mpath->path_change_count++; + flush_mpath = true; + } +@@ -514,6 +525,8 @@ static u32 hwmp_route_info_get(struct ie + /* draft says preq_id should be saved to, but there does + * not seem to be any use for it, skipping by now + */ ++ ++ mesh_nss_offld_path_update(mpath, true, old_next_hop_addr); + } else + spin_unlock_bh(&mpath->state_lock); + } +@@ -544,7 +557,14 @@ static u32 hwmp_route_info_get(struct ie + } + + if (fresh_info) { +- if (rcu_access_pointer(mpath->next_hop) != sta) { ++ /* Reset the old_next_hop_addr since this may have filled ++ * if orig_addr and ta are different ++ */ ++ memset(old_next_hop_addr, 0, ETH_ALEN); ++ next_hop = rcu_dereference(mpath->next_hop); ++ if (next_hop) ++ ether_addr_copy(old_next_hop_addr, next_hop->sta.addr); ++ if (next_hop != sta) { + mpath->path_change_count++; + flush_mpath = true; + } +@@ -561,6 +581,8 @@ static u32 hwmp_route_info_get(struct ie + /* init it at a low value - 0 start is tricky */ + ewma_mesh_fail_avg_add(&sta->mesh->fail_avg, 1); + mesh_path_tx_pending(mpath); ++ ++ mesh_nss_offld_path_update(mpath, true, old_next_hop_addr); + } else + spin_unlock_bh(&mpath->state_lock); + } +@@ -697,15 +719,6 @@ static void hwmp_preq_frame_process(stru + } + } + +- +-static inline struct sta_info * +-next_hop_deref_protected(struct mesh_path *mpath) +-{ +- return rcu_dereference_protected(mpath->next_hop, +- lockdep_is_held(&mpath->state_lock)); +-} +- +- + static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata, + struct ieee80211_mgmt *mgmt, + const u8 *prep_elem, u32 metric) +@@ -1349,3 +1362,274 @@ void mesh_path_tx_root_frame(struct ieee + return; + } + } ++ ++static int mesh_path_offld_mpath_refresh(struct ieee80211_sub_if_data *sdata, ++ u8 *mda) ++{ ++ struct mesh_path *mpath; ++ ++ rcu_read_lock(); ++ ++ mpath = mesh_path_lookup(sdata, mda); ++ if (!mpath || !(mpath->flags & MESH_PATH_ACTIVE)) { ++ moffld_dbg(sdata, ++ "mpath lookup failed during path refresh for %pM, is_mpath %d\n", ++ mda, mpath != NULL); ++ rcu_read_unlock(); ++ return -ENOENT; ++ } ++ ++ if (!(mpath->flags & MESH_PATH_RESOLVING) && !(mpath->flags & MESH_PATH_FIXED)) ++ mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); ++ ++ rcu_read_unlock(); ++ ++ return 0; ++} ++ ++static int mesh_path_offld_mpath_del(struct ieee80211_sub_if_data *sdata, u8 *da) ++{ ++ struct mesh_path *mpath, *mppath; ++ ++ rcu_read_lock(); ++ ++ mpath = mesh_path_lookup(sdata, da); ++ if (!mpath) { ++ moffld_dbg(sdata, "mpath lookup failed for %pM during duplicate mpath removal\n", ++ da); ++ rcu_read_unlock(); ++ return -ENOENT; ++ } ++ ++ mppath = mpp_path_lookup(sdata, da); ++ if (!mppath) { ++ moffld_dbg(sdata, "proxy path lookup failed for %pM during duplicate mpath removal\n", ++ da); ++ rcu_read_unlock(); ++ return -EINVAL; ++ } ++ ++ mesh_path_del(sdata, mpath->dst); ++ ++ rcu_read_unlock(); ++ ++ return 0; ++} ++ ++static int mesh_path_offld_mpath_exp(struct ieee80211_sub_if_data *sdata, u8 *mda) ++{ ++ struct mesh_path *mpath; ++ ++ rcu_read_lock(); ++ ++ mpath = mesh_path_lookup(sdata, mda); ++ if (!mpath) { ++ mpath = mesh_path_add(sdata, mda); ++ if (IS_ERR(mpath)) { ++ rcu_read_unlock(); ++ moffld_dbg(sdata, ++ "failed to add mpath for %pM during mpath exp\n", mda); ++ return PTR_ERR(mpath); ++ } ++ } ++ ++ spin_lock_bh(&mpath->state_lock); ++ mpath->flags &= ~MESH_PATH_ACTIVE; ++ spin_unlock_bh(&mpath->state_lock); ++ ++ if (!(mpath->flags & MESH_PATH_RESOLVING) && ++ mesh_path_sel_is_hwmp(sdata)) ++ mesh_queue_preq(mpath, PREQ_Q_F_START); ++ ++ rcu_read_unlock(); ++ ++ return 0; ++} ++ ++static int mesh_path_offld_mpp_learn(struct ieee80211_sub_if_data *sdata, ++ u8 *da, u8 *mda) ++{ ++ struct mesh_path *mppath; ++ int ret; ++ ++ rcu_read_lock(); ++ mppath = mpp_path_lookup(sdata, da); ++ if (mppath) { ++ moffld_dbg(sdata, "proxy path for da %pM mesh_da %pM already exists\n", ++ da, mda); ++ rcu_read_unlock(); ++ return -EEXIST; ++ } ++ ++ ret = mpp_path_add(sdata, da, mda); ++ if (ret) ++ moffld_dbg(sdata, "failed to add proxy path entry (%d): da %pM mesh_da %pM\n", ++ ret, da, mda); ++ ++ rcu_read_unlock(); ++ ++ return ret; ++} ++ ++static int mesh_path_offld_mpp_add(struct ieee80211_sub_if_data *sdata, ++ u8 *da, u8 *mda) ++{ ++ struct mesh_path *mppath; ++ int ret; ++ ++ rcu_read_lock(); ++ mppath = mpp_path_lookup(sdata, da); ++ if (mppath) { ++ moffld_dbg(sdata, "proxy path for da %pM mesh_da %pM already exists\n", ++ da, mda); ++ rcu_read_unlock(); ++ return -EEXIST; ++ } ++ ++ ret = __mpp_path_add(sdata, da, mda); ++ if (ret) ++ moffld_dbg(sdata, "failed to add proxy path entry (%d): da %pM mesh_da %pM\n", ++ ret, da, mda); ++ ++ rcu_read_unlock(); ++ ++ return ret; ++} ++ ++static int mesh_path_offld_mpp_update(struct ieee80211_sub_if_data *sdata, ++ u8 *da, u8 *mda) ++{ ++ struct mesh_path *mppath; ++ ++ rcu_read_lock(); ++ mppath = mpp_path_lookup(sdata, da); ++ if (!mppath) { ++ moffld_dbg(sdata, ++ "proxy path lookup for da %pM failed during MPP update with mesh_da %pM\n", ++ da, mda); ++ rcu_read_unlock(); ++ return -ENOENT; ++ } else { ++ spin_lock_bh(&mppath->state_lock); ++ if (!ether_addr_equal(mppath->mpp, mda)) ++ memcpy(mppath->mpp, mda, ETH_ALEN); ++ mppath->exp_time = jiffies; ++ spin_unlock_bh(&mppath->state_lock); ++ } ++ rcu_read_unlock(); ++ ++ return 0; ++} ++ ++static int mesh_path_offld_mpath_not_found(struct ieee80211_sub_if_data *sdata, ++ u8 *mda, u8 *ta) ++{ ++ struct mesh_path *mpath; ++ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; ++ ++ rcu_read_lock(); ++ ++ mpath = mesh_path_lookup(sdata, mda); ++ if (!mpath) { ++ mpath = mesh_path_add(sdata, mda); ++ if (IS_ERR(mpath)) { ++ moffld_dbg(sdata, "mpath add failed for mesh_da %pM (%lu)\n", ++ mda, PTR_ERR(mpath)); ++ rcu_read_unlock(); ++ return PTR_ERR(mpath); ++ } ++ } ++ ++ if (!(mpath->flags & MESH_PATH_RESOLVING) && ++ mesh_path_sel_is_hwmp(sdata)) ++ mesh_queue_preq(mpath, PREQ_Q_F_START); ++ ++ rcu_read_unlock(); ++ ++ if (!is_zero_ether_addr(ta)) ++ mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl, ++ mda, 0, WLAN_REASON_MESH_PATH_NOFORWARD, ta); ++ ++ return 0; ++} ++ ++void ieee80211s_update_metric_ppdu(struct ieee80211_hw *hw, ++ struct ieee80211_tx_status *st) ++{ ++ struct sta_info *sta; ++ int i, num_mpdu; ++ bool failed; ++ struct rate_info rinfo; ++ ++ if (!st->sta) ++ return; ++ ++ if (st->mpdu_succ) { ++ num_mpdu = st->mpdu_succ; ++ failed = false; ++ } else if (st->mpdu_fail) { ++ num_mpdu = st->mpdu_fail; ++ failed = true; ++ } else ++ return; ++ ++ sta = container_of(st->sta, struct sta_info, sta); ++ if (!ieee80211_vif_is_mesh(&sta->sdata->vif)) ++ return; ++ ++ for (i = 0; i < num_mpdu; i++) { ++ ewma_mesh_fail_avg_add(&sta->mesh->fail_avg, failed * 100); ++ if (ewma_mesh_fail_avg_read(&sta->mesh->fail_avg) > ++ LINK_FAIL_THRESH) ++ mesh_plink_broken(sta); ++ ++ if (!st->rates) ++ continue; ++ ++ rinfo = st->rates->rate_idx; ++ ewma_mesh_tx_rate_avg_add(&sta->mesh->tx_rate_avg, ++ cfg80211_calculate_bitrate(&rinfo)); ++ } ++} ++EXPORT_SYMBOL(ieee80211s_update_metric_ppdu); ++ ++int ieee80211_mesh_path_offld_change_notify(struct ieee80211_vif *vif, ++ struct ieee80211_mesh_path_offld *path, ++ enum ieee80211_mesh_path_offld_action action) ++{ ++ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); ++ int ret = -ENOTSUPP; ++ ++ moffld_dbg(sdata, "received mesh offload event %d\n", action); ++ ++ switch (action) { ++ case IEEE80211_MESH_PATH_OFFLD_ACTION_MPATH_REFRESH: ++ ret = mesh_path_offld_mpath_refresh(sdata, path->mesh_da); ++ break; ++ case IEEE80211_MESH_PATH_OFFLD_ACTION_MPATH_DEL: ++ ret = mesh_path_offld_mpath_del(sdata, path->mesh_da); ++ break; ++ case IEEE80211_MESH_PATH_OFFLD_ACTION_MPATH_EXP: ++ ret = mesh_path_offld_mpath_exp(sdata, path->mesh_da); ++ break; ++ case IEEE80211_MESH_PATH_OFFLD_ACTION_MPP_LEARN: ++ ret = mesh_path_offld_mpp_learn(sdata, path->da, path->mesh_da); ++ break; ++ case IEEE80211_MESH_PATH_OFFLD_ACTION_MPP_ADD: ++ ret = mesh_path_offld_mpp_add(sdata, path->da, path->mesh_da); ++ break; ++ case IEEE80211_MESH_PATH_OFFLD_ACTION_MPP_UPDATE: ++ ret = mesh_path_offld_mpp_update(sdata, path->da, ++ path->mesh_da); ++ break; ++ case IEEE80211_MESH_PATH_OFFLD_ACTION_PATH_NOT_FOUND: ++ ret = mesh_path_offld_mpath_not_found(sdata, path->da, ++ path->ta); ++ break; ++ default: ++ break; ++ } ++ ++ return ret; ++} ++EXPORT_SYMBOL(ieee80211_mesh_path_offld_change_notify); +--- a/net/mac80211/mesh_pathtbl.c ++++ b/net/mac80211/mesh_pathtbl.c +@@ -15,6 +15,7 @@ + #include "ieee80211_i.h" + #include "mesh.h" + #include ++#include "driver-ops.h" + + static void mesh_path_free_rcu(struct mesh_table *tbl, struct mesh_path *mpath); + +@@ -103,6 +104,63 @@ static void mesh_table_free(struct mesh_ + mesh_path_rht_free, tbl); + } + ++void mesh_nss_offld_proxy_path_exp_update(struct ieee80211_vif *vif, u8* da, u8* mesh_da, u32 inactive_time) ++{ ++ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); ++ struct mesh_table *tbl = &sdata->u.mesh.mpp_paths; ++ struct mesh_path *mppath; ++ struct hlist_node *n; ++ unsigned long expiry; ++ ++ spin_lock_bh(&tbl->walk_lock); ++ hlist_for_each_entry_safe(mppath, n, &tbl->walk_head, walk_list) { ++ if(!ether_addr_equal(da, mppath->dst) || !ether_addr_equal(mesh_da, mppath->mpp)) ++ continue; ++ if ((!(mppath->flags & MESH_PATH_RESOLVING)) && ++ (!(mppath->flags & MESH_PATH_FIXED))) { ++ expiry = jiffies - msecs_to_jiffies(inactive_time); ++ mppath->exp_time = time_after(mppath->exp_time, expiry) ? ++ mppath->exp_time : expiry; ++ } ++ } ++ spin_unlock_bh(&tbl->walk_lock); ++} ++EXPORT_SYMBOL(mesh_nss_offld_proxy_path_exp_update); ++ ++void mesh_nss_offld_path_update(struct mesh_path *mpath, bool is_mpath, u8 *old_next_hop_addr) ++{ ++ struct ieee80211_mesh_path_offld path = {0}; ++ struct sta_info *next_hop; ++ struct ieee80211_sub_if_data *sdata = mpath->sdata; ++ ++ ++ path.metric = mpath->metric; ++ if (time_before(jiffies, mpath->exp_time)) ++ path.exp_time = jiffies_to_msecs(mpath->exp_time - jiffies); ++ ++ path.hop_count = mpath->hop_count; ++ path.flags = mpath->flags; ++ path.mesh_gate = mpath->is_gate; ++ if (is_mpath) { ++ ether_addr_copy(path.mesh_da, mpath->dst); ++ } else { ++ ether_addr_copy(path.mesh_da, mpath->mpp); ++ ether_addr_copy(path.da, mpath->dst); ++ } ++ ++ next_hop = rcu_dereference(mpath->next_hop); ++ if (next_hop) ++ ether_addr_copy(path.next_hop, next_hop->addr); ++ ++ if (old_next_hop_addr) ++ ether_addr_copy(path.old_next_hop, old_next_hop_addr); ++ ++ drv_config_mesh_offload_path(sdata->local, sdata, ++ is_mpath ? IEEE80211_MESH_PATH_OFFLD_CMD_UPDATE_MPATH : ++ IEEE80211_MESH_PATH_OFFLD_CMD_UPDATE_MPP, ++ &path); ++} ++ + /** + * mesh_path_assign_nexthop - update mesh path next hop + * +@@ -240,16 +298,23 @@ static void mesh_path_move_to_queue(stru + + + static struct mesh_path *mpath_lookup(struct mesh_table *tbl, const u8 *dst, +- struct ieee80211_sub_if_data *sdata) ++ struct ieee80211_sub_if_data *sdata, ++ bool is_mpath) + { + struct mesh_path *mpath; ++ bool update; ++ struct sta_info *next_hop; + + mpath = rhashtable_lookup(&tbl->rhead, dst, mesh_rht_params); + + if (mpath && mpath_expired(mpath)) { + spin_lock_bh(&mpath->state_lock); ++ next_hop = rcu_dereference(mpath->next_hop); ++ update = !!(mpath->flags & MESH_PATH_ACTIVE); + mpath->flags &= ~MESH_PATH_ACTIVE; + spin_unlock_bh(&mpath->state_lock); ++ if (update && is_mpath) ++ mesh_nss_offld_path_update(mpath, true, next_hop ? next_hop->addr : NULL); + } + return mpath; + } +@@ -266,13 +331,13 @@ static struct mesh_path *mpath_lookup(st + struct mesh_path * + mesh_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst) + { +- return mpath_lookup(&sdata->u.mesh.mesh_paths, dst, sdata); ++ return mpath_lookup(&sdata->u.mesh.mesh_paths, dst, sdata, true); + } + + struct mesh_path * + mpp_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst) + { +- return mpath_lookup(&sdata->u.mesh.mpp_paths, dst, sdata); ++ return mpath_lookup(&sdata->u.mesh.mpp_paths, dst, sdata, false); + } + + static struct mesh_path * +@@ -334,6 +399,7 @@ mpp_path_lookup_by_idx(struct ieee80211_ + int mesh_path_add_gate(struct mesh_path *mpath) + { + struct mesh_table *tbl; ++ struct sta_info *next_hop; + int err; + + rcu_read_lock(); +@@ -346,6 +412,7 @@ int mesh_path_add_gate(struct mesh_path + goto err_rcu; + } + mpath->is_gate = true; ++ next_hop = rcu_dereference(mpath->next_hop); + mpath->sdata->u.mesh.num_gates++; + + spin_lock(&tbl->gates_lock); +@@ -354,6 +421,8 @@ int mesh_path_add_gate(struct mesh_path + + spin_unlock_bh(&mpath->state_lock); + ++ mesh_nss_offld_path_update(mpath, true, next_hop ? next_hop->addr : NULL); ++ + mpath_dbg(mpath->sdata, + "Mesh path: Recorded new gate: %pM. %d known gates\n", + mpath->dst, mpath->sdata->u.mesh.num_gates); +@@ -370,16 +439,21 @@ err_rcu: + */ + static void mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath) + { ++ struct sta_info *next_hop; ++ + lockdep_assert_held(&mpath->state_lock); + if (!mpath->is_gate) + return; + ++ next_hop = rcu_dereference(mpath->next_hop); + mpath->is_gate = false; + spin_lock_bh(&tbl->gates_lock); + hlist_del_rcu(&mpath->gate_list); + mpath->sdata->u.mesh.num_gates--; + spin_unlock_bh(&tbl->gates_lock); + ++ mesh_nss_offld_path_update(mpath, true, next_hop ? next_hop->addr : NULL); ++ + mpath_dbg(mpath->sdata, + "Mesh path: Deleted gate: %pM. %d known gates\n", + mpath->dst, mpath->sdata->u.mesh.num_gates); +@@ -667,17 +741,8 @@ void mesh_fast_tx_flush_addr(struct ieee + spin_unlock_bh(&cache->walk_lock); + } + +-/** +- * mesh_path_add - allocate and add a new path to the mesh path table +- * @dst: destination address of the path (ETH_ALEN length) +- * @sdata: local subif +- * +- * Returns: 0 on success +- * +- * State: the initial state of the new path is set to 0 +- */ +-struct mesh_path *mesh_path_add(struct ieee80211_sub_if_data *sdata, +- const u8 *dst) ++struct mesh_path *__mesh_path_add(struct ieee80211_sub_if_data *sdata, ++ const u8 *dst) + { + struct mesh_table *tbl; + struct mesh_path *mpath, *new_mpath; +@@ -718,8 +783,36 @@ struct mesh_path *mesh_path_add(struct i + return new_mpath; + } + +-int mpp_path_add(struct ieee80211_sub_if_data *sdata, +- const u8 *dst, const u8 *mpp) ++/** ++ * mesh_path_add - allocate and add a new path to the mesh path table ++ * @dst: destination address of the path (ETH_ALEN length) ++ * @sdata: local subif ++ * ++ * Returns: 0 on success ++ * ++ * State: the initial state of the new path is set to 0 ++ */ ++struct mesh_path *mesh_path_add(struct ieee80211_sub_if_data *sdata, ++ const u8 *dst) ++{ ++ struct mesh_path *new_path; ++ struct ieee80211_mesh_path_offld path = {0}; ++ ++ new_path = __mesh_path_add(sdata, dst); ++ if (IS_ERR(new_path)) ++ return new_path; ++ ++ ether_addr_copy(path.mesh_da, dst); ++ ++ drv_config_mesh_offload_path(sdata->local, sdata, ++ IEEE80211_MESH_PATH_OFFLD_CMD_ADD_MPATH, ++ &path); ++ ++ return new_path; ++} ++ ++int __mpp_path_add(struct ieee80211_sub_if_data *sdata, ++ const u8 *dst, const u8 *mpp) + { + struct mesh_table *tbl; + struct mesh_path *new_mpath; +@@ -757,6 +850,25 @@ int mpp_path_add(struct ieee80211_sub_if + return ret; + } + ++int mpp_path_add(struct ieee80211_sub_if_data *sdata, ++ const u8 *dst, const u8 *mpp) ++{ ++ struct ieee80211_mesh_path_offld path = {0}; ++ int ret; ++ ++ ret = __mpp_path_add(sdata, dst, mpp); ++ if (ret) ++ return ret; ++ ++ ether_addr_copy(path.mesh_da, mpp); ++ ether_addr_copy(path.da, dst); ++ ++ drv_config_mesh_offload_path(sdata->local, sdata, ++ IEEE80211_MESH_PATH_OFFLD_CMD_ADD_MPP, ++ &path); ++ ++ return 0; ++} + + /** + * mesh_plink_broken - deactivates paths and sends perr when a link breaks +@@ -807,8 +919,29 @@ static void mesh_path_free_rcu(struct me + kfree_rcu(mpath, rcu); + } + +-static void __mesh_path_del(struct mesh_table *tbl, struct mesh_path *mpath) ++static void __mesh_path_del(struct mesh_table *tbl, struct mesh_path *mpath, ++ bool is_mpath_tbl) + { ++ struct ieee80211_mesh_path_offld path = {0}; ++ struct sta_info *next_hop; ++ struct ieee80211_sub_if_data *sdata = mpath->sdata; ++ ++ ++ path.metric = mpath->metric; ++ path.exp_time = mpath->exp_time; ++ path.hop_count = mpath->hop_count; ++ path.flags = mpath->flags; ++ if (is_mpath_tbl) { ++ ether_addr_copy(path.mesh_da, mpath->dst); ++ } else { ++ ether_addr_copy(path.mesh_da, mpath->mpp); ++ ether_addr_copy(path.da, mpath->dst); ++ } ++ ++ next_hop = rcu_dereference(mpath->next_hop); ++ if (next_hop) ++ ether_addr_copy(path.next_hop, next_hop->addr); ++ + hlist_del_rcu(&mpath->walk_list); + rhashtable_remove_fast(&tbl->rhead, &mpath->rhash, mesh_rht_params); + if (tbl == &mpath->sdata->u.mesh.mpp_paths) +@@ -816,6 +949,11 @@ static void __mesh_path_del(struct mesh_ + else + mesh_fast_tx_flush_mpath(mpath); + mesh_path_free_rcu(tbl, mpath); ++ ++ drv_config_mesh_offload_path(sdata->local, sdata, ++ is_mpath_tbl ? IEEE80211_MESH_PATH_OFFLD_CMD_DELETE_MPATH : ++ IEEE80211_MESH_PATH_OFFLD_CMD_DELETE_MPP, ++ &path); + } + + /** +@@ -839,7 +977,7 @@ void mesh_path_flush_by_nexthop(struct s + spin_lock_bh(&tbl->walk_lock); + hlist_for_each_entry_safe(mpath, n, &tbl->walk_head, walk_list) { + if (rcu_access_pointer(mpath->next_hop) == sta) +- __mesh_path_del(tbl, mpath); ++ __mesh_path_del(tbl, mpath, true); + } + spin_unlock_bh(&tbl->walk_lock); + } +@@ -854,19 +992,19 @@ static void mpp_flush_by_proxy(struct ie + spin_lock_bh(&tbl->walk_lock); + hlist_for_each_entry_safe(mpath, n, &tbl->walk_head, walk_list) { + if (ether_addr_equal(mpath->mpp, proxy)) +- __mesh_path_del(tbl, mpath); ++ __mesh_path_del(tbl, mpath, false); + } + spin_unlock_bh(&tbl->walk_lock); + } + +-static void table_flush_by_iface(struct mesh_table *tbl) ++static void table_flush_by_iface(struct mesh_table *tbl, bool is_mpath_tbl) + { + struct mesh_path *mpath; + struct hlist_node *n; + + spin_lock_bh(&tbl->walk_lock); + hlist_for_each_entry_safe(mpath, n, &tbl->walk_head, walk_list) { +- __mesh_path_del(tbl, mpath); ++ __mesh_path_del(tbl, mpath, is_mpath_tbl); + } + spin_unlock_bh(&tbl->walk_lock); + } +@@ -881,8 +1019,8 @@ static void table_flush_by_iface(struct + */ + void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata) + { +- table_flush_by_iface(&sdata->u.mesh.mesh_paths); +- table_flush_by_iface(&sdata->u.mesh.mpp_paths); ++ table_flush_by_iface(&sdata->u.mesh.mesh_paths, true); ++ table_flush_by_iface(&sdata->u.mesh.mpp_paths, false); + } + + /** +@@ -896,7 +1034,7 @@ void mesh_path_flush_by_iface(struct iee + */ + static int table_path_del(struct mesh_table *tbl, + struct ieee80211_sub_if_data *sdata, +- const u8 *addr) ++ const u8 *addr, bool is_mpath_tbl) + { + struct mesh_path *mpath; + +@@ -907,7 +1045,7 @@ static int table_path_del(struct mesh_ta + return -ENXIO; + } + +- __mesh_path_del(tbl, mpath); ++ __mesh_path_del(tbl, mpath, is_mpath_tbl); + spin_unlock_bh(&tbl->walk_lock); + return 0; + } +@@ -928,7 +1066,7 @@ int mesh_path_del(struct ieee80211_sub_i + /* flush relevant mpp entries first */ + mpp_flush_by_proxy(sdata, addr); + +- err = table_path_del(&sdata->u.mesh.mesh_paths, sdata, addr); ++ err = table_path_del(&sdata->u.mesh.mesh_paths, sdata, addr, true); + sdata->u.mesh.mesh_paths_generation++; + return err; + } +@@ -1031,7 +1169,10 @@ void mesh_path_flush_pending(struct mesh + */ + void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop) + { ++ struct sta_info *old_next_hop; ++ + spin_lock_bh(&mpath->state_lock); ++ old_next_hop = rcu_dereference(mpath->next_hop); + mesh_path_assign_nexthop(mpath, next_hop); + mpath->sn = 0xffff; + mpath->metric = 0; +@@ -1045,6 +1186,8 @@ void mesh_path_fix_nexthop(struct mesh_p + /* init it at a low value - 0 start is tricky */ + ewma_mesh_fail_avg_add(&next_hop->mesh->fail_avg, 1); + mesh_path_tx_pending(mpath); ++ ++ mesh_nss_offld_path_update(mpath, true, old_next_hop ? old_next_hop->addr : NULL); + } + + void mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata) +@@ -1056,7 +1199,7 @@ void mesh_pathtbl_init(struct ieee80211_ + + static + void mesh_path_tbl_expire(struct ieee80211_sub_if_data *sdata, +- struct mesh_table *tbl) ++ struct mesh_table *tbl, bool is_mpath_tbl) + { + struct mesh_path *mpath; + struct hlist_node *n; +@@ -1066,15 +1209,15 @@ void mesh_path_tbl_expire(struct ieee802 + if ((!(mpath->flags & MESH_PATH_RESOLVING)) && + (!(mpath->flags & MESH_PATH_FIXED)) && + time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE)) +- __mesh_path_del(tbl, mpath); ++ __mesh_path_del(tbl, mpath, is_mpath_tbl); + } + spin_unlock_bh(&tbl->walk_lock); + } + + void mesh_path_expire(struct ieee80211_sub_if_data *sdata) + { +- mesh_path_tbl_expire(sdata, &sdata->u.mesh.mesh_paths); +- mesh_path_tbl_expire(sdata, &sdata->u.mesh.mpp_paths); ++ mesh_path_tbl_expire(sdata, &sdata->u.mesh.mesh_paths, true); ++ mesh_path_tbl_expire(sdata, &sdata->u.mesh.mpp_paths, false); + } + + 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 + info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; + #endif + ++ info = IEEE80211_SKB_CB(skb); ++ memset(info, 0, sizeof(*info)); ++ + /* 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 + break; + #ifdef CPTCFG_MAC80211_MESH + case NL80211_IFTYPE_MESH_POINT: ++ if (ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD) && ++ (sdata->vif.driver_flags & IEEE80211_VIF_NSS_OFFLOAD_DEBUG_MODE) && ++ !(is_multicast_ether_addr(skb->data))) { ++ info->flags = IEEE80211_TX_CTL_HW_80211_ENCAP; ++ goto nss_mesh; ++ } ++ + 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 + + skb_reset_mac_header(skb); + +- info = IEEE80211_SKB_CB(skb); +- memset(info, 0, sizeof(*info)); +- +- info->flags = info_flags; ++#ifdef CPTCFG_MAC80211_MESH ++nss_mesh: ++#endif ++ info->flags |= info_flags; + info->ack_frame_id = info_id; + info->band = band; + +@@ -4284,6 +4294,7 @@ void __ieee80211_subif_start_xmit(struct + struct sk_buff *next; + int len = skb->len; + struct ieee80211_key *key = NULL; ++ struct ieee80211_tx_info *info; + 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 + goto out; + } + +- ieee80211_tx_stats(dev, skb->len); +- +- ieee80211_xmit(sdata, sta, skb); ++ info = IEEE80211_SKB_CB(skb); ++ 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); ++ } else { ++ ieee80211_tx_stats(dev, skb->len); ++ ieee80211_xmit(sdata, sta, skb); ++ } + } + goto out; + out_free: 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/ath11k_nss/335-0003-ath11k-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch new file mode 100644 index 00000000000000..1bfbd0ebdbb27e --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/335-0003-ath11k-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch @@ -0,0 +1,80 @@ +From 6a9662d48c4f277380283050370ab3f1f940b6a6 Mon Sep 17 00:00:00 2001 +From: Venkateswara Naralasetty +Date: Mon, 4 Sep 2023 13:44:47 +0530 +Subject: [PATCH] ath11k: skip HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE config + +Don't set HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE flag to TCL, +HW only take care of tid classification if this flag is not set. + +Signed-off-by: Venkateswara Naralasetty +--- + drivers/net/wireless/ath/ath11k/dp_tx.c | 19 +------------------ + drivers/net/wireless/ath/ath11k/hal_tx.c | 1 - + drivers/net/wireless/ath/ath11k/mac.c | 2 ++ + 3 files changed, 3 insertions(+), 19 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/dp_tx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_tx.c +@@ -44,19 +44,6 @@ static void ath11k_dp_tx_encap_nwifi(str + hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA); + } + +-static u8 ath11k_dp_tx_get_tid(struct sk_buff *skb) +-{ +- struct ieee80211_hdr *hdr = (void *)skb->data; +- struct ath11k_skb_cb *cb = ATH11K_SKB_CB(skb); +- +- if (cb->flags & ATH11K_SKB_HW_80211_ENCAP) +- return skb->priority & IEEE80211_QOS_CTL_TID_MASK; +- else if (!ieee80211_is_data_qos(hdr->frame_control)) +- return HAL_DESC_REO_NON_QOS_TID; +- else +- return skb->priority & IEEE80211_QOS_CTL_TID_MASK; +-} +- + 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: + if (ieee80211_vif_is_mesh(arvif->vif)) + ti.enable_mesh = true; + +- ti.flags1 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE, 1); +- +- ti.tid = ath11k_dp_tx_get_tid(skb); +- + switch (ti.encap_type) { + case HAL_TCL_ENCAP_TYPE_NATIVE_WIFI: + if (arvif->vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) +--- a/drivers/net/wireless/ath/ath11k/hal_tx.c ++++ b/drivers/net/wireless/ath/ath11k/hal_tx.c +@@ -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 | +- 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, +--- 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 + ieee80211_hw_set(ar->hw, USES_RSS); + } + ++ ieee80211_hw_set(ar->hw, SUPPORTS_TID_CLASS_OFFLOAD); ++ + ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; + ar->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; + 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/ath11k_nss/335-0003-mac80211-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch new file mode 100644 index 00000000000000..6a37ba0e1aa730 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/335-0003-mac80211-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch @@ -0,0 +1,45 @@ +From c7bd857a315fb299e4c984be2f3720428477ae6e Mon Sep 17 00:00:00 2001 +From: Venkateswara Naralasetty +Date: Thu, 11 Nov 2021 11:14:08 +0530 +Subject: [PATCH] ath11k: skip HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE config + +Don't set HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE flag to TCL, +HW only take care of tid classification if this flag is not set. + +Signed-off-by: Venkateswara Naralasetty +Signed-off-by: Gautham Kumar Senthilkumaran +--- + include/net/mac80211.h | 3 +++ + net/mac80211/debugfs.c | 1 + + net/mac80211/wme.c | 3 +++ + 3 files changed, 7 insertions(+) + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -2727,6 +2727,8 @@ struct ieee80211_txq { + * + * @IEEE80211_HW_SUPPORTS_NSS_OFFLOAD: Hardware/driver supports NSS offload + * ++ * @IEEE80211_HW_SUPPORTS_TID_CLASS_OFFLOAD: Hardware suports tid calssification offload. ++ * + * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays + */ + enum ieee80211_hw_flags { +@@ -2786,6 +2788,7 @@ enum ieee80211_hw_flags { + IEEE80211_HW_MLO_MCAST_MULTI_LINK_TX, + IEEE80211_HW_SUPPORTS_NSS_OFFLOAD, + IEEE80211_HW_SUPPORTS_MESH_NSS_OFFLOAD, ++ IEEE80211_HW_SUPPORTS_TID_CLASS_OFFLOAD, + + /* keep last, obviously */ + NUM_IEEE80211_HW_FLAGS +--- a/net/mac80211/debugfs.c ++++ b/net/mac80211/debugfs.c +@@ -498,6 +498,7 @@ static const char *hw_flag_names[] = { + FLAG(MLO_MCAST_MULTI_LINK_TX), + FLAG(SUPPORTS_NSS_OFFLOAD), + FLAG(SUPPORTS_MESH_NSS_OFFLOAD), ++ FLAG(SUPPORTS_TID_CLASS_OFFLOAD), + #undef FLAG + }; + diff --git a/package/kernel/mac80211/patches/ath11k_nss/336-mac80211-Mesh-Fast-rx-support.patch b/package/kernel/mac80211/patches/ath11k_nss/336-mac80211-Mesh-Fast-rx-support.patch new file mode 100644 index 00000000000000..d29a05f13943bf --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/336-mac80211-Mesh-Fast-rx-support.patch @@ -0,0 +1,208 @@ +From 0f024902a8a54c70204f5b2f824c5dc74888c536 Mon Sep 17 00:00:00 2001 +From: Sriram R +Date: Wed, 29 Sep 2021 09:30:21 +0530 +Subject: [PATCH] mac80211: Add support for mesh fast Rx path + +Add support to process rx frames for the mesh destination +when driver supports fast Rx by offloading PN, Duplicate, +reordering to the HW. + +Fast Rx from a peer is enabled once the PLINK is established. +Fast Rx is not supported for the forwarding path currently. + +Signed-off-by: Sriram R +--- + net/mac80211/cfg.c | 5 + + net/mac80211/ieee80211_i.h | 1 + + net/mac80211/mesh_plink.c | 5 + + net/mac80211/rx.c | 262 ++++++++++++++++++++++++++++++++++++++++++++- + 4 files changed, 269 insertions(+), 4 deletions(-) + +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -1747,6 +1747,8 @@ static void sta_apply_mesh_params(struct + /* init at low value */ + ewma_mesh_tx_rate_avg_add(&sta->mesh->tx_rate_avg, 10); + ++ ieee80211_check_fast_rx(sta); ++ + break; + case NL80211_PLINK_LISTEN: + case NL80211_PLINK_BLOCKED: +@@ -1761,6 +1763,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); ++ ieee80211_check_fast_rx(sta); + break; + default: + /* nothing */ +--- a/net/mac80211/mesh_plink.c ++++ b/net/mac80211/mesh_plink.c +@@ -381,6 +381,8 @@ static u64 __mesh_plink_deactivate(struc + changed |= ieee80211_mps_set_sta_local_pm(sta, + NL80211_MESH_POWER_UNKNOWN); + ++ ieee80211_check_fast_rx(sta); ++ + return changed; + } + +@@ -846,6 +848,7 @@ static u64 mesh_plink_establish(struct i + mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", sta->sta.addr); + ieee80211_mps_sta_status_update(sta); + changed |= ieee80211_mps_set_sta_local_pm(sta, mshcfg->power_mode); ++ ieee80211_check_fast_rx(sta); + return changed; + } + +@@ -864,7 +867,7 @@ static u64 mesh_plink_fsm(struct ieee802 + struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg; + enum ieee80211_self_protected_actioncode action = 0; + u64 changed = 0; +- bool flush = false; ++ bool flush = false, check_fast_rx = false; + + mpl_dbg(sdata, "peer %pM in state %s got event %s\n", sta->sta.addr, + mplstates[sta->mesh->plink_state], mplevents[event]); +@@ -924,6 +927,7 @@ static u64 mesh_plink_fsm(struct ieee802 + break; + case CNF_ACPT: + changed |= mesh_plink_establish(sdata, sta); ++ check_fast_rx = true; + break; + default: + break; +@@ -939,6 +943,7 @@ static u64 mesh_plink_fsm(struct ieee802 + break; + case OPN_ACPT: + changed |= mesh_plink_establish(sdata, sta); ++ check_fast_rx = true; + action = WLAN_SP_MESH_PEERING_CONFIRM; + break; + default: +@@ -985,6 +990,10 @@ static u64 mesh_plink_fsm(struct ieee802 + break; + } + spin_unlock_bh(&sta->mesh->plink_lock); ++ ++ if (check_fast_rx) ++ ieee80211_check_fast_rx(sta); ++ + if (flush) + mesh_path_flush_by_nexthop(sta); + if (action) { +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -4663,10 +4663,15 @@ void ieee80211_check_fast_rx(struct sta_ + + break; + case NL80211_IFTYPE_MESH_POINT: ++ /* Not required for NSS mode */ ++ if (ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) ++ goto clear; ++ /* Note: da and sa offs are not static, determine in fast rx path */ ++ + fastrx.expected_ds_bits = cpu_to_le16(IEEE80211_FCTL_FROMDS | + IEEE80211_FCTL_TODS); +- fastrx.da_offs = offsetof(struct ieee80211_hdr, addr3); +- fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr4); ++ ++ fastrx.internal_forward = 0; + break; + default: + goto clear; +@@ -4707,7 +4712,7 @@ void ieee80211_check_fast_rx(struct sta_ + __release(check_fast_rx); + + if (assign) +- new = kmemdup(&fastrx, sizeof(fastrx), GFP_KERNEL); ++ new = kmemdup(&fastrx, sizeof(fastrx), GFP_ATOMIC); + + 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 + u8 sa[ETH_ALEN]; + } addrs __aligned(2); + struct ieee80211_sta_rx_stats *stats; ++ struct ieee80211s_hdr *mesh_hdr; ++ struct mesh_path *mppath; ++ u8 da_offs = fast_rx->da_offs, sa_offs = fast_rx->sa_offs; ++ struct ieee80211_sub_if_data *sdata = rx->sdata; + + /* 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 + snap_offs += IEEE80211_CCMP_HDR_LEN; + } + ++ /* Find corresponding offsets for mesh hdr */ ++ if (ieee80211_vif_is_mesh(&sdata->vif)) { ++ if (status->rx_flags & IEEE80211_RX_AMSDU) ++ return false; ++ ++ /* All mesh data frames needs to be QoS Data */ ++ if (unlikely(!ieee80211_is_data_qos(hdr->frame_control))) ++ return false; ++ ++ /* TODO forwarding not handled yet in fast rx */ ++ if (!ether_addr_equal(fast_rx->vif_addr, hdr->addr3)) ++ return false; ++ ++ /* Check if Min Mesh hdr is present */ ++ if (!pskb_may_pull(skb, hdrlen + 6)) ++ goto drop; ++ ++ /* Goto mesh hdr, located at snap offs compared to AP/STA */ ++ mesh_hdr = (struct ieee80211s_hdr *) (skb->data + snap_offs); ++ ++ /* Only Ext Mesh hdr supported in this path now */ ++ if ((mesh_hdr->flags & MESH_FLAGS_AE) != MESH_FLAGS_AE_A5_A6) ++ return false; ++ ++ /* Point to eaddr1 and eaddr2 */ ++ da_offs = snap_offs + ETH_ALEN; ++ sa_offs = da_offs + ETH_ALEN; ++ ++ snap_offs += sizeof(struct ieee80211s_hdr); ++ } ++ + 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 + return true; + } + ++ /* Update MPP table for the received packet */ ++ if (ieee80211_vif_is_mesh(&sdata->vif)) { ++ char *proxied_addr, *mpp_addr; ++ ++ mpp_addr = hdr->addr4; ++ proxied_addr = mesh_hdr->eaddr2; ++ ++ /* Update mpp for the SA */ ++ rcu_read_lock(); ++ mppath = mpp_path_lookup(sdata, proxied_addr); ++ if (!mppath) { ++ mpp_path_add(sdata, proxied_addr, mpp_addr); ++ } else { ++ spin_lock_bh(&mppath->state_lock); ++ ++ if (!ether_addr_equal(mppath->mpp, mpp_addr)) ++ ether_addr_copy(mppath->mpp, mpp_addr); ++ ++ mppath->exp_time = jiffies; ++ spin_unlock_bh(&mppath->state_lock); ++ } ++ rcu_read_unlock(); ++ } ++ + /* do the header conversion - first grab the addresses */ +- ether_addr_copy(addrs.da, skb->data + fast_rx->da_offs); +- ether_addr_copy(addrs.sa, skb->data + fast_rx->sa_offs); ++ ether_addr_copy(addrs.da, skb->data + da_offs); ++ ether_addr_copy(addrs.sa, skb->data + sa_offs); + if (ieee80211_vif_is_mesh(&rx->sdata->vif)) { + skb_pull(skb, snap_offs - 2); + put_unaligned_be16(skb->len - 2, skb->data); 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/ath11k_nss/353-mac80211-fix-dynamic-vlan-warning-with-monitor-interface-restart.patch new file mode 100644 index 00000000000000..d128824140ecb6 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/353-mac80211-fix-dynamic-vlan-warning-with-monitor-interface-restart.patch @@ -0,0 +1,33 @@ +From 0628e831520aa2e57aed02aee4a1772b40ce4f9d Mon Sep 17 00:00:00 2001 +From: Nagarajan Maran +Date: Thu, 30 Jun 2022 17:20:29 +0530 +Subject: [PATCH] mac80211: fix dynamic vlan warning with monitor interface restart + +When monitor interface restarts, in nss offload disabled +case, the encap and decap offload flags are removed +from all the interfaces in that phy#. + +However when dynamic VLAN and monitor interfaces are +created in the same phy#, these flags are not updated +correctly, due to which warning calltrace is observed. + +Add condition check to update the correct flags in +dynamic VLAN case. + +Signed-off-by: Nagarajan Maran +--- + net/mac80211/iface.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -994,7 +994,8 @@ static bool ieee80211_set_sdata_offload_ + flags |= IEEE80211_OFFLOAD_DECAP_ENABLED; + + if (local->monitors && +- !ieee80211_hw_check(&local->hw, SUPPORTS_CONC_MON_RX_DECAP)) ++ (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD) || ++ !ieee80211_hw_check(&local->hw, SUPPORTS_CONC_MON_RX_DECAP))) + flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED; + } else { + flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED; 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 new file mode 100644 index 00000000000000..4a8328f4e3ca83 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/675-01-cfg80211-Extend-interface-combination-advertisement-.patch @@ -0,0 +1,1594 @@ +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/829-mac80211-fix-mesh-ping-issue.patch b/package/kernel/mac80211/patches/ath11k_nss/829-mac80211-fix-mesh-ping-issue.patch new file mode 100644 index 00000000000000..7043ecb079061a --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/829-mac80211-fix-mesh-ping-issue.patch @@ -0,0 +1,113 @@ +From a76238143218ea348cec4b5d26fe9411338ae09e Mon Sep 17 00:00:00 2001 +From: Aaradhana Sahu +Date: Fri, 6 Oct 2023 18:19:53 +0530 +Subject: [PATCH] mac80211: fix mesh ping issue + +Signed-off-by: Aaradhana Sahu +--- + net/mac80211/rx.c | 68 +++-------------------------------------------- + 1 file changed, 4 insertions(+), 64 deletions(-) + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -4748,16 +4748,14 @@ void ieee80211_check_fast_rx(struct sta_ + + break; + case NL80211_IFTYPE_MESH_POINT: +- /* Not required for NSS mode */ +- if (ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) +- goto clear; + /* Note: da and sa offs are not static, determine in fast rx path */ + + fastrx.expected_ds_bits = cpu_to_le16(IEEE80211_FCTL_FROMDS | + IEEE80211_FCTL_TODS); +- +- fastrx.internal_forward = 0; +- break; ++ fastrx.da_offs = offsetof(struct ieee80211_hdr, addr3); ++ fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr4); ++ break; ++ + default: + goto clear; + } +@@ -4980,10 +4978,7 @@ static bool ieee80211_invoke_fast_rx(str + u8 sa[ETH_ALEN]; + } addrs __aligned(2); + struct ieee80211_sta_rx_stats *stats; +- struct ieee80211s_hdr *mesh_hdr; +- struct mesh_path *mppath; + u8 da_offs = fast_rx->da_offs, sa_offs = fast_rx->sa_offs; +- struct ieee80211_sub_if_data *sdata = rx->sdata; + + /* 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 + snap_offs += IEEE80211_CCMP_HDR_LEN; + } + +- /* Find corresponding offsets for mesh hdr */ +- if (ieee80211_vif_is_mesh(&sdata->vif)) { +- if (status->rx_flags & IEEE80211_RX_AMSDU) +- return false; +- +- /* All mesh data frames needs to be QoS Data */ +- if (unlikely(!ieee80211_is_data_qos(hdr->frame_control))) +- return false; +- +- /* TODO forwarding not handled yet in fast rx */ +- if (!ether_addr_equal(fast_rx->vif_addr, hdr->addr3)) +- return false; +- +- /* Check if Min Mesh hdr is present */ +- if (!pskb_may_pull(skb, hdrlen + 6)) +- goto drop; +- +- /* Goto mesh hdr, located at snap offs compared to AP/STA */ +- mesh_hdr = (struct ieee80211s_hdr *) (skb->data + snap_offs); +- +- /* Only Ext Mesh hdr supported in this path now */ +- if ((mesh_hdr->flags & MESH_FLAGS_AE) != MESH_FLAGS_AE_A5_A6) +- return false; +- +- /* Point to eaddr1 and eaddr2 */ +- da_offs = snap_offs + ETH_ALEN; +- sa_offs = da_offs + ETH_ALEN; +- +- snap_offs += sizeof(struct ieee80211s_hdr); +- } +- + 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 + return true; + } + +- /* Update MPP table for the received packet */ +- if (ieee80211_vif_is_mesh(&sdata->vif)) { +- char *proxied_addr, *mpp_addr; +- +- mpp_addr = hdr->addr4; +- proxied_addr = mesh_hdr->eaddr2; +- +- /* Update mpp for the SA */ +- rcu_read_lock(); +- mppath = mpp_path_lookup(sdata, proxied_addr); +- if (!mppath) { +- mpp_path_add(sdata, proxied_addr, mpp_addr); +- } else { +- spin_lock_bh(&mppath->state_lock); +- +- if (!ether_addr_equal(mppath->mpp, mpp_addr)) +- ether_addr_copy(mppath->mpp, mpp_addr); +- +- mppath->exp_time = jiffies; +- spin_unlock_bh(&mppath->state_lock); +- } +- rcu_read_unlock(); +- } +- + /* do the header conversion - first grab the addresses */ + ether_addr_copy(addrs.da, skb->data + da_offs); + ether_addr_copy(addrs.sa, skb->data + sa_offs); 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 new file mode 100644 index 00000000000000..52037816a113b1 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/902-022-ath11k-add-ap-ps-support.patch @@ -0,0 +1,324 @@ +--- 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/902-wifi-mac80211-Fix-memory-corruption-during-mesh-beac.patch b/package/kernel/mac80211/patches/ath11k_nss/902-wifi-mac80211-Fix-memory-corruption-during-mesh-beac.patch new file mode 100644 index 00000000000000..ea76cd96327e46 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/902-wifi-mac80211-Fix-memory-corruption-during-mesh-beac.patch @@ -0,0 +1,68 @@ +From 0ff455d1d446e34ae6c2596d4d8491f66fc61913 Mon Sep 17 00:00:00 2001 +From: Manish Dharanenthiran +Date: Sat, 2 Dec 2023 03:38:31 +0530 +Subject: [PATCH] wifi: mac80211: Fix memory corruption during mesh beacon + update + +During mesh beacon update, u64 flag is used to check for +bit set/unset for validation purpose. But, in +'ieee80211_mbss_info_change_notify' API, unsigned long flag +is modified using sizeof(u64). This leads to following issue: + + > 'mbss_changed' flag in 'ieee80211_if_mesh' is declared as + unsigned_long which creates an architecture dependency + (32bit vs 64bit) while modifying it with u64 flag which + leads to memory corruption. + +Fix above mentioned issue by replacing unsigned long with u64 +for changed flag. + +Signed-off-by: Manish Dharanenthiran +--- + net/mac80211/ieee80211_i.h | 2 +- + net/mac80211/mesh.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -683,7 +683,7 @@ struct ieee80211_if_mesh { + struct timer_list mesh_path_root_timer; + + unsigned long wrkq_flags; +- unsigned long mbss_changed[64 / BITS_PER_LONG]; ++ unsigned long mbss_changed; + + bool userspace_handles_dfs; + +--- a/net/mac80211/mesh.c ++++ b/net/mac80211/mesh.c +@@ -1183,7 +1183,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) +- set_bit(bit, ifmsh->mbss_changed); ++ set_bit(bit, &ifmsh->mbss_changed); + 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 + + /* clear any mesh work (for next join) we may have accrued */ + ifmsh->wrkq_flags = 0; +- memset(ifmsh->mbss_changed, 0, sizeof(ifmsh->mbss_changed)); ++ ifmsh->mbss_changed = 0; + + local->fif_other_bss--; + atomic_dec(&local->iff_allmultis); +@@ -1732,9 +1732,9 @@ static void mesh_bss_info_changed(struct + u32 bit; + u64 changed = 0; + +- for_each_set_bit(bit, ifmsh->mbss_changed, ++ for_each_set_bit(bit, &ifmsh->mbss_changed, + sizeof(changed) * BITS_PER_BYTE) { +- clear_bit(bit, ifmsh->mbss_changed); ++ clear_bit(bit, &ifmsh->mbss_changed); + changed |= BIT(bit); + } + 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 new file mode 100644 index 00000000000000..5d695ccfe55f2e --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/904-300-ath11k-nss_get_arvif_from_dev.patch @@ -0,0 +1,113 @@ +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; + } + } +@@ -786,24 +814,7 @@ ath11k_nss_vdev_special_data_receive(str + int ret = 0; + struct ath11k_peer *ta_peer = NULL; + +- 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/907-068-ath11k-add-rx-histogram-stats.patch b/package/kernel/mac80211/patches/ath11k_nss/907-068-ath11k-add-rx-histogram-stats.patch new file mode 100644 index 00000000000000..d3ffa5bd8da8e7 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/907-068-ath11k-add-rx-histogram-stats.patch @@ -0,0 +1,608 @@ +From 4635ca1f29bc5838d556b09e3c186b76a5198ddb Mon Sep 17 00:00:00 2001 +From: Manikanta Pubbisetty +Date: Fri, 18 Aug 2023 11:43:33 +0530 +Subject: [PATCH] ath11k: add rx histogram stats + +Adding rx rate table and byte level peer rx statistics. Also, +adding a debugfs knob to reset rx stats specific to the peer. + +Signed-off-by: Manikanta Pubbisetty +--- + drivers/net/wireless/ath/ath11k/core.h | 19 ++- + drivers/net/wireless/ath/ath11k/debugfs_sta.c | 152 ++++++++++++++++-- + drivers/net/wireless/ath/ath11k/dp_rx.c | 95 +++++++++-- + drivers/net/wireless/ath/ath11k/dp_rx.h | 19 +++ + drivers/net/wireless/ath/ath11k/hal_rx.c | 85 +++++++--- + drivers/net/wireless/ath/ath11k/hal_rx.h | 21 +++ + drivers/net/wireless/ath/ath11k/hw.c | 18 +++ + drivers/net/wireless/ath/ath11k/hw.h | 1 + + 8 files changed, 351 insertions(+), 59 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -44,6 +44,8 @@ + + #define ATH11K_INVALID_HW_MAC_ID 0xFF + #define ATH11K_CONNECTION_LOSS_HZ (3 * HZ) ++#define ATH11K_RX_RATE_TABLE_NUM 320 ++#define ATH11K_RX_RATE_TABLE_11AX_NUM 576 + + /* SMBIOS type containing Board Data File Name Extension */ + #define ATH11K_SMBIOS_BDF_EXT_TYPE 0xF8 +@@ -420,6 +422,17 @@ struct ath11k_vif_iter { + struct ath11k_vif *arvif; + }; + ++struct ath11k_rx_peer_rate_stats { ++ u64 ht_mcs_count[HAL_RX_MAX_MCS_HT + 1]; ++ u64 vht_mcs_count[HAL_RX_MAX_MCS_VHT + 1]; ++ u64 he_mcs_count[HAL_RX_MAX_MCS_HE + 1]; ++ u64 nss_count[HAL_RX_MAX_NSS]; ++ u64 bw_count[HAL_RX_BW_MAX]; ++ u64 gi_count[HAL_RX_GI_MAX]; ++ u64 legacy_count[HAL_RX_MAX_NUM_LEGACY_RATES]; ++ u64 rx_rate[ATH11K_RX_RATE_TABLE_11AX_NUM]; ++}; ++ + struct ath11k_rx_peer_stats { + u64 num_msdu; + u64 num_mpdu_fcs_ok; +@@ -431,10 +444,6 @@ struct ath11k_rx_peer_stats { + u64 non_ampdu_msdu_count; + u64 stbc_count; + u64 beamformed_count; +- u64 mcs_count[HAL_RX_MAX_MCS + 1]; +- u64 nss_count[HAL_RX_MAX_NSS]; +- u64 bw_count[HAL_RX_BW_MAX]; +- u64 gi_count[HAL_RX_GI_MAX]; + 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 { + u64 rx_duration; + u64 dcm_count; + u64 ru_alloc_cnt[HAL_RX_RU_ALLOC_TYPE_MAX]; ++ struct ath11k_rx_peer_rate_stats pkt_stats; ++ struct ath11k_rx_peer_rate_stats byte_stats; + }; + + #define ATH11K_HE_MCS_NUM 12 +--- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c ++++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c +@@ -10,6 +10,7 @@ + #include "peer.h" + #include "debug.h" + #include "dp_tx.h" ++#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 + struct ath11k *ar = arsta->arvif->ar; + struct ath11k_rx_peer_stats *rx_stats = arsta->rx_stats; + int len = 0, i, retval = 0; +- const int size = 4096; ++ const int size = 4 * 4096; + char *buf; ++ int he_rates_avail = (rx_stats->pream_cnt[HAL_RX_PREAMBLE_11AX] > 1) ? 1 : 0; ++ int rate_table_len = he_rates_avail ? ATH11K_RX_RATE_TABLE_11AX_NUM : ++ ATH11K_RX_RATE_TABLE_NUM; ++ char *legacy_rate_str[] = {"1Mbps", "2Mbps", "5.5Mbps", "6Mbps", ++ "9Mbps", "11Mbps", "12Mbps", "18Mbps", ++ "24Mbps", "36 Mbps", "48Mbps", "54Mbps"}; + + if (!rx_stats) + return -ENOENT; +@@ -422,14 +429,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); +- len += scnprintf(buf + len, size - len, +- "GI: 0.8us %llu 0.4us %llu 1.6us %llu 3.2us %llu\n", +- rx_stats->gi_count[0], rx_stats->gi_count[1], +- rx_stats->gi_count[2], rx_stats->gi_count[3]); +- len += scnprintf(buf + len, size - len, +- "BW: 20Mhz %llu 40Mhz %llu 80Mhz %llu 160Mhz %llu\n", +- rx_stats->bw_count[0], rx_stats->bw_count[1], +- rx_stats->bw_count[2], rx_stats->bw_count[3]); + 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 + 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]); +- len += scnprintf(buf + len, size - len, "\nMCS(0-11) Legacy MCS(12):"); +- for (i = 0; i < HAL_RX_MAX_MCS + 1; i++) +- len += scnprintf(buf + len, size - len, "%llu ", rx_stats->mcs_count[i]); +- len += scnprintf(buf + len, size - len, "\nNSS(1-8):"); +- for (i = 0; i < HAL_RX_MAX_NSS; i++) +- len += scnprintf(buf + len, size - len, "%llu ", rx_stats->nss_count[i]); +- len += scnprintf(buf + len, size - len, "\nRX Duration:%llu ", ++ len += scnprintf(buf + len, size - len, "\nRX Duration:%llu\n", + rx_stats->rx_duration); ++ ++ len += scnprintf(buf + len, size - len, "\nRX success packet stats:\n"); ++ len += scnprintf(buf + len, size - len, "\nHE packet stats:\n"); ++ for (i = 0; i <= HAL_RX_MAX_MCS_HE; i++) ++ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, ++ rx_stats->pkt_stats.he_mcs_count[i], ++ (i + 1) % 6 ? "\t" : "\n"); ++ len += scnprintf(buf + len, size - len, "\nVHT packet stats:\n"); ++ for (i = 0; i <= HAL_RX_MAX_MCS_VHT; i++) ++ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, ++ rx_stats->pkt_stats.vht_mcs_count[i], ++ (i + 1) % 5 ? "\t" : "\n"); ++ len += scnprintf(buf + len, size - len, "\nHT packet stats:\n"); ++ for (i = 0; i <= HAL_RX_MAX_MCS_HT; i++) ++ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, ++ rx_stats->pkt_stats.ht_mcs_count[i], ++ (i + 1) % 8 ? "\t" : "\n"); ++ len += scnprintf(buf + len, size - len, "\nLegacy rate packet stats:\n"); ++ for (i = 0; i < HAL_RX_MAX_NUM_LEGACY_RATES; i++) ++ len += scnprintf(buf + len, size - len, "%s: %llu%s", legacy_rate_str[i], ++ rx_stats->pkt_stats.legacy_count[i], ++ (i + 1) % 4 ? "\t" : "\n"); ++ len += scnprintf(buf + len, size - len, "\nNSS packet stats:\n"); ++ for (i = 0; i < HAL_RX_MAX_NSS; i++) ++ len += scnprintf(buf + len, size - len, "%dx%d: %llu ", i + 1, i + 1, ++ rx_stats->pkt_stats.nss_count[i]); ++ len += scnprintf(buf + len, size - len, ++ "\n\nGI: 0.8us %llu 0.4us %llu 1.6us %llu 3.2us %llu\n", ++ rx_stats->pkt_stats.gi_count[0], ++ rx_stats->pkt_stats.gi_count[1], ++ rx_stats->pkt_stats.gi_count[2], ++ rx_stats->pkt_stats.gi_count[3]); ++ len += scnprintf(buf + len, size - len, ++ "BW: 20Mhz %llu 40Mhz %llu 80Mhz %llu 160Mhz %llu\n", ++ rx_stats->pkt_stats.bw_count[0], ++ rx_stats->pkt_stats.bw_count[1], ++ rx_stats->pkt_stats.bw_count[2], ++ rx_stats->pkt_stats.bw_count[3]); ++ len += scnprintf(buf + len, size - len, "\nRate Table (packets):\n"); ++ for (i = 0; i < rate_table_len; i++) ++ len += scnprintf(buf + len, size - len, "%10llu%s", ++ rx_stats->pkt_stats.rx_rate[i], ++ (i + 1) % (he_rates_avail ? 12 : 8) ? "\t" : "\n"); ++ ++ len += scnprintf(buf + len, size - len, "\nRX success byte stats:\n"); ++ len += scnprintf(buf + len, size - len, "\nHE byte stats:\n"); ++ for (i = 0; i <= HAL_RX_MAX_MCS_HE; i++) ++ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, ++ rx_stats->byte_stats.he_mcs_count[i], ++ (i + 1) % 6 ? "\t" : "\n"); ++ ++ len += scnprintf(buf + len, size - len, "\nVHT byte stats:\n"); ++ for (i = 0; i <= HAL_RX_MAX_MCS_VHT; i++) ++ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, ++ rx_stats->byte_stats.vht_mcs_count[i], ++ (i + 1) % 5 ? "\t" : "\n"); ++ len += scnprintf(buf + len, size - len, "\nHT byte stats:\n"); ++ for (i = 0; i <= HAL_RX_MAX_MCS_HT; i++) ++ len += scnprintf(buf + len, size - len, "MCS %d: %llu%s", i, ++ rx_stats->byte_stats.ht_mcs_count[i], ++ (i + 1) % 8 ? "\t" : "\n"); ++ len += scnprintf(buf + len, size - len, "\nLegacy rate byte stats:\n"); ++ for (i = 0; i < HAL_RX_MAX_NUM_LEGACY_RATES; i++) ++ len += scnprintf(buf + len, size - len, "%s: %llu%s", legacy_rate_str[i], ++ rx_stats->byte_stats.legacy_count[i], ++ (i + 1) % 4 ? "\t" : "\n"); ++ len += scnprintf(buf + len, size - len, "\nNSS byte stats:\n"); ++ for (i = 0; i < HAL_RX_MAX_NSS; i++) ++ len += scnprintf(buf + len, size - len, "%dx%d: %llu ", i + 1, i + 1, ++ rx_stats->byte_stats.nss_count[i]); ++ len += scnprintf(buf + len, size - len, ++ "\n\nGI: 0.8us %llu 0.4us %llu 1.6us %llu 3.2us %llu\n", ++ rx_stats->byte_stats.gi_count[0], ++ rx_stats->byte_stats.gi_count[1], ++ rx_stats->byte_stats.gi_count[2], ++ rx_stats->byte_stats.gi_count[3]); ++ len += scnprintf(buf + len, size - len, ++ "BW: 20Mhz %llu 40Mhz %llu 80Mhz %llu 160Mhz %llu\n", ++ rx_stats->byte_stats.bw_count[0], ++ rx_stats->byte_stats.bw_count[1], ++ rx_stats->byte_stats.bw_count[2], ++ rx_stats->byte_stats.bw_count[3]); ++ len += scnprintf(buf + len, size - len, "\nRate Table (bytes):\n"); ++ for (i = 0; i < rate_table_len; i++) ++ len += scnprintf(buf + len, size - len, "%10llu%s", ++ 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], +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -3400,10 +3400,43 @@ exit: + return total_msdu_reaped; + } + ++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, ++ u32 num_msdu) ++{ ++ u32 rate_idx = 0; ++ u32 mcs_idx = ppdu_info->mcs; ++ u32 nss_idx = ppdu_info->nss - 1; ++ u32 bw_idx = ppdu_info->bw; ++ u32 gi_idx = ppdu_info->gi; ++ ++ if ((mcs_idx > HAL_RX_MAX_MCS_HE) || (nss_idx >= HAL_RX_MAX_NSS) || ++ (bw_idx >= HAL_RX_BW_MAX) || (gi_idx >= HAL_RX_GI_MAX)) { ++ return; ++ } ++ ++ if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11N || ++ ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC) { ++ rate_idx = mcs_idx * 8 + 8 * 10 * nss_idx; ++ rate_idx += bw_idx * 2 + gi_idx; ++ } else if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AX) { ++ gi_idx = ath11k_he_gi_to_nl80211_he_gi(ppdu_info->gi); ++ rate_idx = mcs_idx * 12 + 12 * 12 * nss_idx; ++ rate_idx += bw_idx * 3 + gi_idx; ++ } else { ++ return; ++ } ++ ++ rx_stats->pkt_stats.rx_rate[rate_idx] += num_msdu; ++ rx_stats->byte_stats.rx_rate[rate_idx] += ppdu_info->mpdu_len; ++} ++ + static void ath11k_dp_rx_update_peer_stats(struct ath11k_sta *arsta, + struct hal_rx_mon_ppdu_info *ppdu_info) + { + struct ath11k_rx_peer_stats *rx_stats = arsta->rx_stats; ++ struct ath11k *ar = arsta->arvif->ar; + u32 num_msdu; + int i; + +@@ -3413,6 +3446,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); + ++ if (!ath11k_debugfs_is_extd_rx_stats_enabled(ar)) ++ return; + 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 + ppdu_info->tid = IEEE80211_NUM_TIDS; + } + +- if (ppdu_info->nss > 0 && ppdu_info->nss <= HAL_RX_MAX_NSS) +- rx_stats->nss_count[ppdu_info->nss - 1] += num_msdu; +- +- if (ppdu_info->mcs <= HAL_RX_MAX_MCS) +- rx_stats->mcs_count[ppdu_info->mcs] += num_msdu; +- +- if (ppdu_info->gi < HAL_RX_GI_MAX) +- rx_stats->gi_count[ppdu_info->gi] += num_msdu; +- +- if (ppdu_info->bw < HAL_RX_BW_MAX) +- rx_stats->bw_count[ppdu_info->bw] += num_msdu; +- + 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 + rx_stats->dcm_count += ppdu_info->dcm; + rx_stats->ru_alloc_cnt[ppdu_info->ru_alloc] += num_msdu; + +- arsta->rssi_comb = ppdu_info->rssi_comb; +- + 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 + + rx_stats->rx_duration += ppdu_info->rx_duration; + arsta->rx_duration = rx_stats->rx_duration; ++ ++ if (ppdu_info->nss > 0 && ppdu_info->nss <= HAL_RX_MAX_NSS) { ++ rx_stats->pkt_stats.nss_count[ppdu_info->nss - 1] += num_msdu; ++ rx_stats->byte_stats.nss_count[ppdu_info->nss - 1] += ppdu_info->mpdu_len; ++ } ++ ++ if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11N && ++ ppdu_info->mcs <= HAL_RX_MAX_MCS_HT) { ++ rx_stats->pkt_stats.ht_mcs_count[ppdu_info->mcs] += num_msdu; ++ rx_stats->byte_stats.ht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len; ++ /* To fit into rate table for HT packets */ ++ ppdu_info->mcs = ppdu_info->mcs % 8; ++ } ++ ++ if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC && ++ ppdu_info->mcs <= HAL_RX_MAX_MCS_VHT) { ++ rx_stats->pkt_stats.vht_mcs_count[ppdu_info->mcs] += num_msdu; ++ rx_stats->byte_stats.vht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len; ++ } ++ ++ if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AX && ++ ppdu_info->mcs <= HAL_RX_MAX_MCS_HE) { ++ rx_stats->pkt_stats.he_mcs_count[ppdu_info->mcs] += num_msdu; ++ rx_stats->byte_stats.he_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len; ++ } ++ ++ ++ if ((ppdu_info->preamble_type == HAL_RX_PREAMBLE_11A || ++ ppdu_info->preamble_type == HAL_RX_PREAMBLE_11B) && ++ ppdu_info->rate < HAL_RX_LEGACY_RATE_INVALID) { ++ rx_stats->pkt_stats.legacy_count[ppdu_info->rate] += num_msdu; ++ rx_stats->byte_stats.legacy_count[ppdu_info->rate] += ppdu_info->mpdu_len; ++ } ++ ++ if (ppdu_info->gi < HAL_RX_GI_MAX) { ++ rx_stats->pkt_stats.gi_count[ppdu_info->gi] += num_msdu; ++ rx_stats->byte_stats.gi_count[ppdu_info->gi] += ppdu_info->mpdu_len; ++ } ++ ++ if (ppdu_info->bw < HAL_RX_BW_MAX) { ++ rx_stats->pkt_stats.bw_count[ppdu_info->bw] += num_msdu; ++ rx_stats->byte_stats.bw_count[ppdu_info->bw] += ppdu_info->mpdu_len; ++ } ++ ++ ath11k_dp_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, num_msdu); ++ + } + + 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 { + __be16 snap_type; + } __packed; + ++static inline u32 ath11k_he_gi_to_nl80211_he_gi(u8 sgi) ++{ ++ u32 ret = 0; ++ ++ switch (sgi) { ++ case RX_MSDU_START_SGI_0_8_US: ++ ret = NL80211_RATE_INFO_HE_GI_0_8; ++ break; ++ case RX_MSDU_START_SGI_1_6_US: ++ ret = NL80211_RATE_INFO_HE_GI_1_6; ++ break; ++ case RX_MSDU_START_SGI_3_2_US: ++ ret = NL80211_RATE_INFO_HE_GI_3_2; ++ break; ++ } ++ ++ return ret; ++} ++ + int ath11k_dp_rx_ampdu_start(struct ath11k_vif *arvif, + struct ieee80211_ampdu_params *params); + int ath11k_dp_rx_ampdu_stop(struct ath11k_vif *arvif, +--- 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 + 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); +- ppdu_info->gi = info1 & HAL_RX_HT_SIG_INFO_INFO1_GI; +- +- switch (ppdu_info->mcs) { +- case 0 ... 7: +- ppdu_info->nss = 1; +- break; +- case 8 ... 15: +- ppdu_info->nss = 2; +- break; +- case 16 ... 23: +- ppdu_info->nss = 3; +- break; +- case 24 ... 31: +- ppdu_info->nss = 4; +- break; +- } +- +- if (ppdu_info->nss > 1) +- ppdu_info->mcs = ppdu_info->mcs % 8; +- ++ ppdu_info->gi = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO1_GI, info1); ++ ppdu_info->nss = (ppdu_info->mcs >> 3) + 1; + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; + break; + } + case HAL_PHYRX_L_SIG_B: { + struct hal_rx_lsig_b_info *lsigb = + (struct hal_rx_lsig_b_info *)tlv_data; ++ u8 rate; ++ ++ rate = FIELD_GET(HAL_RX_LSIG_B_INFO_INFO0_RATE, ++ __le32_to_cpu(lsigb->info0)); + +- ppdu_info->rate = FIELD_GET(HAL_RX_LSIG_B_INFO_INFO0_RATE, +- __le32_to_cpu(lsigb->info0)); ++ switch (rate) { ++ case 1: ++ rate = HAL_RX_LEGACY_RATE_1_MBPS; ++ break; ++ case 2: ++ case 5: ++ rate = HAL_RX_LEGACY_RATE_2_MBPS; ++ break; ++ case 3: ++ case 6: ++ rate = HAL_RX_LEGACY_RATE_5_5_MBPS; ++ break; ++ case 4: ++ case 7: ++ rate = HAL_RX_LEGACY_RATE_11_MBPS; ++ break; ++ default: ++ rate = HAL_RX_LEGACY_RATE_INVALID; ++ } ++ ppdu_info->rate = rate; + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; + break; + } + case HAL_PHYRX_L_SIG_A: { + struct hal_rx_lsig_a_info *lsiga = + (struct hal_rx_lsig_a_info *)tlv_data; ++ u8 rate; + +- ppdu_info->rate = FIELD_GET(HAL_RX_LSIG_A_INFO_INFO0_RATE, +- __le32_to_cpu(lsiga->info0)); ++ rate = FIELD_GET(HAL_RX_LSIG_A_INFO_INFO0_RATE, ++ __le32_to_cpu(lsiga->info0)); ++ switch (rate) { ++ case 8: ++ rate = HAL_RX_LEGACY_RATE_48_MBPS; ++ break; ++ case 9: ++ rate = HAL_RX_LEGACY_RATE_24_MBPS; ++ break; ++ case 10: ++ rate = HAL_RX_LEGACY_RATE_12_MBPS; ++ break; ++ case 11: ++ rate = HAL_RX_LEGACY_RATE_6_MBPS; ++ break; ++ case 12: ++ rate = HAL_RX_LEGACY_RATE_54_MBPS; ++ break; ++ case 13: ++ rate = HAL_RX_LEGACY_RATE_36_MBPS; ++ break; ++ case 14: ++ rate = HAL_RX_LEGACY_RATE_18_MBPS; ++ break; ++ case 15: ++ rate = HAL_RX_LEGACY_RATE_9_MBPS; ++ break; ++ default: ++ rate = HAL_RX_LEGACY_RATE_INVALID; ++ } ++ ppdu_info->rate = rate; + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; + break; + } +@@ -1473,6 +1507,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; ++ ++ ppdu_info->mpdu_len += ab->hw_params.hw_ops->rx_desc_get_hal_mpdu_len(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 +@@ -19,7 +19,11 @@ struct hal_rx_wbm_rel_info { + #define VHT_SIG_SU_NSS_MASK 0x7 + + #define HAL_RX_MAX_MCS 12 ++#define HAL_RX_MAX_MCS_HT 31 ++#define HAL_RX_MAX_MCS_VHT 9 ++#define HAL_RX_MAX_MCS_HE 11 + #define HAL_RX_MAX_NSS 8 ++#define HAL_RX_MAX_NUM_LEGACY_RATES 12 + + struct hal_rx_mon_status_tlv_hdr { + u32 hdr; +@@ -104,6 +108,22 @@ struct hal_rx_user_status { + u32 mpdu_err_byte_count; + }; + ++enum hal_rx_legacy_rate { ++ HAL_RX_LEGACY_RATE_1_MBPS, ++ HAL_RX_LEGACY_RATE_2_MBPS, ++ HAL_RX_LEGACY_RATE_5_5_MBPS, ++ HAL_RX_LEGACY_RATE_6_MBPS, ++ HAL_RX_LEGACY_RATE_9_MBPS, ++ HAL_RX_LEGACY_RATE_11_MBPS, ++ HAL_RX_LEGACY_RATE_12_MBPS, ++ HAL_RX_LEGACY_RATE_18_MBPS, ++ HAL_RX_LEGACY_RATE_24_MBPS, ++ HAL_RX_LEGACY_RATE_36_MBPS, ++ HAL_RX_LEGACY_RATE_48_MBPS, ++ HAL_RX_LEGACY_RATE_54_MBPS, ++ HAL_RX_LEGACY_RATE_INVALID, ++}; ++ + #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 { + u32 num_mpdu_fcs_ok; + u32 num_mpdu_fcs_err; + u32 preamble_type; ++ u32 mpdu_len; + u16 chan_num; + u16 tcp_msdu_count; + 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 + return skb_get_hash(skb); + } + ++static u32 ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len(struct hal_rx_mpdu_info *mpdu_info) ++{ ++ return FIELD_GET(HAL_RX_MPDU_INFO_INFO1_MPDU_LEN, ++ __le32_to_cpu(mpdu_info->u.ipq8074.info1)); ++} ++ ++static u32 ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_len(struct hal_rx_mpdu_info *mpdu_info) ++{ ++ return FIELD_GET(HAL_RX_MPDU_INFO_INFO1_MPDU_LEN, ++ __le32_to_cpu(mpdu_info->u.qcn9074.info1)); ++} + 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 = + .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 = + .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, + }; + + const struct ath11k_hw_ops qca6390_ops = { +@@ -1177,6 +1190,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, ++ .rx_desc_get_hal_mpdu_len = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len, + }; + + 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, + .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 = + .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, + }; + + #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 { + 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 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/ath11k_nss/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch new file mode 100644 index 00000000000000..e7908c6daad2a7 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch @@ -0,0 +1,452 @@ +--- 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 + len += scnprintf(buf + len, size - len, "%10llu%s", + rx_stats->byte_stats.rx_rate[i], + (i + 1) % (he_rates_avail ? 12 : 8) ? "\t" : "\n"); ++ len += scnprintf(buf + len, size - len, ++ "\nDCM: %llu\nRU26: %llu \nRU52: %llu \nRU106: %llu \nRU242: %llu \nRU484: %llu \nRU996: %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, + "\nDCM: %llu\nRU: 26 %llu 52: %llu 106: %llu 242: %llu 484: %llu 996: %llu\n", +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -3236,11 +3236,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, ++ struct hal_rx_user_status* user_stats, + u32 num_msdu) + { + u32 rate_idx = 0; +- u32 mcs_idx = ppdu_info->mcs; +- u32 nss_idx = ppdu_info->nss - 1; ++ u32 mcs_idx = (user_stats) ? user_stats->mcs : ppdu_info->mcs; ++ u32 nss_idx = (user_stats) ? user_stats->nss - 1 : ppdu_info->nss - 1; + u32 bw_idx = ppdu_info->bw; + u32 gi_idx = ppdu_info->gi; + +@@ -3262,10 +3263,13 @@ ath11k_dp_rx_update_peer_rate_table_stat + } + + rx_stats->pkt_stats.rx_rate[rate_idx] += num_msdu; +- rx_stats->byte_stats.rx_rate[rate_idx] += ppdu_info->mpdu_len; ++ if (user_stats) ++ rx_stats->byte_stats.rx_rate[rate_idx] += user_stats->mpdu_ok_byte_count; ++ else ++ rx_stats->byte_stats.rx_rate[rate_idx] += ppdu_info->mpdu_len; + } + +-static void ath11k_dp_rx_update_peer_stats(struct ath11k_sta *arsta, ++static void ath11k_dp_rx_update_peer_su_stats(struct ath11k_sta *arsta, + 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 + 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; +- rx_stats->ru_alloc_cnt[ppdu_info->ru_alloc] += num_msdu; + + 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 + + if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11N && + ppdu_info->mcs <= HAL_RX_MAX_MCS_HT) { +- rx_stats->pkt_stats.ht_mcs_count[ppdu_info->mcs] += num_msdu; +- rx_stats->byte_stats.ht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len; +- /* To fit into rate table for HT packets */ +- ppdu_info->mcs = ppdu_info->mcs % 8; ++ rx_stats->pkt_stats.ht_mcs_count[ppdu_info->mcs] += num_msdu; ++ rx_stats->byte_stats.ht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len; ++ /* To fit into rate table for HT packets */ ++ ppdu_info->mcs = ppdu_info->mcs % 8; + } + + if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC && +@@ -3377,7 +3380,120 @@ static void ath11k_dp_rx_update_peer_sta + rx_stats->byte_stats.bw_count[ppdu_info->bw] += ppdu_info->mpdu_len; + } + +- ath11k_dp_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, num_msdu); ++ ath11k_dp_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, NULL, num_msdu); ++ ++} ++ ++static void ath11k_dp_rx_update_user_stats(struct ath11k *ar, ++ struct hal_rx_mon_ppdu_info *ppdu_info, ++ u32 uid) ++{ ++ struct ath11k_sta *arsta = NULL; ++ struct ath11k_rx_peer_stats *rx_stats = NULL; ++ struct hal_rx_user_status* user_stats = &ppdu_info->userstats[uid]; ++ struct ath11k_peer *peer; ++ u32 num_msdu; ++ ++ if (user_stats->ast_index == 0 || user_stats->ast_index == 0xFFFF) ++ return; ++ ++ peer = ath11k_peer_find_by_ast(ar->ab, user_stats->ast_index); ++ ++ if (peer == NULL) { ++ ath11k_warn(ar->ab, "peer ast idx %d can't be found\n", ++ user_stats->ast_index); ++ return; ++ } ++ ++ arsta = (struct ath11k_sta *)peer->sta->drv_priv; ++ rx_stats = arsta->rx_stats; ++ ++ if (!rx_stats) ++ return; ++ ++ arsta->rssi_comb = ppdu_info->rssi_comb; ++ ++ num_msdu = user_stats->tcp_msdu_count + user_stats->tcp_ack_msdu_count + ++ user_stats->udp_msdu_count + user_stats->other_msdu_count; ++ ++ rx_stats->num_msdu += num_msdu; ++ rx_stats->tcp_msdu_count += user_stats->tcp_msdu_count + ++ user_stats->tcp_ack_msdu_count; ++ rx_stats->udp_msdu_count += user_stats->udp_msdu_count; ++ rx_stats->other_msdu_count += user_stats->other_msdu_count; ++ ++ if (ppdu_info->ldpc < HAL_RX_SU_MU_CODING_MAX) ++ rx_stats->coding_count[ppdu_info->ldpc] += num_msdu; ++ ++ if (user_stats->tid <= IEEE80211_NUM_TIDS) ++ rx_stats->tid_count[user_stats->tid] += num_msdu; ++ ++ if (user_stats->preamble_type < HAL_RX_PREAMBLE_MAX) ++ rx_stats->pream_cnt[user_stats->preamble_type] += num_msdu; ++ ++ if (ppdu_info->reception_type < HAL_RX_RECEPTION_TYPE_MAX) ++ rx_stats->reception_type[ppdu_info->reception_type] += num_msdu; ++ ++ if (ppdu_info->is_stbc) ++ rx_stats->stbc_count += num_msdu; ++ ++ if (ppdu_info->beamformed) ++ rx_stats->beamformed_count += num_msdu; ++ ++ if (user_stats->mpdu_cnt_fcs_ok > 1) ++ rx_stats->ampdu_msdu_count += num_msdu; ++ else ++ rx_stats->non_ampdu_msdu_count += num_msdu; ++ ++ rx_stats->num_mpdu_fcs_ok += user_stats->mpdu_cnt_fcs_ok; ++ rx_stats->num_mpdu_fcs_err += user_stats->mpdu_cnt_fcs_err; ++ rx_stats->dcm_count += ppdu_info->dcm; ++ if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA || ++ ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO) ++ rx_stats->ru_alloc_cnt[user_stats->ul_ofdma_ru_size] += num_msdu; ++ ++ rx_stats->rx_duration += ppdu_info->rx_duration; ++ arsta->rx_duration = rx_stats->rx_duration; ++ ++ if (user_stats->nss > 0 && user_stats->nss <= HAL_RX_MAX_NSS) { ++ rx_stats->pkt_stats.nss_count[user_stats->nss - 1] += num_msdu; ++ rx_stats->byte_stats.nss_count[user_stats->nss - 1] += user_stats->mpdu_ok_byte_count; ++ } ++ ++ if (user_stats->preamble_type == HAL_RX_PREAMBLE_11AX && ++ user_stats->mcs <= HAL_RX_MAX_MCS_HE) { ++ rx_stats->pkt_stats.he_mcs_count[user_stats->mcs] += num_msdu; ++ rx_stats->byte_stats.he_mcs_count[user_stats->mcs] += user_stats->mpdu_ok_byte_count; ++ } ++ ++ if (ppdu_info->gi < HAL_RX_GI_MAX) { ++ rx_stats->pkt_stats.gi_count[ppdu_info->gi] += num_msdu; ++ rx_stats->byte_stats.gi_count[ppdu_info->gi] += user_stats->mpdu_ok_byte_count; ++ } ++ ++ if (ppdu_info->bw < HAL_RX_BW_MAX) { ++ rx_stats->pkt_stats.bw_count[ppdu_info->bw] += num_msdu; ++ rx_stats->byte_stats.bw_count[ppdu_info->bw] += user_stats->mpdu_ok_byte_count; ++ } ++ ++ ath11k_dp_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, user_stats, num_msdu); ++} ++ ++static void ath11k_dp_rx_update_peer_mu_stats(struct ath11k *ar, ++ struct hal_rx_mon_ppdu_info *ppdu_info) ++{ ++ u32 num_users, i; ++ ++ if (!ath11k_debugfs_is_extd_rx_stats_enabled(ar)) ++ return; ++ ++ num_users = ppdu_info->num_users; ++ if (num_users > HAL_MAX_UL_MU_USERS) ++ num_users = HAL_MAX_UL_MU_USERS; ++ ++ for (i = 0; i < num_users; i++) { ++ ath11k_dp_rx_update_user_stats(ar, ppdu_info, i); ++ } + + } + +@@ -5846,6 +5962,55 @@ static void ath11k_dp_rx_mon_dest_proces + } + } + ++void ath11k_dp_rx_mon_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info) ++{ ++ struct hal_rx_user_status *rx_user_status; ++ u32 num_users; ++ uint32_t i; ++ uint32_t mu_ul_user_v0_word0; ++ uint32_t mu_ul_user_v0_word1; ++ uint32_t ru_size; ++ ++ if (!(ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA || ++ ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO)) ++ return; ++ ++ num_users = ppdu_info->num_users; ++ if (num_users > HAL_MAX_UL_MU_USERS) ++ num_users = HAL_MAX_UL_MU_USERS; ++ ++ for (i = 0; i < num_users; i++) { ++ rx_user_status = &ppdu_info->userstats[i]; ++ mu_ul_user_v0_word0 = ++ rx_user_status->ul_ofdma_user_v0_word0; ++ mu_ul_user_v0_word1 = ++ rx_user_status->ul_ofdma_user_v0_word1; ++ ++ if (FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID, ++ mu_ul_user_v0_word0) && ++ !FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VER, ++ mu_ul_user_v0_word0)) { ++ rx_user_status->mcs = ++ FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_MCS, ++ mu_ul_user_v0_word1); ++ rx_user_status->nss = ++ FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_NSS, ++ mu_ul_user_v0_word1) + 1; ++ ++ rx_user_status->ofdma_info_valid = 1; ++ rx_user_status->ul_ofdma_ru_start_index = ++ FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_START, ++ mu_ul_user_v0_word1); ++ ++ ru_size = FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE, ++ mu_ul_user_v0_word1); ++ rx_user_status->ul_ofdma_ru_width = ru_size; ++ rx_user_status->ul_ofdma_ru_size = ru_size; ++ } ++ } ++ ++} ++ + int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id, + struct napi_struct *napi, int budget) + { +@@ -5919,8 +6084,13 @@ int ath11k_dp_rx_process_mon_status(stru + + 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); ++ 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)) +--- a/drivers/net/wireless/ath/ath11k/hal_rx.c ++++ b/drivers/net/wireless/ath/ath11k/hal_rx.c +@@ -804,7 +804,6 @@ void ath11k_hal_reo_init_cmd_ring(struct + } + } + +-#define HAL_MAX_UL_MU_USERS 37 + static inline void + ath11k_hal_rx_handle_ofdma_info(void *rx_tlv, + struct hal_rx_user_status *rx_user_status) +@@ -836,6 +835,8 @@ ath11k_hal_rx_populate_mu_user_info(void + { + rx_user_status->ast_index = ppdu_info->ast_index; + rx_user_status->tid = ppdu_info->tid; ++ rx_user_status->tcp_ack_msdu_count = ++ ppdu_info->tcp_ack_msdu_count; + rx_user_status->tcp_msdu_count = + ppdu_info->tcp_msdu_count; + rx_user_status->udp_msdu_count = +@@ -859,6 +860,9 @@ ath11k_hal_rx_populate_mu_user_info(void + ppdu_info->num_mpdu_fcs_ok; + rx_user_status->mpdu_cnt_fcs_err = + ppdu_info->num_mpdu_fcs_err; ++ memcpy(&rx_user_status->mpdu_fcs_ok_bitmap[0], &ppdu_info->mpdu_fcs_ok_bitmap[0], ++ HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * ++ sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0])); + + ath11k_hal_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status); + } +@@ -888,6 +892,14 @@ ath11k_hal_rx_parse_mon_status_tlv(struc + __le32_to_cpu(ppdu_start->info0)); + ppdu_info->chan_num = __le32_to_cpu(ppdu_start->chan_num); + ppdu_info->ppdu_ts = __le32_to_cpu(ppdu_start->ppdu_start_ts); ++ ++ if (ppdu_info->ppdu_id != ppdu_info->last_ppdu_id) { ++ ppdu_info->last_ppdu_id = ppdu_info->ppdu_id; ++ ppdu_info->num_users = 0; ++ memset(&ppdu_info->mpdu_fcs_ok_bitmap, 0, ++ HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * ++ sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0])); ++ } + break; + } + case HAL_RX_PPDU_END_USER_STATS: { +@@ -942,15 +954,16 @@ ath11k_hal_rx_parse_mon_status_tlv(struc + + if (userid < HAL_MAX_UL_MU_USERS) { + struct hal_rx_user_status *rxuser_stats = +- &ppdu_info->userstats; ++ &ppdu_info->userstats[userid]; ++ ppdu_info->num_users += 1; + + ath11k_hal_rx_handle_ofdma_info(tlv_data, rxuser_stats); + ath11k_hal_rx_populate_mu_user_info(tlv_data, ppdu_info, + rxuser_stats); + } +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[0] = ++ ppdu_info->mpdu_fcs_ok_bitmap[0] = + __le32_to_cpu(eu_stats->rsvd1[0]); +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[1] = ++ ppdu_info->mpdu_fcs_ok_bitmap[1] = + __le32_to_cpu(eu_stats->rsvd1[1]); + + break; +@@ -958,12 +971,12 @@ ath11k_hal_rx_parse_mon_status_tlv(struc + case HAL_RX_PPDU_END_USER_STATS_EXT: { + struct hal_rx_ppdu_end_user_stats_ext *eu_stats = + (struct hal_rx_ppdu_end_user_stats_ext *)tlv_data; +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[2] = eu_stats->info1; +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[3] = eu_stats->info2; +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[4] = eu_stats->info3; +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[5] = eu_stats->info4; +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[6] = eu_stats->info5; +- ppdu_info->userstats.mpdu_fcs_ok_bitmap[7] = eu_stats->info6; ++ ppdu_info->mpdu_fcs_ok_bitmap[2] = eu_stats->info1; ++ ppdu_info->mpdu_fcs_ok_bitmap[3] = eu_stats->info2; ++ ppdu_info->mpdu_fcs_ok_bitmap[4] = eu_stats->info3; ++ ppdu_info->mpdu_fcs_ok_bitmap[5] = eu_stats->info4; ++ ppdu_info->mpdu_fcs_ok_bitmap[6] = eu_stats->info5; ++ ppdu_info->mpdu_fcs_ok_bitmap[7] = eu_stats->info6; + break; + } + case HAL_PHYRX_HT_SIG: { +--- a/drivers/net/wireless/ath/ath11k/hal_rx.h ++++ b/drivers/net/wireless/ath/ath11k/hal_rx.h +@@ -72,6 +72,10 @@ enum hal_rx_reception_type { + #define HAL_RX_FCS_LEN 4 + #define HAL_AST_IDX_INVALID 0xFFFF + ++#define HAL_MAX_UL_MU_USERS 37 ++#define HAL_RX_MAX_MPDU 256 ++#define HAL_RX_NUM_WORDS_PER_PPDU_BITMAP (HAL_RX_MAX_MPDU >> 5) ++ + enum hal_rx_mon_status { + HAL_RX_MON_STATUS_PPDU_NOT_DONE, + HAL_RX_MON_STATUS_PPDU_DONE, +@@ -82,14 +86,15 @@ struct hal_rx_user_status { + u32 mcs:4, + nss:3, + ofdma_info_valid:1, +- dl_ofdma_ru_start_index:7, +- dl_ofdma_ru_width:7, +- dl_ofdma_ru_size:8; ++ ul_ofdma_ru_start_index:7, ++ ul_ofdma_ru_width:7, ++ ul_ofdma_ru_size:8; + u32 ul_ofdma_user_v0_word0; + u32 ul_ofdma_user_v0_word1; + u32 ast_index; + u32 tid; + u16 tcp_msdu_count; ++ u16 tcp_ack_msdu_count; + u16 udp_msdu_count; + u16 other_msdu_count; + u16 frame_control; +@@ -103,7 +108,7 @@ struct hal_rx_user_status { + u8 rs_flags; + u32 mpdu_cnt_fcs_ok; + u32 mpdu_cnt_fcs_err; +- u32 mpdu_fcs_ok_bitmap[8]; ++ u32 mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP]; + u32 mpdu_ok_byte_count; + u32 mpdu_err_byte_count; + }; +@@ -144,6 +149,7 @@ struct hal_sw_mon_ring_entries { + + struct hal_rx_mon_ppdu_info { + u32 ppdu_id; ++ u32 last_ppdu_id; + u32 ppdu_ts; + u32 num_mpdu_fcs_ok; + u32 num_mpdu_fcs_err; +@@ -212,9 +218,20 @@ struct hal_rx_mon_ppdu_info { + u8 ltf_size; + u8 rxpcu_filter_pass; + char rssi_chain[8][8]; +- struct hal_rx_user_status userstats; ++ 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]; + }; + ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID BIT(30) ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VER BIT(31) ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_NSS GENMASK(2, 0) ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_MCS GENMASK(6, 3) ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_LDPC BIT(7) ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_DCM BIT(8) ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_START GENMASK(15, 9) ++#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE GENMASK(18, 16) ++ + #define HAL_RX_PPDU_START_INFO0_PPDU_ID GENMASK(15, 0) + + 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_ + return NULL; + } + ++struct ath11k_peer *ath11k_peer_find_by_ast(struct ath11k_base *ab, ++ int ast_hash) ++{ ++ struct ath11k_peer *peer; ++ ++ lockdep_assert_held(&ab->base_lock); ++ ++ list_for_each_entry(peer, &ab->peers, list) ++ if (ast_hash == peer->ast_hash) ++ return peer; ++ ++ 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, +--- 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 + 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); ++struct ath11k_peer *ath11k_peer_find_by_ast(struct ath11k_base *ab, int ast_hash); + void ath11k_peer_cleanup(struct ath11k *ar, u32 vdev_id); + int ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, u8 *addr); + int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, diff --git a/package/kernel/mac80211/patches/ath11k_nss/907-ath11k-remove-error-on-soc-debugfs-fail.patch b/package/kernel/mac80211/patches/ath11k_nss/907-ath11k-remove-error-on-soc-debugfs-fail.patch new file mode 100644 index 00000000000000..b47785828a2bd9 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/907-ath11k-remove-error-on-soc-debugfs-fail.patch @@ -0,0 +1,146 @@ +From 41363c3109235a96d90d5946bbc01d1cc8dad47e Mon Sep 17 00:00:00 2001 +From: Anilkumar Kolli +Date: Sun, 6 Sep 2020 11:01:38 +0530 +Subject: [PATCH] ath11k: update debugfs support for mupltiple radios in PCI +bus + +debugfs_ath11k struct is moved to ath11k_core, since its common +for both pci and ahb. + +Current ath11k_pci insmod fails if there are multiple PCI rdaios, +debugfs directory is created with soc_name and bus_id to allow +creating debugfs directory for second PCI radio. + +with this Debugfs entries looks like, + # ls -l /sys/kernel/debug/ath11k/ + ipq8074 hw2.0 qcn9000 hw1.0_0000:01:00.0 qcn9000 hw1.0_0001:01:00.0 + + # ls -l /sys/kernel/debug/ath11k/ipq8074 hw2.0/ + mac0 mac1 simulate_fw_crash soc_dp_stats + + # ls -l /sys/kernel/debug/ath11k/qcn9000 hw1.0_0000:01:00.0 + mac0 simulate_fw_crash soc_dp_stats + + # /sys/kernel/debug/ath11k/qcn9000 hw1.0_0001:01:00.0: + mac0 simulate_fw_crash soc_dp_stats + +Signed-off-by: Anilkumar Kolli +--- + drivers/net/wireless/ath/ath11k/core.c | 12 +++++++ + drivers/net/wireless/ath/ath11k/core.h | 1 - + drivers/net/wireless/ath/ath11k/debugfs.c | 57 ++++++++++++++++++++++++------ + drivers/net/wireless/ath/ath11k/debugfs.h | 11 ++++++ + 5 files changed, 72 insertions(+), 13 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -2260,5 +2260,17 @@ err_sc_free: + } + EXPORT_SYMBOL(ath11k_core_alloc); + ++int ath11k_init(void) ++{ ++ return ath11k_debugfs_create(); ++} ++module_init(ath11k_init); ++ ++void ath11k_exit(void) ++{ ++ ath11k_debugfs_destroy(); ++} ++module_exit(ath11k_exit); ++ + MODULE_DESCRIPTION("Core module for Qualcomm Atheros 802.11ax wireless LAN cards."); + 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 @@ + #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 + + void ath11k_debugfs_pdev_destroy(struct ath11k_base *ab) + { +- debugfs_remove_recursive(ab->debugfs_soc); +- ab->debugfs_soc = NULL; + } + + int ath11k_debugfs_soc_create(struct ath11k_base *ab) +@@ -1282,6 +1282,24 @@ void ath11k_debugfs_soc_destroy(struct a + } + EXPORT_SYMBOL(ath11k_debugfs_soc_destroy); + ++int ath11k_debugfs_create(void) ++{ ++ debugfs_ath11k = debugfs_create_dir("ath11k", NULL); ++ if (IS_ERR_OR_NULL(debugfs_ath11k)) { ++ if (IS_ERR(debugfs_ath11k)) ++ return PTR_ERR(debugfs_ath11k); ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++void ath11k_debugfs_destroy(void) ++{ ++ debugfs_remove_recursive(debugfs_ath11k); ++ debugfs_ath11k = NULL; ++} ++ + 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 + char pdev_name[10]; + char buf[100] = {0}; + ++ if (!(IS_ERR_OR_NULL(ar->debug.debugfs_pdev))) ++ return 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); +--- a/drivers/net/wireless/ath/ath11k/debugfs.h ++++ b/drivers/net/wireless/ath/ath11k/debugfs.h +@@ -282,6 +282,8 @@ do { \ + #endif + + #ifdef CPTCFG_ATH11K_DEBUGFS ++int ath11k_debugfs_create(void); ++void ath11k_debugfs_destroy(void); + 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 + } + + #else ++static inline int ath11k_debugfs_create(void) ++{ ++ return 0; ++} ++ ++static inline void ath11k_debugfs_destroy(void) ++{ ++} ++ + static inline int ath11k_debugfs_soc_create(struct ath11k_base *ab) + { + return 0; diff --git a/package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch b/package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch new file mode 100644 index 00000000000000..bba58322a254e7 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch @@ -0,0 +1,253 @@ +From 91df8aa674d2d4064ab22f47515c3fb126527208 Mon Sep 17 00:00:00 2001 +From: Karthikeyan Kathirvel +Date: Thu, 12 Nov 2020 15:02:56 +0530 +Subject: [PATCH] ath11k: NSS MCBC Exception added for STA + +Since NSS FW is not supporting PN check for MCBC pkts, those pkts are +excepted from NSS offload to pass through mac80211 PN check. + +Signed-off-by: Karthikeyan Kathirvel +Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 +--- + drivers/net/wireless/ath/ath11k/nss.c | 128 +++++++++++++++++++++ + drivers/net/wireless/ath/ath11k/nss.h | 51 ++++---- + 2 files changed, 153 insertions(+), 26 deletions(-) + create mode 100644 mac80211/patches/301-ath11k-nss-mcbc-exception.patch + +--- 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 + + static void ath11k_nss_wds_type_rx(struct ath11k *ar, struct net_device *dev, + u8* src_mac, u8 is_sa_valid, u8 addr4_valid, +- u16 peer_id, bool *drop) ++ u16 peer_id) + { + 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 + } + } + +- if (!ta_peer->nss.ext_vdev_up) +- *drop = true; + } + + spin_unlock_bh(&ab->base_lock); +@@ -692,8 +690,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, +- struct nss_wifi_vdev_wds_per_packet_metadata *wds_metadata, +- bool *drop) ++ struct nss_wifi_vdev_wds_per_packet_metadata *wds_metadata) + { + struct ath11k *ar = arvif->ar; + struct ath11k_base *ab = ar->ab; +@@ -715,7 +712,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, +- addr4_valid, peer_id, drop); ++ addr4_valid, peer_id); + 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; + 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 ath11k_peer *ta_peer = NULL; + + if (!dev) { + dev_kfree_skb_any(skb); +@@ -834,15 +833,50 @@ ath11k_nss_vdev_special_data_receive(str + return; + } + +- if (eth_decap && wifi_metadata->pkt_type == +- 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, +- wds_metadata, &drop); +- } ++ switch(wifi_metadata->pkt_type) { ++ case NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_WDS_LEARN: ++ if (eth_decap) { ++ wds_metadata = &wifi_metadata->metadata.wds_metadata; ++ ath11k_nss_vdev_spl_receive_ext_wdsdata(arvif, skb, ++ wds_metadata); ++ } ++ dev_kfree_skb_any(skb); ++ break; ++ case NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_MCBC_RX: ++ ath11k_dbg_dump(ab, ATH11K_DBG_DP_RX, "", ++ "mcbc packet exception from nss: ", ++ 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_4ADDR: ++ if (eth_decap) { ++ addr4_metadata = &wifi_metadata->metadata.addr4_metadata; ++ ++ spin_lock_bh(&ab->base_lock); ++ ta_peer = ath11k_peer_find_by_id(ab, addr4_metadata->peer_id); ++ if (!ta_peer) { ++ spin_unlock_bh(&ab->base_lock); ++ dev_kfree_skb_any(skb); ++ return; ++ } + +- if (!drop) +- ath11k_nss_deliver_rx(arvif->vif, skb, eth_decap, data_offs, napi); ++ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, "4addr exception ta_peer %pM\n", ++ ta_peer->addr); ++ if (!ta_peer->nss.ext_vdev_up && addr4_metadata->addr4_valid) ++ ieee80211_rx_nss_notify_4addr(dev, ta_peer->addr); ++ spin_unlock_bh(&ab->base_lock); ++ } ++ dev_kfree_skb_any(skb); ++ break; ++ default: ++ ath11k_warn(ab, "unsupported pkt_type %d from nss\n", wifi_metadata->pkt_type); ++ dev_kfree_skb_any(skb); ++ } + } + + static void +@@ -1049,6 +1083,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; ++ case ATH11K_NSS_WIFI_VDEV_CFG_MCBC_EXC_TO_HOST_CMD: ++ cmd = NSS_WIFI_VDEV_CFG_MCBC_EXC_TO_HOST_CMD; ++ break; + default: + return -EINVAL; + } +@@ -1299,12 +1336,31 @@ int ath11k_nss_vdev_create(struct ath11k + goto free_vdev; + + switch (arvif->vif->type) { +- case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_STATION: + ret = ath11k_nss_vdev_configure(arvif); + if (ret) + goto unregister_vdev; + ++ ret = ath11k_nss_vdev_set_cmd(arvif, ++ ATH11K_NSS_WIFI_VDEV_CFG_MCBC_EXC_TO_HOST_CMD, ++ ATH11K_NSS_ENABLE_MCBC_EXC); ++ if (ret) { ++ ath11k_err(ab, "failed to set MCBC in nss %d\n", ret); ++ goto unregister_vdev; ++ } ++ break; ++ case NL80211_IFTYPE_AP: ++ ret = ath11k_nss_vdev_configure(arvif); ++ if (ret) ++ goto unregister_vdev; ++ ++ ret = ath11k_nss_vdev_set_cmd(arvif, ++ ATH11K_NSS_WIFI_VDEV_CFG_WDS_BACKHAUL_CMD, ++ true); ++ if (ret) { ++ ath11k_warn(ab, "failed to cfg wds backhaul in nss %d\n", ret); ++ 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( + { + struct ath11k *ar = arvif->ar; + struct ath11k_base *ab = ar->ab; +- nss_tx_status_t status; + 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( + + if (!arvif->nss.ctx) { + ath11k_warn(ab, "failed to register nss vdev if_num %d nss_err:%d\n", +- arvif->nss.if_num, status); ++ arvif->nss.if_num, NSS_TX_FAILURE); + return -EINVAL; + } + +--- 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 { + 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/ath11k_nss/908-330-ath11k-sync-wds_ast_entry-updates.patch b/package/kernel/mac80211/patches/ath11k_nss/908-330-ath11k-sync-wds_ast_entry-updates.patch new file mode 100644 index 00000000000000..6ebd709e7d3298 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/908-330-ath11k-sync-wds_ast_entry-updates.patch @@ -0,0 +1,522 @@ +From 9e1f28f343347774b01f330d76d2c5323fcd07ae Mon Sep 17 00:00:00 2001 +From: Rameshkumar Sundaram +Date: Fri, 24 Sep 2021 18:25:08 +0530 +Subject: [PATCH] ath11k: sync wds ast entry on peer/entry deletions + +Peer specific ast entries list is shared between +peer_unmap_event(softirq) and peer_ast_wds_wmi_wk +(worker). The worker sends a WMI command and hence tends to +sleep. +complete_work_sync() is used in peer_unmap_event bh handler +which tries to yield the CPU(calls schedule) +until the worker completes. This results kernel reporting +schedule in atomic context and system crash. +Add new global wmi_ast_list and add all ast add/update +work to this list. +Add a new global wmi_ast_work and queue this +work on each entry to global wmi_ast_list list. +Process the wmi_ast_list in worker and send updates +to FW. +Each ast entry node is shared between global wmi_ast list +and peer specific ast_list and deletes will be done +in sync between two lists. +On peer deletion all the peer specific entries will +be deleted from wmi_ast_list and peer delete in progress +will be set to avoid new ast entries adding up and therefore +peer unmap evnt won't find any ast worker in progress +entries to free in irq context. +This peer ast cleanup and worker processing same entry +will be synchronized with new base_ast_lock mutex. +FW indpendently Deleting a single wds ast entry in irq context & +worker already processing the same cannot be synchronized. +As we can't hold bh scheduling while worker tries to sleep, +and entry in scheduled update work will be sent to FW. + +Signed-off-by: Rameshkumar Sundaram +--- + drivers/net/wireless/ath/ath11k/ahb.c | 1 + + drivers/net/wireless/ath/ath11k/core.c | 3 + + drivers/net/wireless/ath/ath11k/core.h | 4 + + drivers/net/wireless/ath/ath11k/nss.c | 6 +- + drivers/net/wireless/ath/ath11k/nss.h | 8 +- + drivers/net/wireless/ath/ath11k/pci.c | 1 + + drivers/net/wireless/ath/ath11k/peer.c | 172 ++++++++++++++++++++++++--------- + drivers/net/wireless/ath/ath11k/peer.h | 3 +- + 8 files changed, 144 insertions(+), 54 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/ahb.c ++++ b/drivers/net/wireless/ath/ath11k/ahb.c +@@ -1245,6 +1245,7 @@ static void ath11k_ahb_remove_prepare(st + set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags); + cancel_work_sync(&ab->restart_work); + cancel_work_sync(&ab->qmi.event_work); ++ cancel_work_sync(&ab->wmi_ast_work); + } + + 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 + + mutex_init(&ab->core_lock); + mutex_init(&ab->tbl_mtx_lock); ++ mutex_init(&ab->base_ast_lock); + 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 + 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); ++ INIT_WORK(&ab->wmi_ast_work, ath11k_peer_ast_wds_wmi_wk); ++ INIT_LIST_HEAD(&ab->wmi_ast_list); + timer_setup(&ab->rx_replenish_retry, ath11k_ce_rx_replenish_retry, 0); + init_completion(&ab->htc_suspend); + 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 @@ + #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 { + + 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; ++ + /* 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 + spin_unlock_bh(&ab->base_lock); + } + +-static void ath11k_nss_mec_handler(struct ath11k *ar, u8* mec_mac_addr) ++static void ath11k_nss_mec_handler(struct ath11k_vif *arvif, u8* mec_mac_addr) + { ++ struct ath11k *ar = arvif->ar; + 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 + memcpy(mac_addr, mac_addr_h16, ETH_ALEN - 4); + memcpy(mac_addr + 2, mac_addr_l32, 4); + +- if (!ether_addr_equal(ar->mac_addr, mac_addr)) { ++ if (!ether_addr_equal(arvif->vif->addr, mac_addr)) { + 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_ + addr4_valid, peer_id); + break; + case NSS_WIFI_VDEV_WDS_TYPE_MEC: +- ath11k_nss_mec_handler(ar, (u8 *)(skb->data)); ++ ath11k_nss_mec_handler(arvif, (u8 *)(skb->data)); + break; + default: + ath11k_warn(ab, "unsupported wds_type %d\n", wds_type); +@@ -3848,11 +3849,7 @@ int ath11k_nss_add_wds_peer(struct ath11 + wds_peer_msg->ast_type = type; + wds_peer_msg->peer_id = peer->peer_id; + +- if (type == ATH11K_AST_TYPE_MEC) +- ether_addr_copy(wds_peer_msg->peer_mac, ar->mac_addr); +- else +- ether_addr_copy(wds_peer_msg->peer_mac, peer->addr); +- ++ ether_addr_copy(wds_peer_msg->peer_mac, peer->addr); + 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: + return ret; + } + +-int ath11k_nss_del_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, ++int ath11k_nss_del_wds_peer(struct ath11k *ar, u8 *peer_addr, int peer_id, + u8 *dest_mac) + { + struct ath11k_base *ab = ar->ab; +@@ -3993,8 +3990,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; +- wds_peer_msg->peer_id = peer->peer_id; +- ether_addr_copy(wds_peer_msg->peer_mac, peer->addr); ++ wds_peer_msg->peer_id = peer_id; ++ ether_addr_copy(wds_peer_msg->peer_mac, peer_addr); + ether_addr_copy(wds_peer_msg->dest_mac, dest_mac); + + 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 + 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); +-int ath11k_nss_del_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, +- u8 *dest_mac); ++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, + 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 + return 0; + } + +-static inline int ath11k_nss_del_wds_peer(struct ath11k_vif *arvif, struct ath11k_peer *peer, +- u8 *dest_mac) ++static inline int ath11k_nss_del_wds_peer(struct ath11k *ar, u8 *peer_addr, ++ int peer_id, u8 *dest_mac) + { + return 0; + } +--- 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 + } + + set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags); ++ cancel_work_sync(&ab->wmi_ast_work); + + ath11k_core_deinit(ab); + +--- a/drivers/net/wireless/ath/ath11k/peer.c ++++ b/drivers/net/wireless/ath/ath11k/peer.c +@@ -160,49 +160,68 @@ struct ath11k_ast_entry *ath11k_peer_ast + + void ath11k_peer_ast_wds_wmi_wk(struct work_struct *wk) + { +- struct ath11k_ast_entry *ast_entry = container_of(wk, +- struct ath11k_ast_entry, +- wds_wmi_wk); +- struct ath11k *ar; ++ struct ath11k_ast_entry *ast_entry, *entry; ++ struct ath11k_base *ab = container_of(wk, struct ath11k_base, wmi_ast_work); + struct ath11k_peer *peer; ++ struct ath11k *ar; + int ret; ++ u8 peer_addr[ETH_ALEN]; ++ int peer_id; + +- if (!ast_entry) +- return; ++ ast_entry = kzalloc(sizeof(*ast_entry), GFP_ATOMIC); + +- ar = ast_entry->ar; +- peer = ast_entry->peer; ++ mutex_lock(&ab->base_ast_lock); ++ spin_lock_bh(&ab->base_lock); ++ ++ while ((entry = list_first_entry_or_null(&ab->wmi_ast_list, ++ struct ath11k_ast_entry, wmi_list))) { ++ list_del_init(&entry->wmi_list); + +- ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "ath11k_peer_ast_wds_wmi_wk action %d ast_entry %pM next_node %pM vdev %d\n", +- ast_entry->action, ast_entry->addr, ast_entry->next_node_mac, +- ast_entry->vdev_id); +- +- if (ast_entry->action == ATH11K_WDS_WMI_ADD) { +- ret = ath11k_wmi_send_add_update_wds_entry_cmd(ar, +- ast_entry->next_node_mac, +- ast_entry->addr, +- ast_entry->vdev_id, +- true); +- if (ret) { +- ath11k_warn(ar->ab, "add wds_entry_cmd failed %d for %pM next_node %pM\n", +- ret, ast_entry->addr, +- ast_entry->next_node_mac); +- if (peer) +- ath11k_nss_del_wds_peer(ar, peer, +- ast_entry->addr); ++ if (!entry->ar || (entry->peer && entry->peer->delete_in_progress)) { ++ continue; + } +- } else if (ast_entry->action == ATH11K_WDS_WMI_UPDATE) { +- if (!peer) +- return; ++ memcpy(ast_entry, entry, sizeof(*ast_entry)); ++ ar = ast_entry->ar; ++ peer = ast_entry->peer; ++ memcpy(peer_addr, peer->addr, sizeof(peer_addr)); ++ peer_id = peer->peer_id; ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, ++ "ath11k_peer_ast_wds_wmi_wk action %d ast_entry %pM peer %pM vdev %d\n", ++ ast_entry->action, ast_entry->addr, peer_addr, ++ ast_entry->vdev_id); + +- ret = ath11k_wmi_send_add_update_wds_entry_cmd(ar, peer->addr, +- ast_entry->addr, +- ast_entry->vdev_id, +- false); +- if (ret) +- ath11k_warn(ar->ab, "update wds_entry_cmd failed %d for %pM on peer %pM\n", +- ret, ast_entry->addr, peer->addr); ++ if (ast_entry->action == ATH11K_WDS_WMI_ADD) { ++ spin_unlock_bh(&ab->base_lock); ++ ret = ath11k_wmi_send_add_update_wds_entry_cmd(ar, peer_addr, ++ ast_entry->addr, ++ ast_entry->vdev_id, ++ true); ++ if (ret) { ++ ath11k_warn(ar->ab, "add wds_entry_cmd failed %d for %pM, peer %pM\n", ++ ret, ast_entry->addr, peer_addr); ++ if (peer) ++ ath11k_nss_del_wds_peer(ar, peer_addr, peer_id, ++ ast_entry->addr); ++ } ++ } else if (ast_entry->action == ATH11K_WDS_WMI_UPDATE) { ++ if (!peer) { ++ continue; ++ } ++ spin_unlock_bh(&ab->base_lock); ++ ret = ath11k_wmi_send_add_update_wds_entry_cmd(ar, peer_addr, ++ ast_entry->addr, ++ ast_entry->vdev_id, ++ false); ++ if (ret) ++ ath11k_warn(ar->ab, "update wds_entry_cmd failed %d for %pM on peer %pM\n", ++ ret, ast_entry->addr, peer_addr); ++ } ++ spin_lock_bh(&ab->base_lock); + } ++ spin_unlock_bh(&ab->base_lock); ++ mutex_unlock(&ab->base_ast_lock); ++ kfree(ast_entry); + } + + int ath11k_peer_add_ast(struct ath11k *ar, struct ath11k_peer *peer, +@@ -211,6 +230,8 @@ int ath11k_peer_add_ast(struct ath11k *a + struct ath11k_ast_entry *ast_entry = NULL; + struct ath11k_base *ab = ar->ab; + ++ lockdep_assert_held(&ab->base_lock); ++ + if (ab->num_ast_entries == ab->max_ast_index) { + ath11k_warn(ab, "failed to add ast for %pM due to insufficient ast entry resource %d in target\n", + mac_addr, ab->max_ast_index); +@@ -226,6 +247,9 @@ int ath11k_peer_add_ast(struct ath11k *a + } + } + ++ if (peer && peer->delete_in_progress) ++ return -EINVAL; ++ + ast_entry = kzalloc(sizeof(*ast_entry), GFP_ATOMIC); + if (!ast_entry) { + ath11k_warn(ab, "failed to alloc ast_entry for %pM\n", +@@ -257,7 +281,7 @@ int ath11k_peer_add_ast(struct ath11k *a + } + + INIT_LIST_HEAD(&ast_entry->ase_list); +- INIT_WORK(&ast_entry->wds_wmi_wk, ath11k_peer_ast_wds_wmi_wk); ++ INIT_LIST_HEAD(&ast_entry->wmi_list); + ast_entry->vdev_id = peer->vdev_id; + ast_entry->pdev_idx = peer->pdev_idx; + ast_entry->is_mapped = false; +@@ -271,16 +295,12 @@ int ath11k_peer_add_ast(struct ath11k *a + ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_add_ast peer %pM ast_entry %pM, ast_type %d\n", + peer->addr, mac_addr, ast_entry->type); + +- if (type == ATH11K_AST_TYPE_MEC) +- ether_addr_copy(ast_entry->next_node_mac, ar->mac_addr); +- else if (type == ATH11K_AST_TYPE_WDS) +- ether_addr_copy(ast_entry->next_node_mac, peer->addr); +- + if ((ast_entry->type == ATH11K_AST_TYPE_WDS) || + (ast_entry->type == ATH11K_AST_TYPE_MEC)) { + ath11k_nss_add_wds_peer(ar, peer, mac_addr, ast_entry->type); + ast_entry->action = ATH11K_WDS_WMI_ADD; +- ieee80211_queue_work(ar->hw, &ast_entry->wds_wmi_wk); ++ list_add_tail(&ast_entry->wmi_list, &ab->wmi_ast_list); ++ ieee80211_queue_work(ar->hw, &ab->wmi_ast_work); + } + + ab->num_ast_entries++; +@@ -293,6 +313,8 @@ int ath11k_peer_update_ast(struct ath11k + struct ath11k_peer *old_peer = ast_entry->peer; + struct ath11k_base *ab = ar->ab; + ++ lockdep_assert_held(&ab->base_lock); ++ + if (!ast_entry->is_mapped) { + ath11k_warn(ab, "ath11k_peer_update_ast: ast_entry %pM not mapped yet\n", + ast_entry->addr); +@@ -305,6 +327,9 @@ int ath11k_peer_update_ast(struct ath11k + (ast_entry->is_active)) + return 0; + ++ if (peer && peer->delete_in_progress) ++ return -EINVAL; ++ + ast_entry->vdev_id = peer->vdev_id; + ast_entry->pdev_idx = peer->pdev_idx; + ast_entry->type = ATH11K_AST_TYPE_WDS; +@@ -317,7 +342,14 @@ int ath11k_peer_update_ast(struct ath11k + old_peer->addr, peer->addr, ast_entry->addr); + + ast_entry->action = ATH11K_WDS_WMI_UPDATE; +- ieee80211_queue_work(ar->hw, &ast_entry->wds_wmi_wk); ++ ++ /* wmi_list entry might've been processed & removed.*/ ++ if (list_empty(&ast_entry->wmi_list)) ++ list_add_tail(&ast_entry->wmi_list, &ab->wmi_ast_list); ++ else ++ list_move_tail(&ast_entry->wmi_list, &ab->wmi_ast_list); ++ ++ ieee80211_queue_work(ar->hw, &ab->wmi_ast_work); + + return 0; + } +@@ -363,16 +395,23 @@ void ath11k_peer_del_ast(struct ath11k * + ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_del_ast pdev:%d peer %pM ast_entry %pM\n", + ar->pdev->pdev_id, peer->addr, ast_entry->addr); + +- if (ast_entry->is_mapped) +- list_del(&ast_entry->ase_list); ++ if ((ast_entry->type == ATH11K_AST_TYPE_WDS) || ++ (ast_entry->type == ATH11K_AST_TYPE_MEC)) { ++ if (!list_empty(&ast_entry->wmi_list)) { ++ ath11k_dbg(ab, ATH11K_DBG_MAC, ++ "ath11k_peer_del_ast deleting unprocessed ast entry %pM " ++ "of peer %pM from wmi list\n", ast_entry->addr, peer->addr); ++ list_del_init(&ast_entry->wmi_list); ++ } ++ } ++ list_del(&ast_entry->ase_list); + + /* WDS, MEC type AST entries need to be deleted on NSS */ + if (ast_entry->next_hop) +- ath11k_nss_del_wds_peer(ar, peer, ast_entry->addr); ++ ath11k_nss_del_wds_peer(ar, peer->addr, peer->peer_id, ++ ast_entry->addr); + +- cancel_work_sync(&ast_entry->wds_wmi_wk); + kfree(ast_entry); +- + ab->num_ast_entries--; + } + +@@ -681,6 +720,10 @@ void ath11k_peer_cleanup(struct ath11k * + + lockdep_assert_held(&ar->conf_mutex); + ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ mutex_lock(&ab->base_ast_lock); ++#endif ++ + mutex_lock(&ab->tbl_mtx_lock); + spin_lock_bh(&ab->base_lock); + list_for_each_entry_safe(peer, tmp_peer, &ab->peers, list) { +@@ -709,6 +752,9 @@ void ath11k_peer_cleanup(struct ath11k * + + spin_unlock_bh(&ab->base_lock); + mutex_unlock(&ab->tbl_mtx_lock); ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ mutex_unlock(&ab->base_ast_lock); ++#endif + } + + static int ath11k_wait_for_peer_deleted(struct ath11k *ar, int vdev_id, const u8 *addr) +@@ -743,12 +789,18 @@ static int __ath11k_peer_delete(struct a + int ret; + struct ath11k_peer *peer; + struct ath11k_base *ab = ar->ab; ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ struct ath11k_ast_entry *ast_entry, *tmp_ast; ++#endif + + lockdep_assert_held(&ar->conf_mutex); + + reinit_completion(&ar->peer_delete_done); + ath11k_nss_peer_delete(ar->ab, vdev_id, addr); + ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ mutex_lock(&ab->base_ast_lock); ++#endif + mutex_lock(&ab->tbl_mtx_lock); + spin_lock_bh(&ab->base_lock); + +@@ -771,17 +823,35 @@ static int __ath11k_peer_delete(struct a + return -EINVAL; + } + +- /* Check if the found peer is what we want to remove. +- * While the sta is transitioning to another band we may +- * have 2 peer with the same addr assigned to different +- * vdev_id. Make sure we are deleting the correct peer. +- */ +- if (peer && peer->vdev_id == vdev_id) ++ if (peer) { ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ peer->delete_in_progress = true; ++ if (peer->self_ast_entry) { ++ ath11k_peer_del_ast(ar, peer->self_ast_entry); ++ peer->self_ast_entry = NULL; ++ } ++ ++ list_for_each_entry_safe(ast_entry, tmp_ast, ++ &peer->ast_entry_list, ase_list) ++ if ((ast_entry->type == ATH11K_AST_TYPE_WDS) || ++ (ast_entry->type == ATH11K_AST_TYPE_MEC)) { ++ if (!list_empty(&ast_entry->wmi_list)) { ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, ++ "%s deleting unprocessed ast entry %pM of peer %pM from wmi list\n", ++ __func__, ast_entry->addr, addr); ++ list_del_init(&ast_entry->wmi_list); ++ } ++ } ++#endif + ath11k_peer_rhash_delete(ab, peer); ++ } + + spin_unlock_bh(&ab->base_lock); + mutex_unlock(&ab->tbl_mtx_lock); + ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ mutex_unlock(&ab->base_ast_lock); ++#endif + + ret = ath11k_wmi_send_peer_delete_cmd(ar, addr, vdev_id); + 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 { + struct ath11k_ast_entry { + u16 ast_idx; + u8 addr[ETH_ALEN]; +- u8 next_node_mac[ETH_ALEN]; + enum ath11k_wds_wmi_action action; +- struct work_struct wds_wmi_wk; + struct ath11k_peer *peer; + struct ath11k *ar; + bool next_hop; +@@ -47,6 +45,7 @@ struct ath11k_ast_entry { + 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 { + bool dp_setup_done; + struct ppdu_user_delayba ppdu_stats_delayba; + bool delayba_flag; ++ bool delete_in_progress; + }; + + void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id); 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/ath11k_nss/908-362-ath11k-fix-incorrect-ast-index-assignment-for-wds-peer.patch new file mode 100644 index 00000000000000..f734c5aea8d876 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/908-362-ath11k-fix-incorrect-ast-index-assignment-for-wds-peer.patch @@ -0,0 +1,96 @@ +From 396176575be9767a79d451fba4fe2931305f0435 Mon Sep 17 00:00:00 2001 +From: Raj Kumar Bhagat +Date: Mon, 7 Nov 2022 21:49:20 +0530 +Subject: [PATCH] ath11k: fix incorrect ast index assignment for wds peer + +Currently, same ast index is assigned for different nss wds peer mac +addresses which is incorrect. However, firmware provides the correct +and different ast index for different mac addresses. + +Hence, fix this issue by assigning the correct ast index provided by +the firmware. + +Signed-off-by: Raj Kumar Bhagat +--- + drivers/net/wireless/ath/ath11k/nss.c | 5 +++-- + drivers/net/wireless/ath/ath11k/nss.h | 6 ++++-- + drivers/net/wireless/ath/ath11k/peer.c | 3 +-- + 3 files changed, 8 insertions(+), 6 deletions(-) + +--- 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: + } + + int ath11k_nss_map_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, +- u8 *dest_mac, enum ath11k_ast_entry_type type) ++ u8 *dest_mac, struct ath11k_ast_entry *ast_entry) + { + struct ath11k_base *ab = ar->ab; + struct nss_wifili_wds_peer_map_msg *wds_peer_map_msg; + struct nss_wifili_msg *wlmsg = NULL; + nss_wifili_msg_callback_t msg_cb; + nss_tx_status_t status; ++ enum ath11k_ast_entry_type type = ast_entry->type; + int ret = 0; + + wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); +@@ -2503,7 +2502,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; +- wds_peer_map_msg->ast_idx = peer->hw_peer_id; ++ wds_peer_map_msg->ast_idx = ast_entry->ast_idx; + + if (type == ATH11K_AST_TYPE_MEC) + 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; + struct ath11k_base; + struct ath11k_vif; + struct ath11k_peer; ++struct ath11k_ast_entry; + 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 + 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, +- u8 *dest_mac, enum ath11k_ast_entry_type type); ++ u8 *dest_mac, struct ath11k_ast_entry *ast_entry); + 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_ + } + + static inline int ath11k_nss_map_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, +- u8 *dest_mac, int type) ++ u8 *dest_mac, ++ struct ath11k_ast_entry *ast_entry) + { + return 0; + } +--- a/drivers/net/wireless/ath/ath11k/peer.c ++++ b/drivers/net/wireless/ath/ath11k/peer.c +@@ -373,8 +373,7 @@ void ath11k_peer_map_ast(struct ath11k * + + if ((ast_entry->type == ATH11K_AST_TYPE_WDS) || + (ast_entry->type == ATH11K_AST_TYPE_MEC)) +- ath11k_nss_map_wds_peer(ar, peer, mac_addr, +- ast_entry->type); ++ ath11k_nss_map_wds_peer(ar, peer, mac_addr, ast_entry); + + ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_map_ast peer %pM ast_entry %pM\n", + peer->addr, ast_entry->addr); From 8200da1f26d93a00996bece0d105d87d1442cf8b Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 13 Jan 2024 17:13:16 -0500 Subject: [PATCH 202/225] ath11k_nss: fix `'ppdu_info' is a pointer...` error --- ...ul-ofdma-ru-allocation-in-peer-stats.patch | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) 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/ath11k_nss/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch index e7908c6daad2a7..9be70411b10996 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/ath11k_nss/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch @@ -247,19 +247,20 @@ int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id, struct napi_struct *napi, int budget) { -@@ -5919,8 +6084,13 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -5917,10 +6082,13 @@ int ath11k_dp_rx_process_mon_status(stru + goto next_skb; + } - if ((ppdu_info->fc_valid) && - (ppdu_info->ast_index != HAL_AST_IDX_INVALID)) { -- arsta = (struct ath11k_sta *)peer->sta->drv_priv; +- 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; - ath11k_dp_rx_update_peer_stats(arsta, 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); -+ } ++ 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 (ath11k_debugfs_is_pktlog_peer_valid(ar, peer->addr)) From e81a85f43a68a59101dbafb1b4d63400b47309a0 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Tue, 16 Jan 2024 18:45:18 -0500 Subject: [PATCH 203/225] ath11k_nss: bugfix NSS memleak + enhancements bugfixes: * Rreverted patch `105-ath11k-fix-monitor-crash-if-tx-offload-is-enabled.patch`. Initial test show lower memory use. `ieee80211_tx_status_8023` was also removed upstream for a reason as it wasn't being used, and the logic behind it was flawed. See https://patchwork.kernel.org/project/linux-wireless/patch/20230308174703.12270-2-quic_pradeepc@quicinc.com * Mmemory profile for '256M' was missing logic that was in 512/1G. Should build correctly now * added more qsdk related patches to nss/offload ath11k_nss: fix up patches ath11k_nss: revert m3, fix coredump when rebooting M3 SSR dump logic makes the router coredump. Just putting dummy case to skip warning. [12394.072384] Hardware name: Dynalink DL-WRX36 (DT) [12394.079758] Call trace: [12394.084354] dump_backtrace.part.0+0xbc/0xd0 [12394.086614] show_stack+0x18/0x30 [12394.091127] dump_stack_lvl+0x6c/0x88 [12394.094339] dump_stack+0x18/0x34 [12394.097985] bad_page+0xe0/0x110 [12394.101282] __free_pages_ok+0x33c/0x360 [12394.104582] __free_pages+0xbc/0xe0 [12394.108487] dma_direct_free+0xd0/0x140 [12394.111701] dma_free_attrs+0x90/0xb0 [12394.115519] ath11k_qmi_fwreset_from_cold_boot+0x9e0/0xa10 [ath11k] [12394.119343] ath11k_qmi_deinit_service+0x64/0x21d0 [ath11k] [12394.125419] ath11k_core_deinit+0xa4/0xc0 [ath11k] [12394.130974] 0xffffffc000fb3600 [12394.135831] platform_shutdown+0x24/0x40 [12394.138871] device_shutdown+0x14c/0x240 [12394.143037] kernel_restart+0x40/0xb0 [12394.146944] __do_sys_reboot+0xcc/0x200 [12394.150502] __arm64_sys_reboot+0x24/0x30 [12394.154148] invoke_syscall.constprop.0+0x5c/0x110 [12394.158317] do_el0_svc+0x58/0x170 [12394.163001] el0_svc+0x18/0x60 [12394.166386] el0t_64_sync_handler+0x114/0x120 [12394.169426] el0t_64_sync+0x174/0x178 --- ...nitor-crash-if-tx-offload-is-enabled.patch | 60 -- .../199-001-mac80211-add-nss-support.patch | 8 - ...-ath11k_nss-add-nss-driver-interface.patch | 4 +- .../199-003-ath11k-add-nss-support.patch | 6 +- ...-ath11k-Add-support-for-dynamic-vlan.patch | 6 +- ...207-ath11k-Enable-256_512MB-profiles.patch | 29 +- ...00-mac80211-nss-mesh-offload-support.patch | 2 +- .../patches/ath11k_nss/900-fix-build.patch | 46 -- ...load-changes-to-NSS-driver-interface.patch | 19 +- ...04-300-ath11k-nss_get_arvif_from_dev.patch | 4 +- ...support-to-send-the-QoS-Null-Data-fr.patch | 31 + .../906-ath11k-m3-ssr-dump-collection.patch | 12 + .../908-301-ath11k-nss-mcbc-exception.patch | 6 +- .../911-244-ath11k-dp-tx-perf.patch | 623 ++++++++++++++++++ ...-0001-ath11k-optimize-tx-completions.patch | 269 ++++++++ ...se-DECLARE_BITMAP-for-idr-operations.patch | 288 ++++++++ ...1k-add-simple-tx-handler-for-AP-mode.patch | 185 ++++++ .../911-335-ath11k-fix-ar-ops-crash.patch | 71 ++ ...Add-retry-mechanism-for-update_rx_qu.patch | 384 +++++++++++ ...rt-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch | 52 ++ ...-frags-from-uninitialized-peer-in-dp.patch | 74 +++ ...356-ath11k-invalid-desc-sanity-check.patch | 74 +++ ...k-skb_headroom-before-using-skb_push.patch | 209 ++++++ ...fix-RCU-stall-in-mesh-fast-xmit-path.patch | 120 ++++ ...ix-crash-when-accessing-null-pointer.patch | 87 +++ ...ing-memset-of-ppdu-info-for-next-skb.patch | 87 +++ 26 files changed, 2590 insertions(+), 166 deletions(-) delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/105-ath11k-fix-monitor-crash-if-tx-offload-is-enabled.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/906-456-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/906-ath11k-m3-ssr-dump-collection.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/911-244-ath11k-dp-tx-perf.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/911-335-0001-ath11k-optimize-tx-completions.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/911-335-0002-ath11k-use-DECLARE_BITMAP-for-idr-operations.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/911-335-0006-ath11k-add-simple-tx-handler-for-AP-mode.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/911-335-ath11k-fix-ar-ops-crash.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/913-341-ath11k-fix-support-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/913-353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/913-356-ath11k-invalid-desc-sanity-check.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/913-374-ath11k-Check-skb_headroom-before-using-skb_push.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/913-686-mac80211-fix-RCU-stall-in-mesh-fast-xmit-path.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/913-726-mac80211-fix-crash-when-accessing-null-pointer.patch create mode 100644 package/kernel/mac80211/patches/ath11k_nss/913-830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/105-ath11k-fix-monitor-crash-if-tx-offload-is-enabled.patch b/package/kernel/mac80211/patches/ath11k_nss/105-ath11k-fix-monitor-crash-if-tx-offload-is-enabled.patch deleted file mode 100644 index 9304833c87d1c3..00000000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/105-ath11k-fix-monitor-crash-if-tx-offload-is-enabled.patch +++ /dev/null @@ -1,60 +0,0 @@ - drivers/net/wireless/ath/ath11k/dp_tx.c | 20 +++++++++++++++++--- - 1 file changed, 17 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/ath/ath11k/dp_tx.c -+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -@@ -322,6 +322,8 @@ ath11k_dp_tx_htt_tx_complete_buf(struct - struct ath11k_skb_cb *skb_cb; - struct ath11k *ar; - struct ath11k_peer *peer; -+ struct ieee80211_vif *vif; -+ u8 flags = 0; - - spin_lock(&tx_ring->tx_idr_lock); - msdu = idr_remove(&tx_ring->txbuf_idr, ts->msdu_id); -@@ -348,6 +350,14 @@ ath11k_dp_tx_htt_tx_complete_buf(struct - return; - } - -+ if (!skb_cb->vif) { -+ dev_kfree_skb_any(msdu); -+ return; -+ } -+ -+ flags = skb_cb->flags; -+ vif = skb_cb->vif; -+ - memset(&info->status, 0, sizeof(info->status)); - - if (ts->acked) { -@@ -555,6 +565,8 @@ static void ath11k_dp_tx_complete_msdu(s - struct ath11k_peer *peer; - struct ath11k_sta *arsta; - struct rate_info rate; -+ struct ieee80211_vif *vif; -+ u8 flags = 0; - - if (WARN_ON_ONCE(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) { - /* Must not happen */ -@@ -575,6 +587,9 @@ static void ath11k_dp_tx_complete_msdu(s - return; - } - -+ flags = skb_cb->flags; -+ vif = skb_cb->vif; -+ - info = IEEE80211_SKB_CB(msdu); - memset(&info->status, 0, sizeof(info->status)); - -@@ -641,7 +656,10 @@ static void ath11k_dp_tx_complete_msdu(s - - spin_unlock_bh(&ab->base_lock); - -- ieee80211_tx_status_ext(ar->hw, &status); -+ if (flags & ATH11K_SKB_HW_80211_ENCAP) -+ ieee80211_tx_status_8023(ar->hw, vif, msdu); -+ else -+ ieee80211_tx_status_ext(ar->hw, &status); - } - - static inline void ath11k_dp_tx_status_parse(struct ath11k_base *ab, diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch b/package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch index f25def295537ca..a06ef7652df538 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch @@ -451,11 +451,3 @@ Signed-off-by: Sriram R QCOM_AOSS_QMP= QCOM_COMMAND_DB= QCOM_CPR= -@@ -174,6 +175,7 @@ ATH11K_DEBUGFS= - ATH11K_TRACING= - ATH11K_SPECTRAL= - ATH11K_THERMAL= -+ATH11K_MEM_PROFILE_512M= - ATH12K= - ATH12K_DEBUG= - ATH12K_TRACING= diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch b/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch index beee16098f14c3..79f8190d5b990f 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch @@ -600,8 +600,8 @@ Signed-off-by: Sriram R + __attribute__((unused)) struct napi_struct *napi) +{ + enum ath11k_hw_txrx_mode decap_type; -+ struct wireless_dev *wdev; -+ struct ieee80211_vif *vif; ++ struct wireless_dev *wdev = NULL; ++ struct ieee80211_vif *vif = NULL; + struct ath11k_vif *arvif; + struct ath11k_base *ab; + bool eth_decap = false; diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch b/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch index ffae0a9448ef8b..34b30984ca76d2 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch @@ -557,15 +557,13 @@ Signed-off-by: Sriram R exit: mutex_unlock(&ar->conf_mutex); return ret; -@@ -6216,10 +6279,16 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6216,10 +6279,14 @@ static void ath11k_mac_op_tx(struct ieee if (control->sta) arsta = ath11k_sta_to_arsta(control->sta); - ret = ath11k_dp_tx(ar, arvif, arsta, skb); -+ if (ar->ab->nss.enabled) { -+ arvif->ar->ab->nss.debug_mode = true; ++ if (ar->ab->nss.enabled) + ret = ath11k_nss_tx(arvif, skb); -+ } + else + ret = ath11k_dp_tx(ar, arvif, arsta, skb); if (unlikely(ret)) { diff --git a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch index b17b9fb419745d..a937ffba79961c 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch @@ -150,9 +150,9 @@ Signed-off-by: Seevalamuthu Mariappan spin_lock_bh(&tx_ring->tx_idr_lock); idr_remove(&tx_ring->txbuf_idr, FIELD_GET(DP_TX_DESC_ID_MSDU_ID, ti.desc_id)); -@@ -358,6 +429,9 @@ ath11k_dp_tx_htt_tx_complete_buf(struct - flags = skb_cb->flags; - vif = skb_cb->vif; +@@ -348,6 +419,9 @@ 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 */ diff --git a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch index a4c063ce69ba49..4d7af8641311dc 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch @@ -50,11 +50,11 @@ Signed-off-by: Ramya Gnanasekar /* Target configuration defines */ +#if defined(CPTCFG_ATH11K_MEM_PROFILE_256M) -+#define TARGET_NUM_VDEVS 8 -+#define TARGET_NUM_PEERS_PDEV (128 + TARGET_NUM_VDEVS) ++#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 128 -+#define ATH11K_QMI_TARGET_MEM_MODE ATH11K_QMI_TARGET_MEM_MODE_512M ++#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 @@ -138,7 +138,7 @@ Signed-off-by: Ramya Gnanasekar #endif --- a/local-symbols +++ b/local-symbols -@@ -171,12 +171,13 @@ ATH11K= +@@ -171,6 +171,8 @@ ATH11K= ATH11K_AHB= ATH11K_PCI= ATH11K_NSS_SUPPORT= @@ -147,12 +147,6 @@ Signed-off-by: Ramya Gnanasekar ATH11K_DEBUG= ATH11K_DEBUGFS= ATH11K_TRACING= - ATH11K_SPECTRAL= - ATH11K_THERMAL= --ATH11K_MEM_PROFILE_512M= - ATH12K= - ATH12K_DEBUG= - ATH12K_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 { @@ -282,17 +276,16 @@ Signed-off-by: Ramya Gnanasekar .hal_params = &ath11k_hw_hal_params_ipq8074, .supports_dynamic_smps_6ghz = false, .alloc_cacheable_memory = true, -@@ -127,7 +131,9 @@ static struct ath11k_hw_params ath11k_hw +@@ -127,6 +131,9 @@ 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, - .name = "ipq6018 hw1.0", @@ -177,7 +183,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = true, .coldboot_cal_ftm = true, @@ -374,13 +367,7 @@ Signed-off-by: Ramya Gnanasekar --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c -@@ -1592,10 +1592,13 @@ static ssize_t ath11k_dump_mgmt_stats(st - size_t count, loff_t *ppos) - { - struct ath11k *ar = file->private_data; -+#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M -+ struct ath11k_base *ab = ar->ab; -+#endif +@@ -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; diff --git a/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch b/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch index 7233913ee6f0f7..d3e6b9850b620f 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch @@ -187,7 +187,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran + u32 metric; + unsigned long exp_time; + u8 hop_count; -+ u16 flags; /* See &enum ieee80211_mesh_path_flags */ ++ u8 flags; /* See &enum ieee80211_mesh_path_flags */ + u8 mesh_gate; + u8 block_mesh_fwd; + u8 metadata_type; diff --git a/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch b/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch index 180fb7feab2e49..12feacda8555f7 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch @@ -104,19 +104,6 @@ NL80211_CMD_COLOR_CHANGE_COMPLETED, 0, 0); } ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -5241,6 +5241,10 @@ void ieee80211_tx_status_ext(struct ieee - * (NULL for multicast packets) - * @info: tx status information - */ -+void ieee80211_tx_status_8023(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ struct sk_buff *skb); -+ - static inline void ieee80211_tx_status_noskb(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, - struct ieee80211_tx_info *info) --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -4777,7 +4777,7 @@ void ieee80211_color_collision_detection @@ -160,39 +147,6 @@ /* now keys can no longer be reached */ ieee80211_free_sta_keys(local, sta); ---- a/net/mac80211/status.c -+++ b/net/mac80211/status.c -@@ -1244,6 +1244,30 @@ void ieee80211_tx_rate_update(struct iee - } - EXPORT_SYMBOL(ieee80211_tx_rate_update); - -+void ieee80211_tx_status_8023(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ struct sk_buff *skb) -+{ -+ struct ieee80211_sub_if_data *sdata; -+ struct ieee80211_tx_status status = { -+ .skb = skb, -+ .info = IEEE80211_SKB_CB(skb), -+ }; -+ struct sta_info *sta; -+ -+ sdata = vif_to_sdata(vif); -+ -+ rcu_read_lock(); -+ -+ if (!ieee80211_lookup_ra_sta(sdata, skb, &sta) && !IS_ERR(sta)) -+ status.sta = &sta->sta; -+ -+ ieee80211_tx_status_ext(hw, &status); -+ -+ rcu_read_unlock(); -+} -+EXPORT_SYMBOL(ieee80211_tx_status_8023); -+ - void ieee80211_report_low_ack(struct ieee80211_sta *pubsta, u32 num_packets) - { - struct sta_info *sta = container_of(pubsta, struct sta_info, sta); --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -19414,7 +19414,7 @@ void cfg80211_ch_switch_started_notify(s 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/ath11k_nss/902-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch index 7e2a9f0ee4dd4b..47146c459e796e 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/ath11k_nss/902-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch @@ -13,20 +13,7 @@ Signed-off-by: Sathishkumar Muruganandam --- a/drivers/net/wireless/ath/ath11k/nss.c +++ b/drivers/net/wireless/ath/ath11k/nss.c -@@ -9,10 +9,12 @@ - #include "nss.h" - #include "core.h" - #include "peer.h" -+#include "dp_tx.h" - #include "dp_rx.h" - #include "dp_tx.h" - #include "hif.h" - #include "wmi.h" -+#include "wmi.h" - #include "../../../../../net/mac80211/sta_info.h" - - /*-----------------------------ATH11K-NSS Helpers--------------------------*/ -@@ -348,6 +350,22 @@ void ath11k_nss_wifili_event_receive(str +@@ -348,6 +348,22 @@ void ath11k_nss_wifili_event_receive(str ath11k_nss_wifili_link_desc_return(ab, (void *)&msg->msg.linkdescinfomsg); break; @@ -301,8 +288,8 @@ Signed-off-by: Sathishkumar Muruganandam __attribute__((unused)) struct napi_struct *napi) { - enum ath11k_hw_txrx_mode decap_type; - struct wireless_dev *wdev; - struct ieee80211_vif *vif; + 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_ ath11k_dbg_dump(ab, ATH11K_DBG_DP_RX, "", "dp rx msdu from nss: ", 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 index 5d695ccfe55f2e..86812a1830d817 100644 --- 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 @@ -85,9 +85,9 @@ Signed-off-by: Vasanthakumar Thiagarajan break; } } -@@ -786,24 +814,7 @@ ath11k_nss_vdev_special_data_receive(str +@@ -785,24 +813,7 @@ ath11k_nss_vdev_special_data_receive(str + int data_offs = 0; int ret = 0; - struct ath11k_peer *ta_peer = NULL; - if (!dev) { - dev_kfree_skb_any(skb); 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/ath11k_nss/906-456-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch new file mode 100644 index 00000000000000..10c39288094b5f --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/906-456-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch @@ -0,0 +1,31 @@ +From 047c8f3ea16fe1d071f83b51b8c132f797903c91 Mon Sep 17 00:00:00 2001 +From: Karthikeyan Periyasamy +Date: Tue, 10 Oct 2023 09:13:38 +0530 +Subject: [PATCH] wifi: ath11k: Add support to send the QoS Null Data frame + through exception path + +When we try to send QoS NULL Data frame in Ethernet encap type, it modified +as QoS Data frame with TID 0 (encryption enabled one if security enabled). +But expectation is, it should be send as open type frame with TID 7 since +its a QoS NULL data frame. + +Added this frame under exception route to bypass TCL with the help of FW. + +Signed-off-by: Karthikeyan Periyasamy +--- + drivers/net/wireless/ath/ath11k/dp_tx.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- 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: + + 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))) + is_diff_encap = true; + else + ath11k_dp_tx_encap_nwifi(skb); diff --git a/package/kernel/mac80211/patches/ath11k_nss/906-ath11k-m3-ssr-dump-collection.patch b/package/kernel/mac80211/patches/ath11k_nss/906-ath11k-m3-ssr-dump-collection.patch new file mode 100644 index 00000000000000..47b29fd19e19bb --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/906-ath11k-m3-ssr-dump-collection.patch @@ -0,0 +1,12 @@ +--- 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_ + ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type; + idx++; + break; ++ case M3_DUMP_REGION_TYPE: ++ idx++; ++ break; + default: + ath11k_warn(ab, "qmi ignore invalid mem req type %d\n", + ab->qmi.target_mem[i].type); diff --git a/package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch b/package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch index bba58322a254e7..47c6b7ec3e5ae2 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch +++ b/package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch @@ -69,9 +69,9 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 int ret = 0; + struct ath11k_peer *ta_peer = NULL; - if (!dev) { - dev_kfree_skb_any(skb); -@@ -834,15 +833,50 @@ ath11k_nss_vdev_special_data_receive(str + arvif = ath11k_nss_get_arvif_from_dev(dev); + if (!arvif) { +@@ -843,15 +842,50 @@ ath11k_nss_vdev_special_data_receive(str return; } diff --git a/package/kernel/mac80211/patches/ath11k_nss/911-244-ath11k-dp-tx-perf.patch b/package/kernel/mac80211/patches/ath11k_nss/911-244-ath11k-dp-tx-perf.patch new file mode 100644 index 00000000000000..79906c8d3a4ab3 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/911-244-ath11k-dp-tx-perf.patch @@ -0,0 +1,623 @@ +From a19b1279d75dd1306c6eac291e985657f988780c Mon Sep 17 00:00:00 2001 +From: P Praneesh +Date: Thu, 7 Jan 2021 16:32:30 +0530 +Subject: [PATCH] ath11k: dp_tx perf improvements + + Contains below changes, + 1. Add branch prediction in tx path + 2. Allow fast tx completion by freeing skb when stats is disabled. + 3. Remove mod operator overhead for dst ring access to avoid(to be profiled) + 4. Lockless tcl ring usage since rings are selected per cpu + +Sample stats disable command: +echo 1 > /sys/kernel/debug/ath11k/qcn9000\ hw1.0_0000\:01\:00.0/stats_disable +echo 1 > /sys/kernel/debug/ath11k/ipq8074\ hw2.0/stats_disable + +Signed-off-by: Sriram R +Signed-off-by: P Praneesh +--- + drivers/net/wireless/ath/ath11k/core.h | 1 + + drivers/net/wireless/ath/ath11k/dp.c | 7 +- + drivers/net/wireless/ath/ath11k/dp_tx.c | 118 ++++++++++++++++++-------------- + drivers/net/wireless/ath/ath11k/dp_tx.h | 2 + + drivers/net/wireless/ath/ath11k/hal.c | 9 ++- + drivers/net/wireless/ath/ath11k/mac.c | 9 ++- + 6 files changed, 88 insertions(+), 58 deletions(-) + +--- 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_ + enum ath11k_skb_flags { + ATH11K_SKB_HW_80211_ENCAP = BIT(0), + ATH11K_SKB_CIPHER_SET = BIT(1), ++ ATH11K_SKB_TX_STATUS = BIT(2), + }; + + struct ath11k_skb_cb { +@@ -919,7 +920,12 @@ struct ath11k_soc_dp_tx_err_stats { + /* 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 */ + 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 + if (!ab->hw_params.supports_shadow_regs) + return; + +- for (i = 0; i < ab->hw_params.max_tx_ring; i++) ++ for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) + 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 + 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); +- for (i = 0; i < ab->hw_params.max_tx_ring; i++) { ++ 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); + } +@@ -411,6 +411,11 @@ static int ath11k_dp_srng_common_setup(s + goto err; + } + ++ if (ab->hw_params.max_tx_ring > DP_TCL_NUM_RING_MAX) { ++ srng = &ab->hal.srng_list[dp->tcl_cmd_ring.ring_id]; ++ ath11k_hal_tx_init_data_ring(ab, srng, HAL_TCL_CMD); ++ } ++ + 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 + goto err; + } + +- for (i = 0; i < ab->hw_params.max_tx_ring; i++) { ++ for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { + 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 + } + + srng = &ab->hal.srng_list[dp->tx_ring[i].tcl_data_ring.ring_id]; +- ath11k_hal_tx_init_data_ring(ab, srng); ++ ath11k_hal_tx_init_data_ring(ab, srng, HAL_TCL_DATA); + + 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 * + + ath11k_dp_reo_cmd_list_cleanup(ab); + +- for (i = 0; i < ab->hw_params.max_tx_ring; i++) { ++ for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { + 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 * + + size = sizeof(struct hal_wbm_release_ring) * DP_TX_COMP_RING_SIZE; + +- for (i = 0; i < ab->hw_params.max_tx_ring; i++) { ++ for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { + idr_init(&dp->tx_ring[i].txbuf_idr); + spin_lock_init(&dp->tx_ring[i].tx_idr_lock); + 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 + u32 ring_selector = 0; + u8 ring_map = 0; + bool tcl_ring_retry, is_diff_encap = false; +- u8 align_pad, htt_meta_size = 0; +- +- if (unlikely(test_bit(ATH11K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags))) +- return -ESHUTDOWN; ++ u8 align_pad, htt_meta_size = 0, max_tx_ring, tcl_ring_id, ring_id; + + if (unlikely(!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && + !ieee80211_is_data(hdr->frame_control))) + return -ENOTSUPP; + +- ring_selector = ab->hw_params.hw_ops->get_ring_selector(skb); ++ max_tx_ring = ab->hw_params.max_tx_ring; ++ ++#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); ++ return -ENOSPC; ++ } ++#endif ++ ring_selector = smp_processor_id();; + pool_id = ring_selector; + + tcl_ring_sel: + tcl_ring_retry = false; + +- ti.ring_id = ring_selector % ab->hw_params.max_tx_ring; +- ti.rbm_id = ab->hw_params.hal_params->tcl2wbm_rbm_map[ti.ring_id].rbm_id; ++ 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; + +- ring_map |= BIT(ti.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: + spin_unlock_bh(&tx_ring->tx_idr_lock); + + if (unlikely(ret < 0)) { +- if (ring_map == (BIT(ab->hw_params.max_tx_ring) - 1) || ++ if (ring_map == (BIT(max_tx_ring) - 1) || + !ab->hw_params.tcl_ring_retry) { +- atomic_inc(&ab->soc_stats.tx_err.misc_fail); ++ ab->soc_stats.tx_err.idr_na[tcl_ring_id]++; + return -ENOSPC; + } + +@@ -260,6 +268,11 @@ tcl_ring_sel: + ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN; + } + ++ ti.data_len = skb->len - ti.pkt_offset; ++ skb_cb->pkt_offset = ti.pkt_offset; ++ skb_cb->vif = arvif->vif; ++ skb_cb->ar = ar; ++ + 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: + goto fail_remove_idr; + } + +- ti.data_len = skb->len - ti.pkt_offset; +- skb_cb->pkt_offset = ti.pkt_offset; + skb_cb->paddr = ti.paddr; +- skb_cb->vif = arvif->vif; +- skb_cb->ar = ar; + +- hal_ring_id = tx_ring->tcl_data_ring.ring_id; ++ if (ring_id == DP_TCL_NUM_RING_MAX) ++ hal_ring_id = dp->tcl_cmd_ring.ring_id; ++ else ++ 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); +@@ -287,7 +300,7 @@ tcl_ring_sel: + * desc because the desc is directly enqueued onto hw queue. + */ + ath11k_hal_srng_access_end(ab, tcl_ring); +- ab->soc_stats.tx_err.desc_na[ti.ring_id]++; ++ ab->soc_stats.tx_err.desc_na[tcl_ring_id]++; + spin_unlock_bh(&tcl_ring->lock); + ret = -ENOMEM; + +@@ -296,8 +309,8 @@ tcl_ring_sel: + * checking this ring earlier for each pkt tx. + * Restart ring selection if some rings are not checked yet. + */ +- if (unlikely(ring_map != (BIT(ab->hw_params.max_tx_ring)) - 1) && +- ab->hw_params.tcl_ring_retry && ab->hw_params.max_tx_ring > 1) { ++ if (unlikely(ring_map != (BIT(max_tx_ring)) - 1) && ++ ab->hw_params.tcl_ring_retry && max_tx_ring > 1) { + tcl_ring_retry = true; + ring_selector++; + } +@@ -308,17 +321,17 @@ tcl_ring_sel: + ath11k_hal_tx_cmd_desc_setup(ab, hal_tcl_desc + + sizeof(struct hal_tlv_hdr), &ti); + ++ atomic_inc(&ar->dp.num_tx_pending); ++ atomic_inc(&ab->num_max_allowed); + ath11k_hal_srng_access_end(ab, tcl_ring); + +- ath11k_dp_shadow_start_timer(ab, tcl_ring, &dp->tx_ring_timer[ti.ring_id]); ++ ath11k_dp_shadow_start_timer(ab, tcl_ring, &dp->tx_ring_timer[ti.buf_id]); + + spin_unlock_bh(&tcl_ring->lock); + + ath11k_dbg_dump(ab, ATH11K_DBG_DP_TX, NULL, "dp tx msdu: ", + skb->data, skb->len); + +- atomic_inc(&ar->dp.num_tx_pending); +- atomic_inc(&ab->num_max_allowed); + + return 0; + +@@ -365,7 +378,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); +- atomic_dec(&ab->num_max_allowed); + } + + static void +@@ -379,6 +391,7 @@ ath11k_dp_tx_htt_tx_complete_buf(struct + struct ath11k_skb_cb *skb_cb; + struct ath11k *ar; + struct ath11k_peer *peer; ++ u8 flags = 0; + + 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 + + if (atomic_dec_and_test(&ar->dp.num_tx_pending)) + wake_up(&ar->dp.tx_empty_waitq); +- atomic_dec(&ab->num_max_allowed); + + dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); + ++ flags = skb_cb->flags; ++ ++ /* Free skb here if stats is disabled */ ++ if (ab->stats_disable && !(flags & ATH11K_SKB_TX_STATUS)) { ++ if (msdu->destructor) { ++ msdu->wifi_acked_valid = 1; ++ msdu->wifi_acked = ts->acked; ++ } ++ if (skb_has_frag_list(msdu)) { ++ kfree_skb_list(skb_shinfo(msdu)->frag_list); ++ skb_shinfo(msdu)->frag_list = NULL; ++ } ++ dev_kfree_skb(msdu); ++ return; ++ } ++ ++ if (unlikely(!skb_cb->vif)) { ++ dev_kfree_skb_any(msdu); ++ return; ++ } ++ + if (!skb_cb->vif) { + ieee80211_free_txskb(ar->hw, msdu); + return; +@@ -616,6 +649,7 @@ static void ath11k_dp_tx_complete_msdu(s + struct ath11k_peer *peer; + struct ath11k_sta *arsta; + struct rate_info rate; ++ u8 flags = 0; + + 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 + + dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); + ++ /* Free skb here if stats is disabled */ ++ if (ab->stats_disable && !(flags & ATH11K_SKB_TX_STATUS)) { ++ if (msdu->destructor) { ++ msdu->wifi_acked_valid = 1; ++ msdu->wifi_acked = ts->status == HAL_WBM_TQM_REL_REASON_FRAME_ACKED; ++ } ++ if (skb_has_frag_list(msdu)) { ++ kfree_skb_list(skb_shinfo(msdu)->frag_list); ++ skb_shinfo(msdu)->frag_list = NULL; ++ } ++ dev_kfree_skb(msdu); ++ return; ++ } ++ + 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 + + spin_lock_bh(&ab->base_lock); + peer = ath11k_peer_find_by_id(ab, ts->peer_id); +- if (!peer || !peer->sta) { ++ if (unlikely(!peer || !peer->sta)) { + 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 + ts->rate_stats = 0; + } + ++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; ++ ++ /* Dont consider HTT_TX_COMP_STATUS_MEC_NOTIFY */ ++ if (FIELD_GET(HTT_TX_WBM_COMP_INFO0_STATUS, status_desc->info0) == ++ HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY) ++ return false; ++ } ++ return true; ++} ++ + void ath11k_dp_tx_completion_handler(struct ath11k_base *ab, int ring_id) + { + struct ath11k *ar; + struct ath11k_dp *dp = &ab->dp; +- int hal_ring_id = dp->tx_ring[ring_id].tcl_comp_ring.ring_id; ++ 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; + struct hal_tx_status ts = { 0 }; + struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id]; + int valid_entries; + u32 *desc; +- u32 msdu_id; ++ u32 msdu_id, desc_id; + u8 mac_id; ++ struct hal_wbm_release_ring *tx_status; + + spin_lock_bh(&status_ring->lock); + +@@ -763,33 +828,27 @@ void ath11k_dp_tx_completion_handler(str + + ath11k_hal_srng_dst_invalidate_entry(ab, status_ring, valid_entries); + +- while ((ATH11K_TX_COMPL_NEXT(tx_ring->tx_status_head) != +- tx_ring->tx_status_tail) && +- (desc = ath11k_hal_srng_dst_get_next_cache_entry(ab, status_ring))) { +- memcpy(&tx_ring->tx_status[tx_ring->tx_status_head], +- desc, sizeof(struct hal_wbm_release_ring)); +- tx_ring->tx_status_head = +- 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)) ++ continue; + +- if (unlikely((ath11k_hal_srng_dst_peek(ab, status_ring) != NULL) && +- (ATH11K_TX_COMPL_NEXT(tx_ring->tx_status_head) == +- tx_ring->tx_status_tail))) { +- /* TODO: Process pending tx_status messages when kfifo_is_full() */ +- ath11k_warn(ab, "Unable to process some of the tx_status ring desc because status_fifo is full\n"); ++ memcpy(&tx_ring->tx_status[count], ++ desc, sizeof(struct hal_wbm_release_ring)); ++ count++; + } + + ath11k_hal_srng_access_end(ab, status_ring); + + spin_unlock_bh(&status_ring->lock); + +- while (ATH11K_TX_COMPL_NEXT(tx_ring->tx_status_tail) != tx_ring->tx_status_head) { +- struct hal_wbm_release_ring *tx_status; +- u32 desc_id; +- +- tx_ring->tx_status_tail = +- ATH11K_TX_COMPL_NEXT(tx_ring->tx_status_tail); +- tx_status = &tx_ring->tx_status[tx_ring->tx_status_tail]; ++ if (atomic_sub_return(count, &ab->num_max_allowed) < 0) { ++ ath11k_warn(ab, "tx completion mismatch count %d ring id %d max_num %d\n", ++ count, tx_ring->tcl_data_ring_id, ++ atomic_read(&ab->num_max_allowed)); ++ } ++ ++ while (count--) { ++ tx_status = &tx_ring->tx_status[i++]; + 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 + wake_up(&ar->dp.tx_empty_waitq); + + ath11k_dp_tx_complete_msdu(ar, msdu, &ts); +- atomic_dec(&ab->num_max_allowed); + } + } + +--- 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 + if (control->sta) + arsta = ath11k_sta_to_arsta(control->sta); + ++ /* Must call mac80211 tx status handler, else when stats is disabled we free ++ * the skb from driver. Own tx packets on monitor will also be disabled. ++ */ ++ if ((info->flags & (IEEE80211_TX_CTL_REQ_TX_STATUS | IEEE80211_TX_INTFL_NL80211_FRAME_TX)) || ++ info->ack_frame_id || vif->type == NL80211_IFTYPE_MESH_POINT || ++ test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags)) ++ skb_cb->flags |= ATH11K_SKB_TX_STATUS; ++ + if (ar->ab->nss.enabled) + ret = ath11k_nss_tx(arvif, skb); + else + ret = ath11k_dp_tx(ar, arvif, arsta, skb); ++ + if (unlikely(ret)) { +- ath11k_warn(ar->ab, "failed to transmit frame %d\n", ret); ++ if (!ar->ab->nss.enabled && ret != -ENOSPC && ret != -ENOMEM) ++ ath11k_warn(ar->ab, "failed to transmit frame %d\n", ret); + ieee80211_free_txskb(ar->hw, skb); + return; + } +@@ -7690,7 +7700,7 @@ err_vdev_del: + idr_for_each(&ar->txmgmt_idr, + ath11k_mac_vif_txmgmt_idr_remove, vif); + +- for (i = 0; i < ab->hw_params.max_tx_ring; i++) { ++ for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { + spin_lock_bh(&ab->dp.tx_ring[i].tx_idr_lock); + idr_for_each(&ab->dp.tx_ring[i].txbuf_idr, + 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 + len += scnprintf(buf + len, size - len, "ring%d: %u\n", + i, soc_stats->tx_err.desc_na[i]); + ++ len += scnprintf(buf + len, size - len, "\nTCL Ring idr Failures:\n"); ++ for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) ++ len += scnprintf(buf + len, size - len, "ring%d: %u\n", ++ i, soc_stats->tx_err.idr_na[i]); ++ ++ len += scnprintf(buf + len, size - len, "\nMax Transmit Failures: %d\n", ++ atomic_read(&soc_stats->tx_err.max_fail)); ++ + len += scnprintf(buf + len, size - len, + "\nMisc Transmit Failures: %d\n", + atomic_read(&soc_stats->tx_err.misc_fail)); + ++ len += scnprintf(buf + len, size - len, ++ "\nNSS Transmit Failures: %d\n", ++ atomic_read(&soc_stats->tx_err.nss_tx_fail)); ++ + len += ath11k_debugfs_dump_soc_ring_bp_stats(ab, buf + len, size - len); + + 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 + .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, +@@ -217,6 +216,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, ++ /* In addition to TCL ring use TCL_CMD ring also for tx */ ++ .max_tx_ring = DP_TCL_NUM_RING_MAX + 1, + }, + { + .name = "qca6390 hw2.0", +@@ -384,6 +384,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, ++ /* In addition to TCL ring use TCL_CMD ring also for tx */ ++ .max_tx_ring = DP_TCL_NUM_RING_MAX + 1, + }, + { + .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; + ++ 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; ++ + return 0; + } + EXPORT_SYMBOL(ath11k_core_pre_init); +--- a/drivers/net/wireless/ath/ath11k/hal_tx.h ++++ b/drivers/net/wireless/ath/ath11k/hal_tx.h +@@ -18,7 +18,7 @@ + + struct hal_tx_info { + u16 meta_data_flags; /* %HAL_TCL_DATA_CMD_INFO0_META_ */ +- u8 ring_id; ++ u8 buf_id; + u32 desc_id; + enum hal_tcl_desc_type type; + enum hal_tcl_encap_type encap_type; +@@ -70,5 +70,5 @@ int ath11k_hal_reo_cmd_send(struct ath11 + enum hal_reo_cmd_type type, + struct ath11k_hal_reo_cmd *cmd); + void ath11k_hal_tx_init_data_ring(struct ath11k_base *ab, +- struct hal_srng *srng); ++ struct hal_srng *srng, enum hal_ring_type type); + #endif +--- a/drivers/net/wireless/ath/ath11k/hal_tx.c ++++ b/drivers/net/wireless/ath/ath11k/hal_tx.c +@@ -37,18 +37,18 @@ static const u8 dscp_tid_map[DSCP_TID_MA + void ath11k_hal_tx_cmd_desc_setup(struct ath11k_base *ab, void *cmd, + struct hal_tx_info *ti) + { +- struct hal_tcl_data_cmd *tcl_cmd = cmd; ++ struct hal_tcl_data_cmd tcl_cmd, *tcl_desc = cmd; + +- tcl_cmd->buf_addr_info.info0 = ++ tcl_cmd.buf_addr_info.info0 = + FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, ti->paddr); +- tcl_cmd->buf_addr_info.info1 = ++ tcl_cmd.buf_addr_info.info1 = + FIELD_PREP(BUFFER_ADDR_INFO1_ADDR, + ((uint64_t)ti->paddr >> HAL_ADDR_MSB_REG_SHIFT)); +- tcl_cmd->buf_addr_info.info1 |= +- FIELD_PREP(BUFFER_ADDR_INFO1_RET_BUF_MGR, ti->rbm_id) | ++ tcl_cmd.buf_addr_info.info1 |= ++ FIELD_PREP(BUFFER_ADDR_INFO1_RET_BUF_MGR, ti->buf_id) | + FIELD_PREP(BUFFER_ADDR_INFO1_SW_COOKIE, ti->desc_id); + +- tcl_cmd->info0 = ++ tcl_cmd.info0 = + 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 + FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_CMD_NUM, + ti->meta_data_flags); + +- tcl_cmd->info1 = ti->flags0 | ++ tcl_cmd.info1 = ti->flags0 | + FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_DATA_LEN, ti->data_len) | + 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_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, + ti->dscp_tid_tbl_idx) | + FIELD_PREP(HAL_TCL_DATA_CMD_INFO3_SEARCH_INDEX, + ti->bss_ast_idx) | + FIELD_PREP(HAL_TCL_DATA_CMD_INFO3_CACHE_SET_NUM, + ti->bss_ast_hash); +- tcl_cmd->info4 = 0; ++ tcl_cmd.info4 = 0; + + if (ti->enable_mesh) +- ab->hw_params.hw_ops->tx_mesh_enable(ab, tcl_cmd); ++ ab->hw_params.hw_ops->tx_mesh_enable(ab, &tcl_cmd); ++ ++ *tcl_desc = tcl_cmd; + } + + 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 + ctrl_reg_val); + } + +-void ath11k_hal_tx_init_data_ring(struct ath11k_base *ab, struct hal_srng *srng) ++void ath11k_hal_tx_init_data_ring(struct ath11k_base *ab, struct hal_srng *srng, ++ enum hal_ring_type type) ++ + { + struct hal_srng_params params; + struct hal_tlv_hdr *tlv; +@@ -145,7 +149,7 @@ void ath11k_hal_tx_init_data_ring(struct + + memset(¶ms, 0, sizeof(params)); + +- entry_size = ath11k_hal_srng_get_entrysize(ab, HAL_TCL_DATA); ++ entry_size = ath11k_hal_srng_get_entrysize(ab, type); + ath11k_hal_srng_get_params(ab, srng, ¶ms); + desc = (u8 *)params.ring_base_vaddr; + diff --git a/package/kernel/mac80211/patches/ath11k_nss/911-335-0001-ath11k-optimize-tx-completions.patch b/package/kernel/mac80211/patches/ath11k_nss/911-335-0001-ath11k-optimize-tx-completions.patch new file mode 100644 index 00000000000000..3cc13d1ba98543 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/911-335-0001-ath11k-optimize-tx-completions.patch @@ -0,0 +1,269 @@ +From 34b4e65248e7e1605448b06a006347354990bfba Mon Sep 17 00:00:00 2001 +From: Venkateswara Naralasetty +Date: Thu, 11 Nov 2021 10:30:35 +0530 +Subject: [PATCH] ath11k: optimize tx completions + +Process the required fields from tx completion status +in case of stats disabled. + +Signed-off-by: Venkateswara Naralasetty +--- + drivers/net/wireless/ath/ath11k/dp_tx.c | 114 ++++++++++++++++---------------- + 1 file changed, 58 insertions(+), 56 deletions(-) + +--- 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: + spin_unlock_bh(&ab->base_lock); + } + ++static inline void ath11k_dp_tx_status_parse(struct ath11k_base *ab, ++ struct hal_wbm_release_ring *desc, ++ struct hal_tx_status *ts) ++{ ++ ts->buf_rel_source = ++ FIELD_GET(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE, desc->info0); ++ if (unlikely(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_FW && ++ ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) ++ return; ++ ++ if (unlikely(ts->buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW)) ++ return; ++ ++ ts->status = FIELD_GET(HAL_WBM_RELEASE_INFO0_TQM_RELEASE_REASON, ++ desc->info0); ++ ts->ppdu_id = FIELD_GET(HAL_WBM_RELEASE_INFO1_TQM_STATUS_NUMBER, ++ desc->info1); ++ ts->try_cnt = FIELD_GET(HAL_WBM_RELEASE_INFO1_TRANSMIT_COUNT, ++ desc->info1); ++ ts->ack_rssi = FIELD_GET(HAL_WBM_RELEASE_INFO2_ACK_FRAME_RSSI, ++ desc->info2); ++ if (desc->info2 & HAL_WBM_RELEASE_INFO2_FIRST_MSDU) ++ ts->flags |= HAL_TX_STATUS_FLAGS_FIRST_MSDU; ++ ts->peer_id = FIELD_GET(HAL_WBM_RELEASE_INFO3_PEER_ID, desc->info3); ++ ts->tid = FIELD_GET(HAL_WBM_RELEASE_INFO3_TID, desc->info3); ++ if (desc->rate_stats.info0 & HAL_TX_RATE_STATS_INFO0_VALID) ++ ts->rate_stats = desc->rate_stats.info0; ++ else ++ ts->rate_stats = 0; ++} ++ + static void ath11k_dp_tx_complete_msdu(struct ath11k *ar, + struct sk_buff *msdu, +- struct hal_tx_status *ts) ++ struct hal_wbm_release_ring *tx_status, ++ enum hal_wbm_rel_src_module buf_rel_source) + { + 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 + 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; + +- if (WARN_ON_ONCE(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) { ++ if (unlikely(WARN_ON_ONCE(buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM))) { + /* Must not happen */ + return; + } +@@ -660,11 +696,14 @@ static void ath11k_dp_tx_complete_msdu(s + + dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); + +- /* Free skb here if stats is disabled */ ++ rel_status = FIELD_GET(HAL_WBM_RELEASE_INFO0_TQM_RELEASE_REASON, ++ tx_status->info0); ++ ++ /* Free skb here if stats is disabled */ + if (ab->stats_disable && !(flags & ATH11K_SKB_TX_STATUS)) { + if (msdu->destructor) { + msdu->wifi_acked_valid = 1; +- msdu->wifi_acked = ts->status == HAL_WBM_TQM_REL_REASON_FRAME_ACKED; ++ msdu->wifi_acked = rel_status == HAL_WBM_TQM_REL_REASON_FRAME_ACKED; + } + 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 + return; + } + ++ ath11k_dp_tx_status_parse(ab, tx_status, &ts); ++ + 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)); + + /* skip tx rate update from ieee80211_status*/ + info->status.rates[0].idx = -1; + +- if (ts->status == HAL_WBM_TQM_REL_REASON_FRAME_ACKED && ++ if (ts.status == HAL_WBM_TQM_REL_REASON_FRAME_ACKED && + !(info->flags & IEEE80211_TX_CTL_NO_ACK)) { + info->flags |= IEEE80211_TX_STAT_ACK; + info->status.ack_signal = ATH11K_DEFAULT_NOISE_FLOOR + +- ts->ack_rssi; ++ ts.ack_rssi; + info->status.flags |= IEEE80211_TX_STATUS_ACK_SIGNAL_VALID; + } + +- if (ts->status == HAL_WBM_TQM_REL_REASON_CMD_REMOVE_TX && ++ if (ts.status == HAL_WBM_TQM_REL_REASON_CMD_REMOVE_TX && + (info->flags & IEEE80211_TX_CTL_NO_ACK)) + info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; + + if (unlikely(ath11k_debugfs_is_extd_tx_stats_enabled(ar)) || + ab->hw_params.single_pdev_only) { +- if (ts->flags & HAL_TX_STATUS_FLAGS_FIRST_MSDU) { ++ if (ts.flags & HAL_TX_STATUS_FLAGS_FIRST_MSDU) { + if (ar->last_ppdu_id == 0) { +- ar->last_ppdu_id = ts->ppdu_id; +- } else if (ar->last_ppdu_id == ts->ppdu_id || ++ ar->last_ppdu_id = ts.ppdu_id; ++ } else if (ar->last_ppdu_id == ts.ppdu_id || + ar->cached_ppdu_id == ar->last_ppdu_id) { + ar->cached_ppdu_id = ar->last_ppdu_id; + ar->cached_stats.is_ampdu = true; +- ath11k_dp_tx_update_txcompl(ar, ts); ++ ath11k_dp_tx_update_txcompl(ar, &ts); + memset(&ar->cached_stats, 0, + sizeof(struct ath11k_per_peer_tx_stats)); + } else { + ar->cached_stats.is_ampdu = false; +- ath11k_dp_tx_update_txcompl(ar, ts); ++ ath11k_dp_tx_update_txcompl(ar, &ts); + memset(&ar->cached_stats, 0, + sizeof(struct ath11k_per_peer_tx_stats)); + } +- ar->last_ppdu_id = ts->ppdu_id; ++ ar->last_ppdu_id = ts.ppdu_id; + } + +- ath11k_dp_tx_cache_peer_stats(ar, msdu, ts); ++ ath11k_dp_tx_cache_peer_stats(ar, msdu, &ts); + } + + spin_lock_bh(&ab->base_lock); +- peer = ath11k_peer_find_by_id(ab, ts->peer_id); ++ peer = ath11k_peer_find_by_id(ab, ts.peer_id); + if (unlikely(!peer || !peer->sta)) { + ath11k_dbg(ab, ATH11K_DBG_DATA, + "dp_tx: failed to find the peer with peer_id %d\n", +- ts->peer_id); ++ ts.peer_id); + 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 + ieee80211_tx_status_ext(ar->hw, &status); + } + +-static inline void ath11k_dp_tx_status_parse(struct ath11k_base *ab, +- struct hal_wbm_release_ring *desc, +- struct hal_tx_status *ts) +-{ +- ts->buf_rel_source = +- FIELD_GET(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE, desc->info0); +- if (unlikely(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_FW && +- ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) +- return; +- +- if (unlikely(ts->buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW)) +- return; +- +- ts->status = FIELD_GET(HAL_WBM_RELEASE_INFO0_TQM_RELEASE_REASON, +- desc->info0); +- ts->ppdu_id = FIELD_GET(HAL_WBM_RELEASE_INFO1_TQM_STATUS_NUMBER, +- desc->info1); +- ts->try_cnt = FIELD_GET(HAL_WBM_RELEASE_INFO1_TRANSMIT_COUNT, +- desc->info1); +- ts->ack_rssi = FIELD_GET(HAL_WBM_RELEASE_INFO2_ACK_FRAME_RSSI, +- desc->info2); +- if (desc->info2 & HAL_WBM_RELEASE_INFO2_FIRST_MSDU) +- ts->flags |= HAL_TX_STATUS_FLAGS_FIRST_MSDU; +- ts->peer_id = FIELD_GET(HAL_WBM_RELEASE_INFO3_PEER_ID, desc->info3); +- ts->tid = FIELD_GET(HAL_WBM_RELEASE_INFO3_TID, desc->info3); +- if (desc->rate_stats.info0 & HAL_TX_RATE_STATS_INFO0_VALID) +- ts->rate_stats = desc->rate_stats.info0; +- else +- ts->rate_stats = 0; +-} +- + 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 + 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; +- struct hal_tx_status ts = { 0 }; + struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id]; + int valid_entries; ++ enum hal_wbm_rel_src_module buf_rel_source; + 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 + + while (count--) { + tx_status = &tx_ring->tx_status[i++]; +- ath11k_dp_tx_status_parse(ab, tx_status, &ts); + + desc_id = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, + tx_status->buf_addr_info.info1); + mac_id = FIELD_GET(DP_TX_DESC_ID_MAC_ID, desc_id); + msdu_id = FIELD_GET(DP_TX_DESC_ID_MSDU_ID, desc_id); + +- if (unlikely(ts.buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW)) { ++ buf_rel_source = FIELD_GET(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE, ++ tx_status->info0); ++ ++ if (unlikely(buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW)) { + 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 + if (atomic_dec_and_test(&ar->dp.num_tx_pending)) + wake_up(&ar->dp.tx_empty_waitq); + +- ath11k_dp_tx_complete_msdu(ar, msdu, &ts); ++ ath11k_dp_tx_complete_msdu(ar, msdu, tx_status, buf_rel_source); + } + } + 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/ath11k_nss/911-335-0002-ath11k-use-DECLARE_BITMAP-for-idr-operations.patch new file mode 100644 index 00000000000000..7b87edb0ae6baa --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/911-335-0002-ath11k-use-DECLARE_BITMAP-for-idr-operations.patch @@ -0,0 +1,288 @@ +From 6cd8cb301e431860e71b8d3453846a9ed0efea81 Mon Sep 17 00:00:00 2001 +From: Venkateswara Naralasetty +Date: Thu, 11 Nov 2021 10:38:26 +0530 +Subject: [PATCH] ath11k: use DECLARE_BITMAP for idr operations + +Use DECLARE_BITMAP for declaring bit map for idrs. And use APIs +find_first_zero_bit, set_bit and clear bit instead of idr_alloc +and idr_destroy. + +This helps in improving idle CPU and throughput. + +Signed-off-by: Venkateswara Naralasetty +--- + drivers/net/wireless/ath/ath11k/dp.c | 34 +++++++++++++----- + drivers/net/wireless/ath/ath11k/dp.h | 10 +++++- + drivers/net/wireless/ath/ath11k/dp_tx.c | 61 ++++++++++++++++++--------------- + 3 files changed, 69 insertions(+), 36 deletions(-) + +--- 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 + 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); ++ kfree(dp->tx_ring[i].idr_pool); ++ dp->tx_ring[i].idr_pool = NULL; + } + 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 + { + struct ath11k_dp *dp = &ab->dp; + struct hal_srng *srng; +- int i, ret; ++ int i, ret, j; + 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 + 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); ++ ++ dp->tx_ring[i].idr_pool = kcalloc(DP_TX_IDR_SIZE, ++ sizeof(struct idr_entry), GFP_KERNEL); ++ if (!dp->tx_ring[i].idr_pool) { ++ ath11k_warn(ab, "failed to allocate memory for idr pool ring(%d)\n", i); ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ /* Reset id to default */ ++ for (j = 0; j < DP_TX_IDR_SIZE; j++) ++ dp->tx_ring[i].idr_pool[j].id = -1; + } + + 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 + ath11k_dp_update_vdev_search(arvif); + } + +-static int ath11k_dp_tx_pending_cleanup(int buf_id, void *skb, void *ctx) ++static int ath11k_dp_tx_pending_cleanup(struct ath11k_base *ab, void *skb) + { +- struct ath11k_base *ab = ctx; + 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 * + { + 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); + ++ for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { ++ struct dp_tx_ring *tx_ring = &dp->tx_ring[i]; ++ spin_lock_bh(&tx_ring->tx_idr_lock); ++ for(j = 0; j < DP_TX_IDR_SIZE; j++) { ++ ++ if (test_and_clear_bit(j, tx_ring->idrs)) ++ ath11k_dp_tx_pending_cleanup(ab, tx_ring->idr_pool[j].buf); ++ } ++ ++ spin_unlock_bh(&tx_ring->tx_idr_lock); ++ } ++ + ath11k_dp_srng_common_cleanup(ab); + + ath11k_dp_reo_cmd_list_cleanup(ab); + + for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { +- 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); +- 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 @@ + #define ATH11K_DP_H + + #include "hal_rx.h" ++#include "hw.h" + + #define MAX_RXDMA_PER_PDEV 2 + +@@ -78,6 +79,13 @@ struct dp_rxdma_ring { + + #define ATH11K_TX_COMPL_NEXT(x) (((x) + 1) % DP_TX_COMP_RING_SIZE) + ++struct idr_entry { ++ int id; ++ void *buf; ++}; ++ ++#define DP_TX_IDR_SIZE ATH11K_DP_TX_COMP_RING_SIZE ++ + struct dp_tx_ring { + u8 tcl_data_ring_id; + struct dp_srng tcl_data_ring; +@@ -88,6 +96,8 @@ struct dp_tx_ring { + struct hal_wbm_release_ring *tx_status; + int tx_status_head; + int tx_status_tail; ++ DECLARE_BITMAP(idrs, DP_TX_IDR_SIZE); ++ struct idr_entry *idr_pool; + }; + + enum dp_mon_status_buf_state { +@@ -207,7 +217,6 @@ struct ath11k_pdev_dp { + #define DP_TCL_DATA_RING_SIZE 512 + #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_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 + 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; ++ u32 idr; + + if (unlikely(!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && + !ieee80211_is_data(hdr->frame_control))) +@@ -152,24 +153,28 @@ tcl_ring_sel: + 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, +- DP_TX_IDR_SIZE - 1, GFP_ATOMIC); +- spin_unlock_bh(&tx_ring->tx_idr_lock); +- +- if (unlikely(ret < 0)) { ++ idr = find_first_zero_bit(tx_ring->idrs, DP_TX_IDR_SIZE); ++ if (unlikely(idr >= DP_TX_IDR_SIZE)) { + if (ring_map == (BIT(max_tx_ring) - 1) || + !ab->hw_params.tcl_ring_retry) { ++ spin_unlock_bh(&tx_ring->tx_idr_lock); + ab->soc_stats.tx_err.idr_na[tcl_ring_id]++; + return -ENOSPC; + } + + /* Check if the next ring is available */ ++ spin_unlock_bh(&tx_ring->tx_idr_lock); + ring_selector++; + goto tcl_ring_sel; + } + ++ 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); ++ + ti.desc_id = FIELD_PREP(DP_TX_DESC_ID_MAC_ID, ar->pdev_idx) | +- FIELD_PREP(DP_TX_DESC_ID_MSDU_ID, ret) | ++ FIELD_PREP(DP_TX_DESC_ID_MSDU_ID, idr) | + 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: + fail_remove_idr: + if (ti.pkt_offset) + skb_pull(skb, ti.pkt_offset); +- spin_lock_bh(&tx_ring->tx_idr_lock); +- idr_remove(&tx_ring->txbuf_idr, +- FIELD_GET(DP_TX_DESC_ID_MSDU_ID, ti.desc_id)); +- spin_unlock_bh(&tx_ring->tx_idr_lock); ++ ++ tx_ring->idr_pool[idr].id = -1; ++ clear_bit(idr, tx_ring->idrs); + + if (tcl_ring_retry) + goto tcl_ring_sel; +@@ -353,16 +357,19 @@ fail_remove_idr: + } + + static void ath11k_dp_tx_free_txbuf(struct ath11k_base *ab, u8 mac_id, +- int msdu_id, ++ u32 msdu_id, + struct dp_tx_ring *tx_ring) + { + struct ath11k *ar; +- struct sk_buff *msdu; ++ struct sk_buff *msdu = NULL; + struct ath11k_skb_cb *skb_cb; + +- spin_lock(&tx_ring->tx_idr_lock); +- msdu = idr_remove(&tx_ring->txbuf_idr, msdu_id); +- spin_unlock(&tx_ring->tx_idr_lock); ++ if (msdu_id < DP_TX_IDR_SIZE && ++ tx_ring->idr_pool[msdu_id].id == msdu_id) { ++ msdu = tx_ring->idr_pool[msdu_id].buf; ++ tx_ring->idr_pool[msdu_id].id = -1; ++ clear_bit(msdu_id, tx_ring->idrs); ++ } + + 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 + struct ath11k_dp_htt_wbm_tx_status *ts) + { + struct ieee80211_tx_status status = { 0 }; +- struct sk_buff *msdu; ++ struct sk_buff *msdu = NULL; + struct ieee80211_tx_info *info; + struct ath11k_skb_cb *skb_cb; + struct ath11k *ar; + struct ath11k_peer *peer; ++ u32 msdu_id = ts->msdu_id; + u8 flags = 0; + +- spin_lock(&tx_ring->tx_idr_lock); +- msdu = idr_remove(&tx_ring->txbuf_idr, ts->msdu_id); +- spin_unlock(&tx_ring->tx_idr_lock); ++ if (msdu_id < DP_TX_IDR_SIZE && ++ tx_ring->idr_pool[msdu_id].id == msdu_id) { ++ msdu = tx_ring->idr_pool[msdu_id].buf; ++ tx_ring->idr_pool[msdu_id].id = -1; ++ clear_bit(msdu_id, tx_ring->idrs); ++ } + + 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 + } + + while (count--) { ++ msdu=NULL; + 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 + continue; + } + +- spin_lock(&tx_ring->tx_idr_lock); +- msdu = idr_remove(&tx_ring->txbuf_idr, msdu_id); ++ if (msdu_id < DP_TX_IDR_SIZE && ++ tx_ring->idr_pool[msdu_id].id == msdu_id) { ++ msdu = tx_ring->idr_pool[msdu_id].buf; ++ tx_ring->idr_pool[msdu_id].id = -1; ++ clear_bit(msdu_id, tx_ring->idrs); ++ } ++ + if (unlikely(!msdu)) { + ath11k_warn(ab, "tx completion for unknown msdu_id %d\n", + msdu_id); +- spin_unlock(&tx_ring->tx_idr_lock); + continue; + } + +- spin_unlock(&tx_ring->tx_idr_lock); +- + ar = ab->pdevs[mac_id].ar; + + if (atomic_dec_and_test(&ar->dp.num_tx_pending)) 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 new file mode 100644 index 00000000000000..c61c206c417de7 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/911-335-0006-ath11k-add-simple-tx-handler-for-AP-mode.patch @@ -0,0 +1,185 @@ +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 new file mode 100644 index 00000000000000..ffae27277d7316 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/911-335-ath11k-fix-ar-ops-crash.patch @@ -0,0 +1,71 @@ +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/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch b/package/kernel/mac80211/patches/ath11k_nss/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch new file mode 100644 index 00000000000000..90f335efbca6fb --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch @@ -0,0 +1,384 @@ +From 17d1895bad45ec2ef4c8c430ac0fbaff2ff1cf39 Mon Sep 17 00:00:00 2001 +From: Manish Dharanenthiran +Date: Tue, 18 Apr 2023 15:01:42 +0530 +Subject: [PATCH 2/3] CHROMIUM: ath11k: Add retry mechanism for update_rx_queue + reo cmd + +While reo_cmd ring is full, peer delete update rx queue +will be failed as there is no space to send the command +in ring. During the failure scenario, host will do +dma_unmap and free the allocated address but the HW +still have that particular vaddr. So, on next alloc +cycle kernel will allocated the freed addr but HW will +still have the address. This will result in memory +corruption as the host will try to access/write that +memory which is already in-use. + +To avoid this corruption, added new retry mechanism +for HAL_REO_CMD_UPDATE_RX_QUEUE by adding new list to +dp struct and protecting with new lock for access. +This avoids the host free in failure case and will +be freed only when HW freed that particular vaddr. + +Also, updated below changes +1) reo_flush command for sending 1K desc in one +command instead of sending 11 command for single +TID. + +2) Set FWD_MPDU and valid bit flag so that reo +flush will happen soon instead of waiting to +flush the queue. + +Signed-off-by: Manish Dharanenthiran +Signed-off-by: Tamizh Chelvam Raja +--- + drivers/net/wireless/ath/ath11k/core.h | 3 + + drivers/net/wireless/ath/ath11k/debugfs.c | 12 ++ + drivers/net/wireless/ath/ath11k/dp.c | 2 + + drivers/net/wireless/ath/ath11k/dp.h | 15 ++ + drivers/net/wireless/ath/ath11k/dp_rx.c | 167 +++++++++++++++++----- + 5 files changed, 161 insertions(+), 38 deletions(-) + +--- 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 { + 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]; ++ u32 hal_reo_cmd_drain; ++ u32 reo_cmd_cache_error; ++ u32 reo_cmd_update_rx_queue_error; + struct ath11k_soc_dp_tx_err_stats tx_err; + struct ath11k_dp_ring_bp_stats bp_stats; + }; +--- 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 + "\nNSS Transmit Failures: %d\n", + atomic_read(&soc_stats->tx_err.nss_tx_fail)); + ++ len += scnprintf(buf + len, size - len, ++ "\nHAL_REO_CMD_DRAIN Counter: %u\n", ++ soc_stats->hal_reo_cmd_drain); ++ ++ len += scnprintf(buf + len, size - len, ++ "\nREO_CMD_CACHE_FLUSH Failure: %u\n", ++ soc_stats->reo_cmd_cache_error); ++ ++ len += scnprintf(buf + len, size - len, ++ "\nREO_CMD_UPDATE_RX_QUEUE Failure: %u\n", ++ soc_stats->reo_cmd_update_rx_queue_error); ++ + len += ath11k_debugfs_dump_soc_ring_bp_stats(ab, buf + len, size - len); + + 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 * + + INIT_LIST_HEAD(&dp->reo_cmd_list); + INIT_LIST_HEAD(&dp->reo_cmd_cache_flush_list); ++ INIT_LIST_HEAD(&dp->reo_cmd_update_rx_queue_list); + INIT_LIST_HEAD(&dp->dp_full_mon_mpdu_list); + spin_lock_init(&dp->reo_cmd_lock); ++ spin_lock_init(&dp->reo_cmd_update_queue_lock); + + dp->reo_cmd_cache_flush_count = 0; + +--- a/drivers/net/wireless/ath/ath11k/dp.h ++++ b/drivers/net/wireless/ath/ath11k/dp.h +@@ -24,6 +24,7 @@ struct dp_rx_tid { + u32 *vaddr; + dma_addr_t paddr; + u32 size; ++ u32 pending_desc_size; + u32 ba_win_sz; + bool active; + +@@ -51,6 +52,14 @@ struct dp_reo_cache_flush_elem { + unsigned long ts; + }; + ++struct dp_reo_update_rx_queue_elem { ++ struct list_head list; ++ struct dp_rx_tid data; ++ int peer_id; ++ u8 tid; ++ bool reo_cmd_update_rx_queue_resend_flag; ++}; ++ + struct dp_reo_cmd { + struct list_head list; + struct dp_rx_tid data; +@@ -296,6 +305,12 @@ struct ath11k_dp { + * - reo_cmd_cache_flush_count + */ + spinlock_t reo_cmd_lock; ++ struct list_head reo_cmd_update_rx_queue_list; ++ /** ++ * protects access to below field, ++ * - reo_cmd_update_rx_queue_list ++ */ ++ spinlock_t reo_cmd_update_queue_lock; + struct ath11k_hp_update_timer reo_cmd_timer; + struct ath11k_hp_update_timer tx_ring_timer[DP_TCL_NUM_RING_MAX]; + }; +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -21,6 +21,9 @@ + + #define ATH11K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ) + ++static void ath11k_dp_rx_tid_del_func(struct ath11k_dp *dp, void *ctx, ++ enum hal_reo_cmd_status status); ++ + 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( + return 0; + } + ++static int ath11k_peer_rx_tid_delete_handler(struct ath11k_base *ab, ++ struct dp_rx_tid *rx_tid, u8 tid) ++{ ++ struct ath11k_hal_reo_cmd cmd = {0}; ++ struct ath11k_dp *dp = &ab->dp; ++ ++ lockdep_assert_held(&dp->reo_cmd_update_queue_lock); ++ ++ rx_tid->active = false; ++ cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; ++ cmd.addr_lo = lower_32_bits(rx_tid->paddr); ++ cmd.addr_hi = upper_32_bits(rx_tid->paddr); ++ cmd.upd0 |= HAL_REO_CMD_UPD0_VLD; ++ ++ return ath11k_dp_tx_send_reo_cmd(ab, rx_tid, ++ HAL_REO_CMD_UPDATE_RX_QUEUE, ++ &cmd, ++ ath11k_dp_rx_tid_del_func); ++} ++ + void ath11k_dp_reo_cmd_list_cleanup(struct ath11k_base *ab) + { + struct ath11k_dp *dp = &ab->dp; + struct dp_reo_cmd *cmd, *tmp; + struct dp_reo_cache_flush_elem *cmd_cache, *tmp_cache; ++ struct dp_reo_update_rx_queue_elem *cmd_queue, *tmp_queue; + struct dp_rx_tid *rx_tid; + ++ spin_lock_bh(&dp->reo_cmd_update_queue_lock); ++ list_for_each_entry_safe(cmd_queue, tmp_queue, ++ &dp->reo_cmd_update_rx_queue_list, ++ list) { ++ list_del(&cmd_queue->list); ++ rx_tid = &cmd_queue->data; ++ if (rx_tid->vaddr) { ++ dma_unmap_single(ab->dev, rx_tid->paddr, ++ rx_tid->size, DMA_BIDIRECTIONAL); ++ kfree(rx_tid->vaddr); ++ rx_tid->vaddr = NULL; ++ } ++ kfree(cmd_queue); ++ } ++ spin_unlock_bh(&dp->reo_cmd_update_queue_lock); ++ + 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 + } + } + +-static void ath11k_dp_reo_cache_flush(struct ath11k_base *ab, ++static int ath11k_dp_reo_cache_flush(struct ath11k_base *ab, + struct dp_rx_tid *rx_tid) + { + struct ath11k_hal_reo_cmd cmd = {0}; + unsigned long tot_desc_sz, desc_sz; + int ret; + +- tot_desc_sz = rx_tid->size; ++ if (rx_tid->pending_desc_size) ++ tot_desc_sz = rx_tid->pending_desc_size; ++ else ++ tot_desc_sz = rx_tid->size; ++ + 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 + HAL_REO_CMD_FLUSH_CACHE, &cmd, + NULL); + if (ret) +- ath11k_warn(ab, +- "failed to send HAL_REO_CMD_FLUSH_CACHE, tid %d (%d)\n", +- rx_tid->tid, ret); ++ rx_tid->pending_desc_size = tot_desc_sz + desc_sz; ++ ++ /* If this fails with ring full condition, then ++ * no need to retry below as it is expected to ++ * fail within short time ++ */ ++ if (ret == -ENOBUFS) ++ goto exit; + } + ++ rx_tid->pending_desc_size = desc_sz; + 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 + ret = ath11k_dp_tx_send_reo_cmd(ab, rx_tid, + HAL_REO_CMD_FLUSH_CACHE, + &cmd, ath11k_dp_reo_cmd_free); +- if (ret) { +- ath11k_err(ab, "failed to send HAL_REO_CMD_FLUSH_CACHE cmd, tid %d (%d)\n", +- rx_tid->tid, ret); +- dma_unmap_single(ab->dev, rx_tid->paddr, rx_tid->size, +- DMA_BIDIRECTIONAL); +- kfree(rx_tid->vaddr); +- rx_tid->vaddr = NULL; +- } ++ ++exit: ++ return ret; + } + + static void ath11k_dp_rx_tid_del_func(struct ath11k_dp *dp, void *ctx, + enum hal_reo_cmd_status status) + { + struct ath11k_base *ab = dp->ab; +- struct dp_rx_tid *rx_tid = ctx; ++ struct dp_rx_tid *rx_tid = ctx, *update_rx_tid; + struct dp_reo_cache_flush_elem *elem, *tmp; ++ struct dp_reo_update_rx_queue_elem *qelem, *qtmp; + + if (status == HAL_REO_CMD_DRAIN) { ++ ab->soc_stats.hal_reo_cmd_drain++; + 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 + return; + } + ++ /* Check if there is any pending rx_queue, if yes then update it */ ++ spin_lock_bh(&dp->reo_cmd_update_queue_lock); ++ list_for_each_entry_safe(qelem, qtmp, &dp->reo_cmd_update_rx_queue_list, ++ list) { ++ if (qelem->reo_cmd_update_rx_queue_resend_flag && ++ qelem->data.active) { ++ update_rx_tid = &qelem->data; ++ ++ if (ath11k_peer_rx_tid_delete_handler(ab, update_rx_tid, qelem->tid)) { ++ update_rx_tid->active = true; ++ break; ++ } ++ update_rx_tid->vaddr = NULL; ++ update_rx_tid->paddr = 0; ++ update_rx_tid->size = 0; ++ update_rx_tid->pending_desc_size = 0; ++ ++ list_del(&qelem->list); ++ kfree(qelem); ++ } ++ } ++ spin_unlock_bh(&dp->reo_cmd_update_queue_lock); ++ + elem = kzalloc(sizeof(*elem), GFP_ATOMIC); + if (!elem) + goto free_desc; +@@ -832,13 +902,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))) { ++ spin_unlock_bh(&dp->reo_cmd_lock); ++ if (ath11k_dp_reo_cache_flush(ab, &elem->data)) { ++ ab->soc_stats.reo_cmd_cache_error++; ++ /* In failure case, just update the timestamp ++ * for flush cache elem and continue ++ */ ++ spin_lock_bh(&dp->reo_cmd_lock); ++ elem->ts = jiffies; ++ break; ++ } ++ spin_lock_bh(&dp->reo_cmd_lock); + list_del(&elem->list); + dp->reo_cmd_cache_flush_count--; +- spin_unlock_bh(&dp->reo_cmd_lock); +- +- ath11k_dp_reo_cache_flush(ab, &elem->data); + kfree(elem); +- spin_lock_bh(&dp->reo_cmd_lock); + } + } + spin_unlock_bh(&dp->reo_cmd_lock); +@@ -854,34 +931,48 @@ free_desc: + void ath11k_peer_rx_tid_delete(struct ath11k *ar, + struct ath11k_peer *peer, u8 tid) + { +- struct ath11k_hal_reo_cmd cmd = {0}; + struct dp_rx_tid *rx_tid = &peer->rx_tid[tid]; +- int ret; ++ struct dp_reo_update_rx_queue_elem *elem, *tmp; ++ struct ath11k_base *ab = ar->ab; ++ struct ath11k_dp *dp = &ab->dp; + + if (!rx_tid->active) + return; + +- rx_tid->active = false; ++ elem = kzalloc(sizeof(*elem), GFP_ATOMIC); ++ if (!elem) { ++ ath11k_warn(ar->ab, "failed to alloc reo_update_rx_queue_elem, rx tid %d\n", ++ rx_tid->tid); ++ return; ++ } ++ elem->reo_cmd_update_rx_queue_resend_flag = false; ++ elem->peer_id = peer->peer_id; ++ elem->tid = tid; ++ memcpy(&elem->data, rx_tid, sizeof(*rx_tid)); ++ spin_lock_bh(&dp->reo_cmd_update_queue_lock); ++ list_add_tail(&elem->list, &dp->reo_cmd_update_rx_queue_list); + +- cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; +- cmd.addr_lo = lower_32_bits(rx_tid->paddr); +- cmd.addr_hi = upper_32_bits(rx_tid->paddr); +- cmd.upd0 |= HAL_REO_CMD_UPD0_VLD; +- ret = ath11k_dp_tx_send_reo_cmd(ar->ab, rx_tid, +- HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, +- ath11k_dp_rx_tid_del_func); +- if (ret) { +- if (ret != -ESHUTDOWN) +- ath11k_err(ar->ab, "failed to send HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n", +- tid, ret); +- dma_unmap_single(ar->ab->dev, rx_tid->paddr, rx_tid->size, +- DMA_BIDIRECTIONAL); +- kfree(rx_tid->vaddr); ++ list_for_each_entry_safe(elem, tmp, &dp->reo_cmd_update_rx_queue_list, ++ list) { ++ rx_tid = &elem->data; ++ ++ if (ath11k_peer_rx_tid_delete_handler(ab, rx_tid, elem->tid)) { ++ rx_tid->active = true; ++ ab->soc_stats.reo_cmd_update_rx_queue_error++; ++ elem->reo_cmd_update_rx_queue_resend_flag = true; ++ break; ++ } + rx_tid->vaddr = NULL; ++ rx_tid->paddr = 0; ++ rx_tid->size = 0; ++ rx_tid->pending_desc_size = 0; ++ ++ list_del(&elem->list); ++ kfree(elem); + } ++ spin_unlock_bh(&dp->reo_cmd_update_queue_lock); + +- rx_tid->paddr = 0; +- rx_tid->size = 0; ++ return; + } + + static int ath11k_dp_rx_link_desc_return(struct ath11k_base *ab, 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/ath11k_nss/913-341-ath11k-fix-support-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch new file mode 100644 index 00000000000000..a1b885c8b50e5a --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/913-341-ath11k-fix-support-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch @@ -0,0 +1,52 @@ +From 516c1d2faf4480c355ec5000d6d4ad4fc287d0e8 Mon Sep 17 00:00:00 2001 +From: Aditya Kumar Singh +Date: Thu, 30 Dec 2021 17:44:40 +0530 +Subject: [PATCH] ath11k: fix support for ext vdev in NSS for AP_VLAN vif + during recovery + +When driver is recovering, it tears down nss connection and sets +ab->nss.enabled as false. However, this is not set back to its original +state post recovery and hence when ext vdev is added again, warning +trace appears since ath11k_mac_op_add_interface() does not handle +NL80211_IFTYPE_AP_VLAN vif with nss disabled and throws a WARN_ON(1). + +[ 2777.201255] ------------[ cut here ]------------ +[ 2777.209669] WARNING: CPU: 0 PID: 77 at drivers/net/wireless/ath/ath11k/mac.c:7298 ath11k_mac_op_add_interface+0x314/0xa98 [ath11k] +[----- Trimmed -----] +[ 2777.499054] CPU: 0 PID: 77 Comm: kworker/0:2 Tainted: G W 5.4.89 #0 +[ 2777.515132] Hardware name: Generic DT based system +[ 2777.522658] Workqueue: events_freezable ieee80211_restart_work [mac80211] +[ 2777.527305] [<8030f3a4>] (unwind_backtrace) from [<8030b700>] (show_stack+0x10/0x14) +[ 2777.534153] [<8030b700>] (show_stack) from [<808da410>] (dump_stack+0x88/0xa8) +[ 2777.541964] [<808da410>] (dump_stack) from [<8031bf20>] (__warn+0xa4/0xd0) +[ 2777.548994] [<8031bf20>] (__warn) from [<8031bfbc>] (warn_slowpath_fmt+0x70/0x9c) +[ 2777.555972] [<8031bfbc>] (warn_slowpath_fmt) from [] (ath11k_mac_op_add_interface+0x314/0xa98 [ath11k]) +[ 2777.563664] [] (ath11k_mac_op_add_interface [ath11k]) from [<7fd34720>] (drv_add_interface+0x68/0x78 [mac80211]) +[ 2777.573928] [<7fd34720>] (drv_add_interface [mac80211]) from [<7fd679bc>] (ieee80211_reconfig+0x240/0xce8 [mac80211]) +[ 2777.584843] [<7fd679bc>] (ieee80211_reconfig [mac80211]) from [<7fd311ec>] (ieee80211_restart_work+0xd4/0xf4 [mac80211]) +[ 2777.595401] [<7fd311ec>] (ieee80211_restart_work [mac80211]) from [<80331968>] (process_one_work+0x1dc/0x310) +[ 2777.606205] [<80331968>] (process_one_work) from [<80332cf8>] (worker_thread+0x2bc/0x40c) +[ 2777.616009] [<80332cf8>] (worker_thread) from [<803373ac>] (kthread+0x164/0x180) +[ 2777.624167] [<803373ac>] (kthread) from [<803010e0>] (ret_from_fork+0x14/0x34) + +Added logic to enable nss as per MODULE_PARM_DESC parameter. + +Signed-off-by: Aditya Kumar Singh +--- + drivers/net/wireless/ath/ath11k/core.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- 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 + + clear_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags); + ++ /* We have disabled NSS Offload support in the starting. ++ * Re-enabling it if it was originally enabled in the MODULE_PARM_DESC. ++ */ ++ ab->nss.enabled = nss_offload; ++ + ret = ath11k_core_qmi_firmware_ready(ab); + if (ret) + goto err_hal_srng_deinit; 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/ath11k_nss/913-353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch new file mode 100644 index 00000000000000..e8ac589acfc8ec --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/913-353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch @@ -0,0 +1,74 @@ +From 0ab84604de1db0f589f7303507f38148ba8f3f04 Mon Sep 17 00:00:00 2001 +From: Nagarajan Maran +Date: Tue, 28 Jun 2022 11:31:50 +0530 +Subject: [PATCH] ath11k: Ignore frags from uninitialized peer in dp + +In certain scenario, fragmented packet is received for self peer, +for which rx_tid and rx_frags are not initialized in datapath. +While handling this fragment, crash is observed as the +rx_frag list is uninitialised and when we walk in +ath11k_dp_rx_h_sort_frags, skb null leads to exception. + +To address this, before processing received fragments we +check dp_setup_done flag is set to ensure that peer +has completed its dp peer setup for fragment queue, +else ignore processing the fragments. + +Also, __fls would have an undefined behavior if the argument +is passed as "0". Hence, added changes to handle the same. + +Below is the call trace of the crash: + + CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.4.164 #0 + Hardware name: Qualcomm Technologies, Inc. IPQ6018/AP-CP01-C1 (DT) + pstate: a0400005 (NzCv daif +PAN -UAO) + pc : ath11k_dp_process_rx_err+0x550/0x1084 [ath11k] + lr : ath11k_dp_process_rx_err+0x4e0/0x1084 [ath11k] + + Call trace: + ath11k_dp_process_rx_err+0x550/0x1084 [ath11k] + ath11k_dp_service_srng+0x70/0x370 [ath11k] + 0xffffffc009693a04 + __napi_poll+0x30/0xa4 + net_rx_action+0x118/0x270 + __do_softirq+0x10c/0x244 + irq_exit+0x64/0xb4 + __handle_domain_irq+0x88/0xac + gic_handle_irq+0x74/0xbc + el1_irq+0xf0/0x1c0 + arch_cpu_idle+0x10/0x18 + do_idle+0x104/0x248 + cpu_startup_entry+0x20/0x64 + rest_init+0xd0/0xdc + arch_call_rest_init+0xc/0x14 + start_kernel+0x480/0x4b8 + Code: f9400281 f94066a2 91405021 b94a0023 (f9406401) + +Signed-off-by: Harshitha Prem +Signed-off-by: Nagarajan Maran +--- + drivers/net/wireless/ath/ath11k/dp.c | 3 ++- + drivers/net/wireless/ath/ath11k/dp_rx.c | 11 ++++++++++- + drivers/net/wireless/ath/ath11k/peer.h | 2 ++ + 3 files changed, 14 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/dp.c ++++ b/drivers/net/wireless/ath/ath11k/dp.c +@@ -38,6 +38,7 @@ void ath11k_dp_peer_cleanup(struct ath11 + ath11k_peer_rx_tid_cleanup(ar, peer); + peer->dp_setup_done = false; + crypto_free_shash(peer->tfm_mmic); ++ peer->dp_setup_done = false; + spin_unlock_bh(&ab->base_lock); + } + +--- a/drivers/net/wireless/ath/ath11k/peer.h ++++ b/drivers/net/wireless/ath/ath11k/peer.h +@@ -93,6 +93,7 @@ struct ath11k_peer { + u16 sec_type; + u16 sec_type_grp; + bool is_authorized; ++ /* Peer's datapath set flag */ + bool dp_setup_done; + struct ppdu_user_delayba ppdu_stats_delayba; + bool delayba_flag; diff --git a/package/kernel/mac80211/patches/ath11k_nss/913-356-ath11k-invalid-desc-sanity-check.patch b/package/kernel/mac80211/patches/ath11k_nss/913-356-ath11k-invalid-desc-sanity-check.patch new file mode 100644 index 00000000000000..4e7e37957b1f31 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/913-356-ath11k-invalid-desc-sanity-check.patch @@ -0,0 +1,74 @@ +From c7e37aebbe19056eb7b61299e75c863263acf2b9 Mon Sep 17 00:00:00 2001 +From: Nagarajan Maran +Date: Tue, 9 Aug 2022 13:22:43 +0530 +Subject: [PATCH] Fix SKB corruption in REO destination ring + +In the traffic cases, randomly, invalid RX descriptor +from REO destination ring is received. This +invalid descriptor causes wrong SKB to be fetched +which in turn causes SKB memory corruption issue. + +Introduced Sanity check to validate the descriptor, +before processing the SKB. + +During the failure scenario, invalid RX descriptor +filled with values "0" is received which in-turn +corrupts the SKB stored in the ldr lookup +with buffer id "0". Changed the start id for +idr allocation to "1" and the buffer id "0" is +reserved for error validation. + + +Crash Signature : + +Unable to handle kernel paging request at virtual address 3f004900 +During the crash, +PC points to "b15_dma_inv_range+0x30/0x50" +LR points to "dma_cache_maint_page+0x8c/0x128". +The Backtrace obtained is as follows: +[<8031716c>] (b15_dma_inv_range) from [<80313a4c>] (dma_cache_maint_page+0x8c/0x128) +[<80313a4c>] (dma_cache_maint_page) from [<80313b90>] (__dma_page_dev_to_cpu+0x28/0xcc) +[<80313b90>] (__dma_page_dev_to_cpu) from [<7fb5dd68>] (ath11k_dp_process_rx+0x1e8/0x4a4 [ath11k]) +[<7fb5dd68>] (ath11k_dp_process_rx [ath11k]) from [<7fb53c20>] (ath11k_dp_service_srng+0xb0/0x2ac [ath11k]) +[<7fb53c20>] (ath11k_dp_service_srng [ath11k]) from [<7f67bba4>] (ath11k_pci_ext_grp_napi_poll+0x1c/0x78 [ath11k_pci]) +[<7f67bba4>] (ath11k_pci_ext_grp_napi_poll [ath11k_pci]) from [<807d5cf4>] (__napi_poll+0x28/0xb8) +[<807d5cf4>] (__napi_poll) from [<807d5f28>] (net_rx_action+0xf0/0x280) +[<807d5f28>] (net_rx_action) from [<80302148>] (__do_softirq+0xd0/0x280) +[<80302148>] (__do_softirq) from [<80320408>] (irq_exit+0x74/0xd4) +[<80320408>] (irq_exit) from [<803638a4>] (__handle_domain_irq+0x90/0xb4) +[<803638a4>] (__handle_domain_irq) from [<805bedec>] (gic_handle_irq+0x58/0x90) +[<805bedec>] (gic_handle_irq) from [<80301a78>] (__irq_svc+0x58/0x8c) + +Signed-off-by: Nagarajan Maran +--- + drivers/net/wireless/ath/ath11k/dp_rx.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -3228,6 +3228,16 @@ try_again: + while (likely(desc = + (struct hal_reo_dest_ring *)ath11k_hal_srng_dst_get_next_entry(ab, + srng))) { ++ ++ push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON, ++ desc->info0); ++ if (unlikely(push_reason == ++ HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED)) { ++ ath11k_warn(ab,"Received invalid desc\n"); ++ ab->soc_stats.hal_reo_error[dp->reo_dst_ring[ring_id].ring_id]++; ++ continue; ++ } ++ + 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: + + num_buffs_reaped[mac_id]++; + +- push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON, +- desc->info0); + if (unlikely(push_reason != + HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION)) { + dev_kfree_skb_any(msdu); 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/ath11k_nss/913-374-ath11k-Check-skb_headroom-before-using-skb_push.patch new file mode 100644 index 00000000000000..1bbbdd6c7446da --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/913-374-ath11k-Check-skb_headroom-before-using-skb_push.patch @@ -0,0 +1,209 @@ +From efecc6e8355d02aeac7bf1a43397551440a8d0d8 Mon Sep 17 00:00:00 2001 +From: Tamizh Chelvam Raja +Date: Thu, 30 Mar 2023 22:12:56 +0530 +Subject: [PATCH] ath11k: Check skb_headroom before using skb_push + +Below kernel panic may occur if there is no +skb_headroom available for performing skb_push. + +<4>[67506.565072] CPU: 1 PID: 1741 Comm: ap-wireless-opt Not tainted 5.4.89+ #0 +<4>[67506.578860] Hardware name: Generic DT based system +<4>[67506.585728] PC is at fortify_panic+0x10/0x18 +<4>[67506.590406] LR is at fortify_panic+0x10/0x18 + +(fortify_panic) from [<7f2cd3cc>] (ath11k_dp_rx_crypto_icv_len+0x1e0/0x161c [ath11k]) +(ath11k_dp_rx_crypto_icv_len [ath11k]) from [<7f2cdbac>] (ath11k_dp_rx_crypto_icv_len+0x9c0/0x161c [ath11k]) +(ath11k_dp_rx_crypto_icv_len [ath11k]) from [<7f2ce0e8>] (ath11k_dp_rx_crypto_icv_len+0xefc/0x161c [ath11k]) +(ath11k_dp_rx_crypto_icv_len [ath11k]) from [<7f2cedb0>] (ath11k_dp_process_rx+0x4ec/0x544 [ath11k]) +(ath11k_dp_process_rx [ath11k]) from [<7f2c417c>] (ath11k_dp_service_srng+0xdc/0x2a0 [ath11k]) +(ath11k_dp_service_srng [ath11k]) from [<7f0d78c8>] (ath11k_pci_ext_grp_napi_poll+0x20/0x50 [ath11k_pci]) +(ath11k_pci_ext_grp_napi_poll [ath11k_pci]) from [<806a6a74>] (__napi_poll+0x28/0xb8) +(__napi_poll) from [<806a6c9c>] (net_rx_action+0xec/0x280) +(net_rx_action) from [<8010226c>] (__do_softirq+0xc4/0x248) +(__do_softirq) from [<8011f230>] (irq_exit+0x6c/0xcc) +(irq_exit) from [<80162a08>] (__handle_domain_irq+0x8c/0xb0) +(__handle_domain_irq) from [<803f0188>] (gic_handle_irq+0x54/0x8c) +(gic_handle_irq) from [<80101a8c>] (__irq_svc+0x6c/0xa8) + +Fix this by checking skb_headroom and expand the +headroom if required size is not available. + +Signed-off-by: Tamizh Chelvam Raja +--- + drivers/net/wireless/ath/ath11k/dp_rx.c | 70 +++++++++++++++++++++++++ + 1 file changed, 70 insertions(+) + +--- 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 + size_t hdr_len, crypto_len; + struct ieee80211_hdr *hdr; + u16 fc, qos_ctl = 0; ++ int expand_by; + u8 *crypto_hdr; + + if (!(status->flag & RX_FLAG_IV_STRIPPED)) { + crypto_len = ath11k_dp_rx_crypto_param_len(ar, enctype); ++ if (skb_headroom(msdu) < crypto_len) { ++ expand_by = crypto_len - skb_headroom(msdu); ++ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) ++ return; ++ } + crypto_hdr = skb_push(msdu, crypto_len); + ath11k_dp_rx_desc_get_crypto_header(ab, rx_desc, crypto_hdr, enctype); + } + + fc = ath11k_dp_rxdesc_get_mpdu_frame_ctrl(ab, rx_desc); + hdr_len = ieee80211_hdrlen(fc); ++ 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; ++ } + 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 + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + u16 qos_ctl = 0; ++ int expand_by = 0; + u8 *qos, *crypto_hdr; + bool add_qos_ctrl = false; + +@@ -2359,26 +2371,46 @@ static void ath11k_dp_rx_h_undecap_nwifi + } + + if (!(status->flag & RX_FLAG_IV_STRIPPED)) { ++ 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; ++ } + if (first_hdr) { +- memcpy(skb_push(msdu, +- ath11k_dp_rx_crypto_param_len(ar, enctype)), +- (void *)hdr + hdr_len, +- ath11k_dp_rx_crypto_param_len(ar, enctype)); ++ memcpy(skb_push(msdu, crypto_param_len), ++ (void *)hdr + hdr_len, crypto_param_len); + } else { +- crypto_hdr = skb_push(msdu, ath11k_dp_rx_crypto_param_len(ar, enctype)); ++ crypto_hdr = skb_push(msdu, crypto_param_len); + ath11k_dp_rx_desc_get_crypto_header(ar->ab, + rxcb->rx_desc, crypto_hdr, enctype); + } + } + + if (!rxcb->is_first_msdu || add_qos_ctrl) { ++ if (skb_headroom(msdu) < IEEE80211_QOS_CTL_LEN) { ++ expand_by = IEEE80211_QOS_CTL_LEN - skb_headroom(msdu); ++ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) ++ return; ++ } + memcpy(skb_push(msdu, + IEEE80211_QOS_CTL_LEN), &qos_ctl, + IEEE80211_QOS_CTL_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), decap_hdr, hdr_len); + return; + } + ++ 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); + + /* original 802.11 header has a different DA and in +@@ -2487,6 +2519,7 @@ static void ath11k_dp_rx_h_undecap_eth(s + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + void *rfc1042; ++ int expand_by; + 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 + ether_addr_copy(sa, eth->h_source); + rfc.snap_type = eth->h_proto; + skb_pull(msdu, sizeof(struct ethhdr)); ++ if (skb_headroom(msdu) < sizeof(struct ath11k_dp_rfc1042_hdr)) { ++ expand_by = sizeof(struct ath11k_dp_rfc1042_hdr) - skb_headroom(msdu); ++ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) ++ return; ++ } + 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 + skb_pull(msdu, sizeof(struct ethhdr)); + + /* push rfc1042/llc/snap */ ++ if (skb_headroom(msdu) < sizeof(struct ath11k_dp_rfc1042_hdr)) { ++ expand_by = sizeof(struct ath11k_dp_rfc1042_hdr) - skb_headroom(msdu); ++ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) ++ return; ++ } + 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 + 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); + + exit: +@@ -2954,10 +3007,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; ++ int expand_by; + + if (status->encoding == RX_ENC_HE && + !(status->flag & RX_FLAG_RADIOTAP_HE) && + !(status->flag & RX_FLAG_SKIP_MONITOR)) { ++ if (skb_headroom(msdu) < sizeof(known)) { ++ expand_by = sizeof(known) - skb_headroom(msdu); ++ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) ++ goto exit; ++ } + 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 + !(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/ath11k_nss/913-686-mac80211-fix-RCU-stall-in-mesh-fast-xmit-path.patch b/package/kernel/mac80211/patches/ath11k_nss/913-686-mac80211-fix-RCU-stall-in-mesh-fast-xmit-path.patch new file mode 100644 index 00000000000000..6614d8d496b354 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/913-686-mac80211-fix-RCU-stall-in-mesh-fast-xmit-path.patch @@ -0,0 +1,120 @@ +From 331198f889cef552e4644abf1f2ebfcaa2cc41e9 Mon Sep 17 00:00:00 2001 +From: P Praneesh +Date: Wed, 23 Nov 2022 18:50:47 +0530 +Subject: [PATCH] mac80211: fix RCU stall in mesh fast xmit path + +In mesh fast xmit, mesh_fill_cached_hdr tries to acquire spinlock +which is already acquired by the same core for updating mesh path +table. Fix it by using atomic variable instead of using spinlock. + +[100466.097939] rcu: INFO: rcu_preempt self-detected stall on CPU +[100466.097962] rcu: 0-....: (8381 ticks this GP) idle=e86/0/0x3 softirq=2648463/2648463 fqs=4184 +[100466.102651] (t=8403 jiffies g=5521597 q=620) +[100466.111586] Task dump for CPU 0: +[100466.115839] swapper/0 R running task 0 0 0 0x0000000a +[100466.119228] Call trace: +[100466.126348] dump_backtrace+0x0/0x15c +[100466.128949] show_stack+0x14/0x1c +[100466.132508] sched_show_task+0x104/0x134 +[100466.135893] dump_cpu_task+0x40/0x274 +[100466.139974] rcu_dump_cpu_stacks+0x7c/0xd4 +[100466.143620] rcu_sched_clock_irq+0x350/0x824 +[100466.147699] update_process_times+0x2c/0x50 +[100466.152213] tick_sched_handle.isra.4+0x3c/0x44 +[100466.156553] tick_sched_timer+0x48/0x88 +[100466.161153] __hrtimer_run_queues+0xa0/0x140 +[100466.165059] hrtimer_interrupt+0xe4/0x214 +[100466.169315] arch_timer_handler_virt+0x28/0x3c +[100466.173308] handle_percpu_devid_irq+0x84/0x12c +[100466.177733] generic_handle_irq+0x18/0x2c +[100466.182593] __handle_domain_irq+0x84/0xac +[100466.186500] gic_handle_irq+0x74/0xbc +[100466.190579] el1_irq+0xf0/0x1c0 +[100466.194398] queued_spin_lock_slowpath+0x98/0x2c0 +[100466.197800] mesh_fill_cached_hdr+0x15c/0x2d0 [mac80211] +[100466.202397] __ieee80211_subif_start_xmit+0xf4/0xf3c [mac80211] +[100466.207865] ieee80211_subif_start_xmit+0x274/0x2ac [mac80211] +[100466.213933] dev_hard_start_xmit+0x1b0/0x230 +[100466.219574] sch_direct_xmit+0xbc/0x300 +[100466.224086] __dev_queue_xmit+0x5b0/0x8cc +[100466.228079] dev_queue_xmit+0x10/0x18 +[100466.231990] sfe_ipv4_recv_udp+0x1014/0x1050 [qca_nss_sfe] +[100466.235722] sfe_ipv4_recv+0x394/0x5a4 [qca_nss_sfe] +[100466.241190] sfe_recv+0xf0/0x47c [qca_nss_sfe] +[100466.246397] __netif_receive_skb_core+0x1ac/0xa3c +[100466.250736] __netif_receive_skb_list_core+0x84/0x1ec +[100466.255598] netif_receive_skb_list_internal+0x250/0x29c +[100466.260720] gro_normal_list+0x24/0x40 +[100466.266186] gro_normal_one+0x3c/0x48 +[100466.269832] napi_gro_receive+0xc0/0x104 +[100466.273655] edma_rx_napi_poll+0x820/0xdb4 [qca_nss_dp] +[100466.277734] __napi_poll+0x30/0xa4 +[100466.283113] net_rx_action+0x118/0x270 +[100466.286325] __do_softirq+0x10c/0x244 +[100466.290145] irq_exit+0x64/0xb4 +[100466.293965] __handle_domain_irq+0x88/0xac +[100466.297350] gic_handle_irq+0x74/0xbc +[100466.301256] el1_irq+0xf0/0x1c0 +[100466.305076] arch_cpu_idle+0x10/0x18 +[100466.308461] do_idle+0x104/0x248 +[100466.312019] cpu_startup_entry+0x20/0x64 +[100466.315320] rest_init+0xd0/0xdc +[100466.319311] arch_call_rest_init+0xc/0x14 +[100466.322610] start_kernel+0x480/0x4b8 + +Signed-off-by: P Praneesh +--- + net/mac80211/cfg.c | 2 +- + net/mac80211/mesh.h | 4 ++-- + net/mac80211/mesh_hwmp.c | 4 ++-- + net/mac80211/mesh_pathtbl.c | 9 ++++----- + 4 files changed, 9 insertions(+), 10 deletions(-) + +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -2347,7 +2347,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; +- pinfo->path_change_count = mpath->path_change_count; ++ pinfo->path_change_count = atomic_read(&mpath->path_change_count); + } + + static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev, +--- a/net/mac80211/mesh.h ++++ b/net/mac80211/mesh.h +@@ -126,7 +126,7 @@ struct mesh_path { + unsigned long fast_tx_check; + bool is_root; + bool is_gate; +- u32 path_change_count; ++ atomic_t path_change_count; + }; + + #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 + 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 + 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/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 new file mode 100644 index 00000000000000..8e60a5f6b255f7 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/913-726-mac80211-fix-crash-when-accessing-null-pointer.patch @@ -0,0 +1,87 @@ +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/ath11k_nss/913-830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch b/package/kernel/mac80211/patches/ath11k_nss/913-830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch new file mode 100644 index 00000000000000..28b4fdf6468337 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k_nss/913-830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch @@ -0,0 +1,87 @@ +From 5b4a0de1356558f58df9c6a1f46c7c0ce2fadb03 Mon Sep 17 00:00:00 2001 +From: Yuvasree Sivasankaran +Date: Mon, 28 Aug 2023 14:48:41 +0530 +Subject: [PATCH] ath11k: Avoiding memset of ppdu-info for next skb + +While parsing mon status from skb, ppdu_info got memset with zero during +next skb fetch from queue or mon ring in case a single PPDU is more than +RX_BUFFER_SIZE. Because of this nss value got override for respective +ppdu and leads to warn_on in mac80211.Removed memset from next skb fetch +and added flag to track discontinued skb in case of fetch from skb. + +WARN_ON Reason: + +Rate marked as an HE rate but data is invalid: MCS: 0, NSS: 0 + +Below the call trace observed: + + Call trace: + ieee80211_rx_list+0x1d4/0xcc4 [mac80211] + ieee80211_rx_napi+0x58/0xcc [mac80211] + ath11k_dp_rx_deliver_msdu+0x358/0x3e4 [ath11k] + ath11k_dp_rx_mon_deliver.isra.27+0x470/0x4cc [ath11k] + ath11k_dp_rx_mon_dest_process+0x1cc/0x2bc [ath11k] + ath11k_dp_rx_process_mon_status+0x5ec/0xf90 [ath11k] + ath11k_dp_rx_process_mon_rings+0x40c/0x44c [ath11k] + ath11k_dp_service_srng+0x114/0x2c0 [ath11k] + ath11k_ahb_ext_grp_napi_poll+0x30/0xa0 [ath11k_ahb] + __napi_poll+0x30/0xa4 + net_rx_action+0x118/0x270 + __do_softirq+0x10c/0x244 + irq_exit+0x64/0xb4 + __handle_domain_irq+0x88/0xac + gic_handle_irq+0x74/0xbc + el1_irq+0xf0/0x1c0 + arch_cpu_idle+0x10/0x18 + do_idle+0x104/0x248 + cpu_startup_entry+0x20/0x64 + rest_init+0xd0/0xdc + arch_call_rest_init+0xc/0x14 + start_kernel+0x46c/0x4a4 + --[ end trace e754e9088a240857 ]--- + +Signed-off-by: Yuvasree Sivasankaran +--- + drivers/net/wireless/ath/ath11k/dp_rx.c | 6 ++++-- + drivers/net/wireless/ath/ath11k/hal_rx.h | 1 + + 2 files changed, 5 insertions(+), 2 deletions(-) + +--- 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 + if (!num_buffs_reaped) + goto exit; + +- memset(ppdu_info, 0, sizeof(*ppdu_info)); ++ if (!ppdu_info->ppdu_continuation) ++ memset(ppdu_info, 0, sizeof(*ppdu_info)); ++ + 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 + if (log_type != ATH11K_PKTLOG_TYPE_INVALID) + trace_ath11k_htt_rxdesc(ar, skb->data, log_type, rx_buf_sz); + +- memset(ppdu_info, 0, sizeof(*ppdu_info)); + 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) { + dev_kfree_skb_any(skb); ++ ppdu_info->ppdu_continuation = true; + continue; + } + +--- 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]; + 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]; + }; + From b607770203bbf30b7c8054f2008994c3e98b09dc Mon Sep 17 00:00:00 2001 From: Qosmio Date: Wed, 17 Jan 2024 05:04:28 -0500 Subject: [PATCH 204/225] ath11k_nss: set pbuf script off by default uci option pbuf.opt.memory_profile must be explicity set to auto, 1gb, 512m, 256m to run. --- .../mac80211/files/etc/init.d/qca-nss-pbuf | 16 +++++++++++----- package/kernel/mac80211/files/pbuf.uci | 3 ++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf index be89de061ce8b1..02afd5f6c3d380 100755 --- a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf +++ b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf @@ -50,15 +50,21 @@ apply_nss_config() { board=$memory_profile logger -t ath11k_nss "Using custom memory profile - $board" ;; - *) - logger -s -t ath11k_nss -p user.error "Unknown profile $memory_profile. Choose 1gb, 512mb, or 256mb" + off*|false*|disable*|0) + logger -s -t ath11k_nss -p user.warn "NSS pbuf option 'memory_profile=off'. Not running. Enable if you have issues connecting more than 65 clients" + exit 0 + ;; + auto) board=$(board_name) - logger -s -t ath11k_nss -p user.warn "Falling back to: $board" + logger -t ath11k_nss "Setting n2hcfg values for board: $board" + ;; + *) + logger -s -t ath11k_nss -p user.error "Unknown profile $memory_profile. Choose auto, 1gb, 512mb, or 256mb" + exit 1 ;; esac else - board=$(board_name) - logger -t ath11k_nss "Setting n2hcfg values for board: $board" + exi 0 fi case "$board" in diff --git a/package/kernel/mac80211/files/pbuf.uci b/package/kernel/mac80211/files/pbuf.uci index ac4fadbc4f5e63..2b277e11f02f4d 100644 --- a/package/kernel/mac80211/files/pbuf.uci +++ b/package/kernel/mac80211/files/pbuf.uci @@ -1,5 +1,6 @@ config general opt - # to bypass board autodetection, uncomment ONE of the options below + option memory_profile 'off' + # option memory_profile 'auto' # option memory_profile '1gb' # option memory_profile '512mb' # option memory_profile '256mb' From 74d8a3c23e654ce0de43ea666c846c6d02f4e4ff Mon Sep 17 00:00:00 2001 From: Qosmio Date: Wed, 17 Jan 2024 15:45:10 -0500 Subject: [PATCH 205/225] ath11k_nss: Refresh patches ath11k_nss: fix build for 256/1G mem, and ath10k ath11k_nss: bump release version '8' mac80211: refactor NSS patches Since NSS requires patches to subsys, and ath*k directories. Move patches into a subset of nss for better tracking against QSDK, and modularization. ath11k_nss: rename patches ath11k_nss: clean up optional patches To reduce bug tracking headaches, I've remove the following patches, as they are not required for NSS offload and have been around the last 2-3 years without ever being upstreamed. nss/ath11k/235-001-ath11k-Add-support-for-beacon-tx-mode.patch nss/ath11k/237-002-ath11k-Add-provision-to-configure-rx-hashmap.patch nss/ath11k/902-020-ath11k-add-btcoex-config.patch nss/ath11k/902-022-ath11k-add-ap-ps-support.patch nss/ath11k/907-068-ath11k-add-rx-histogram-stats.patch nss/ath11k/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch nss/ath11k/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch nss/ath11k/913-353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch nss/ath11k/913-356-ath11k-invalid-desc-sanity-check.patch nss/ath11k/913-374-ath11k-Check-skb_headroom-before-using-skb_push.patch nss/ath11k/913-830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch nss/subsys/235-002-mac80211-Add-support-for-beacon-tx-mode.patch nss/subsys/913-726-mac80211-fix-crash-when-accessing-null-pointer.patch ath11k_nss: Remove superfluous patches Remove patches unrelated to NSS offloading to minimize bloat and better track NSS related issues. ath11k_nss: Refactor patches to use upstream names Reworked patches to use upstream QSDK names. Allows for better tracking ath11k_nss: align wifi offload with qca-nss-drv The option in qca-nss-drv is actually 'NSS_DRV_WIFIOFFLOAD_ENABLE' use the same syntax. ath10k-ct: fix compile with NSS wifi ath11k_nss: Merge every NSS related feature + more * Added macro to disable NSS mesh offload * Added menuconfig option "ATH11K_NSS_MESH_SUPPORT" to selectivley build mesh support, as well it's depenacndy on nss-drv-wifimeshmgr. * Added option to disable HTT Stats, and STA stats (stations). * Reducing footprint by ~210KB. Debugfs minimal is still enabled. * Reworked a TON of patches, some my own, hopefully there should be a far less amount of WOA2/WPA3 connection issues. * Updated the /etc/init.d/pbuf script to be more robust. (handles tweaking ath11k and NSS settings better) NOTES: Although mesh package builds (nss-drv-wifimeshmgr), ath11k doesn't seem to support it yet. Not sure if NSS requires 3 radios to work, I'm at a dead end currently with that route. ATTENTION: the ptch `37-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch` works well on nss with frame_mode=2. And on `ath11k frame_mode=1 nss_offload=0` And on `ath11k frame_mode=2 nss_offload=1` if you set nss_offload=off and frame_mode=2, it will CRASH if you set nss_offload=on and frame_mode=2, it will RUN if you set nss_offload=off and frame_mode=1, it will RUN ath11k_nss: fix n2h high_water_core0/wifi_pool_buf These were commented out, but looks like they are needed to prevent lock ups with heavy usage apps (users report in torrenting) ath11k_nss: Renumber ath11k patches in the range commit 3c7cc4b725ea406f19b736427034e3bdb436aedc Author: Yuvasree Sivasankaran AuthorDate: Thu Jan 4 11:25:56 2024 +0530 Commit: Yuvasree Sivasankaran CommitDate: Wed Jan 3 22:53:51 2024 -0800 wifi: ath11k: Renumber ath11k patches in the range In ath11k, patches are not maintained in the range and not sequential. Renumber the patches sequential and in the range. Change-Id: I77c51c0f5bf9f94863db4ef364b156e14465a60c Signed-off-by: Yuvasree Sivasankaran ath11k_nss: Add mac hw flag to avoid tx queue in mac80211 commit 4e9b5f7f0d1ed40dbf3208f7ed4448e49b4a4ac1 Author: Yuvasree Sivasankaran AuthorDate: Wed Dec 6 12:20:59 2023 +0530 Commit: Yuvasree Sivasankaran CommitDate: Mon Dec 18 12:52:33 2023 +0530 wifi: mac80211: Add mac hw flag to avoid tx queue in mac80211 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. ath11k_nss: add the HTC+ / iPhone fix commit ccdca73cd65723c3cb63c17edc95c4c43318cb38 Author: John Crispin AuthorDate: Sun Jul 9 17:12:34 2023 +0200 Commit: John Crispin CommitDate: Thu Aug 31 16:08:34 2023 +0200 mac80211: add the HTC+ / iPhone fix Signed-off-by: John Crispin ath11k_nss: ath-next fix connection failure due to unexpected peer delete 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. Also do some cleanups in patch "wifi: ath11k: remove invalid peer create logic", and refactor in patches "wifi: ath11k: rename ath11k_start_vdev_delay()" and "wifi: ath11k: avoid forward declaration of ath11k_mac_start_vdev_delay()". Tested this patch set using QCA6390 and WCN6855 on both STA and SAP interfaces. Basic connection and ping work well. Baochen Qiang (4): wifi: ath11k: remove invalid peer create logic wifi: ath11k: rename ath11k_start_vdev_delay() wifi: ath11k: avoid forward declaration of ath11k_mac_start_vdev_delay() wifi: ath11k: fix connection failure due to unexpected peer delete drivers/net/wireless/ath/ath11k/mac.c | 564 +++++++++++++------------- 1 file changed, 288 insertions(+), 276 deletions(-) ath11k_nss: Revert support for beacon_tx_mode ath11k_nss: Update release fix dependancies ath11k_nss: mgmt and data ack rssi update Data ACK RSSI : Advertise NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT feature support for accounting and notifying "last ack signal" and "avg ack signal" to user space through NL interface. Enabled data ack rssi support for ethernet mode. Mgmt ACK RSSI: Enabled support for Tx-ACK RSSI in HTT over Management packets. --- .../999-003-ath10k-add-nss-support.patch | 32 + package/kernel/mac80211/Makefile | 18 +- package/kernel/mac80211/ath.mk | 48 +- .../mac80211/files/etc/init.d/qca-nss-pbuf | 68 +- .../107-ath11k-tid-counter-fix.patch | 21 - .../211-ath11k-add-obss-pd-support.patch | 56 - ...11k-Disable-rx_header-tlv-for-2K-SKB.patch | 920 ----- ...01-ath11k-account-tx-rx-packets-flow.patch | 494 --- ...-mac80211-account-tx-rx-packets-flow.patch | 369 -- ...th11k-Add-support-for-beacon-tx-mode.patch | 45 - ...80211-Add-support-for-beacon-tx-mode.patch | 159 - ...dd-provision-to-configure-rx-hashmap.patch | 208 - .../245-revert-dev-sw-netstats-txrx-add.patch | 145 - ...-nss-thread-priority-during-pdev_ini.patch | 109 - .../640-006-mac80211-add-eht-radiotap.patch | 506 --- ...interface-combination-advertisement-.patch | 1594 -------- .../702-ath11k-fix-memory-leak-in-dp-rx.patch | 48 - .../902-020-ath11k-add-btcoex-config.patch | 612 --- .../902-022-ath11k-add-ap-ps-support.patch | 324 -- ...04-300-ath11k-nss_get_arvif_from_dev.patch | 113 - .../905-ath11k-add-support-memory-stats.patch | 946 ----- ...1k-add-simple-tx-handler-for-AP-mode.patch | 185 - .../911-335-ath11k-fix-ar-ops-crash.patch | 71 - ...k-skb_headroom-before-using-skb_push.patch | 209 - ...ix-crash-when-accessing-null-pointer.patch | 87 - .../199-004-ath10k-fixup-nss-compile.patch | 19 + ...th11k-fix-for-peer-memory-corruption.patch | 0 .../068-ath11k-add-rx-histogram-stats.patch} | 135 +- ...9-ath11k-add-HE-stats-in-peer-stats.patch} | 74 +- ...080-ath11k-ethernet-rx-decap-offload.patch | 15 + ...dma-counter-always-zero-in-peer-stat.patch | 82 + ...dma-counter-increamenting-improperly.patch | 2 +- ...l-ofdma-ru-allocation-in-peer-stats.patch} | 51 +- .../113-ath11k-add-8023-undecap-support.patch | 4 +- ...-adding-support-for-mgmt-frame-stats.patch | 24 +- ...1k-remove-error-on-soc-debugfs-fail.patch} | 40 +- .../188-ath11k-m3-ssr-dump-collection.patch} | 0 ...91-ath11k-add-mgmt-and-data-ack-rssi.patch | 27 - ...-ath11k_nss-add-nss-driver-interface.patch | 31 +- .../199-003-ath11k-add-nss-support.patch | 323 +- ...-ath11k-Add-support-for-dynamic-vlan.patch | 4 +- ...207-ath11k-Enable-256_512MB-profiles.patch | 164 +- ...oad-changes-to-NSS-driver-interface.patch} | 30 +- ...support-on-NSS-offload-for-STA-mode.patch} | 86 +- ...14-ath11k-qos-null-frame-tx-over-wmi.patch | 181 +- ...rt-to-enable-disable-color-collision.patch | 46 + ...dev-in-NSS-for-AP_VLAN-vif-handling.patch} | 48 +- ...port-for-WDS-offload-in-NSS-offload.patch} | 77 +- ...ev-in-NSS-for-dynamic-VLAN-handling.patch} | 18 +- ...dynamic-VLAN-support-in-NSS-offload.patch} | 50 +- ...ow-fast-rx-by-bypassing-stats-update.patch | 102 + ...dst-ring-descriptors-from-cacheable-.patch | 6 +- ...ow-fast-rx-by-bypassing-stats-update.patch | 191 +- .../ath11k/244-ath11k-dp-tx-perf.patch} | 100 +- .../patches/nss/ath11k/270-iphone-issue.patch | 11 + .../300-ath11k-nss-mesh-offload-support.patch | 3365 +++++++++++++++++ .../301-ath11k-nss-mcbc-exception.patch} | 80 +- ...lookup-failure-in-mgmt-tx-completion.patch | 125 + ...avoid-stack-corrupt-in-nwifi-undecap.patch | 0 ...e-free-of-peer-rx_tid-during-reo-cmd.patch | 2 +- ...0-ath11k-sync-wds_ast_entry-updates.patch} | 45 +- ...0001-ath11k-optimize-tx-completions.patch} | 52 +- ...e-DECLARE_BITMAP-for-idr-operations.patch} | 32 +- ...TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch | 19 +- ...ing-rx-stats-with-monitor-vif-enable.patch | 88 + ...1k-skip-status-ring-entry-processing.patch | 10 +- ...t-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch} | 2 +- ...ccess-of-the-dma-buffer-back-to-dma-.patch | 0 ...frags-from-uninitialized-peer-in-dp.patch} | 2 +- ...56-ath11k-invalid-desc-sanity-check.patch} | 15 +- ...-fix-clear-peer-keys-during-disassoc.patch | 4 +- ...-fix-tkip-encryption-traffic-failure.patch | 2 +- ...t-ast-index-assignment-for-wds-peer.patch} | 15 +- ...Fix-ppdu_id-from-firmware-PPDU-stats.patch | 52 + ...dd-retry-mechanism-for-update_rx_qu.patch} | 30 +- ...treaming-not-working-for-wan-to-wlan.patch | 49 + ...-event-handler-support-for-link-desc.patch | 6 +- ...th11k-Advertise-TX_QUEUE-mac-hw-flag.patch | 28 + ...id-memset-of-ppdu-info-for-next-skb.patch} | 12 +- ...upport-to-send-the-QoS-Null-Data-fr.patch} | 7 +- ...11k-remove-invalid-peer-create-logic.patch | 58 + ...th11k-rename-ath11k_start_vdev_delay.patch | 52 + ...ation-of-ath11k_mac_start_vdev_delay.patch | 601 +++ ...ailure-due-to-unexpected-peer-delete.patch | 257 ++ ...k-make-debugfs-sta-htt-stats-modular.patch | 198 + .../subsys/007-fix_compilation_issue.patch} | 74 +- ...-when-using-encapsulation-offloading.patch | 0 .../199-001-mac80211-add-nss-support.patch | 4 +- ...t-callback-when-hwencap-enable-in-st.patch | 0 ...03-mac80211-ath11k-fw-dynamic-muedca.patch | 203 + ...ath11k-Add-support-for-dynamic-vlan.patch} | 0 ...07-mac80211-add-nss-redirect-support.patch | 0 ...-iftype-support-on-NSS-offload-case.patch} | 28 +- ...dynamic-VLAN-support-on-NSS-offload.patch} | 32 +- .../subsys}/245-compilation_fix.patch | 13 +- ...300-ath11k-nss-mesh-offload-support.patch} | 57 +- ...CL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch} | 4 +- ...-0005-mac80211-simple-tx-for-AP-mode.patch | 7 +- .../336-mac80211-Mesh-Fast-rx-support.patch | 10 +- ...mac80211-fix-unconditional-sta-usage.patch | 17 +- .../345-mac80211-fix-mixed-declaration.patch | 57 + ...change-to-40Mhz-during-channel-switc.patch | 39 + ...rning-with-monitor-interface-restart.patch | 2 +- ...unused-RX_FLAGS-from-mac80211_rx_fla.patch | 6 +- ...ncapsulation-of-EAPOL-frames-if-OFFL.patch | 89 +- ...ix-RCU-stall-in-mesh-fast-xmit-path.patch} | 12 +- ...-the-frame-to-driver-tx-ops-directly.patch | 4 +- ...se-HW-checksum-offload-only-for-ethm.patch | 18 +- ...1-Add-mac-hw-flag-to-avoid-queue-skb.patch | 342 ++ .../829-mac80211-fix-mesh-ping-issue.patch | 8 +- ...x-memory-corruption-during-mesh-beac.patch | 0 111 files changed, 6921 insertions(+), 8641 deletions(-) create mode 100644 package/kernel/ath10k-ct/patches/999-003-ath10k-add-nss-support.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/107-ath11k-tid-counter-fix.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/211-ath11k-add-obss-pd-support.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/234-001-ath11k-account-tx-rx-packets-flow.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/234-002-mac80211-account-tx-rx-packets-flow.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/235-001-ath11k-Add-support-for-beacon-tx-mode.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/235-002-mac80211-Add-support-for-beacon-tx-mode.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/237-002-ath11k-Add-provision-to-configure-rx-hashmap.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/245-revert-dev-sw-netstats-txrx-add.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/640-006-mac80211-add-eht-radiotap.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/675-01-cfg80211-Extend-interface-combination-advertisement-.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/702-ath11k-fix-memory-leak-in-dp-rx.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/902-020-ath11k-add-btcoex-config.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/902-022-ath11k-add-ap-ps-support.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/904-300-ath11k-nss_get_arvif_from_dev.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/905-ath11k-add-support-memory-stats.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/911-335-0006-ath11k-add-simple-tx-handler-for-AP-mode.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/911-335-ath11k-fix-ar-ops-crash.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/913-374-ath11k-Check-skb_headroom-before-using-skb_push.patch delete mode 100644 package/kernel/mac80211/patches/ath11k_nss/913-726-mac80211-fix-crash-when-accessing-null-pointer.patch create mode 100644 package/kernel/mac80211/patches/nss/ath10k/199-004-ath10k-fixup-nss-compile.patch rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/033-ath11k-fix-for-peer-memory-corruption.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss/907-068-ath11k-add-rx-histogram-stats.patch => nss/ath11k/068-ath11k-add-rx-histogram-stats.patch} (84%) rename package/kernel/mac80211/patches/{ath11k_nss/902-069-ath11k-add-HE-stats-in-peer-stats.patch => nss/ath11k/069-ath11k-add-HE-stats-in-peer-stats.patch} (93%) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/080-ath11k-ethernet-rx-decap-offload.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/084-ath11k-fix-ul-ofdma-counter-always-zero-in-peer-stat.patch rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/087-ath11k-fix-ul-ofdma-counter-increamenting-improperly.patch (96%) rename package/kernel/mac80211/patches/{ath11k_nss/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch => nss/ath11k/108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch} (91%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/113-ath11k-add-8023-undecap-support.patch (92%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/142-ath11k-adding-support-for-mgmt-frame-stats.patch (93%) rename package/kernel/mac80211/patches/{ath11k_nss/907-ath11k-remove-error-on-soc-debugfs-fail.patch => nss/ath11k/181-ath11k-remove-error-on-soc-debugfs-fail.patch} (88%) rename package/kernel/mac80211/patches/{ath11k_nss/906-ath11k-m3-ssr-dump-collection.patch => nss/ath11k/188-ath11k-m3-ssr-dump-collection.patch} (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/191-ath11k-add-mgmt-and-data-ack-rssi.patch (57%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/199-002-ath11k_nss-add-nss-driver-interface.patch (99%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/199-003-ath11k-add-nss-support.patch (82%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/207-ath11k-Add-support-for-dynamic-vlan.patch (99%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/207-ath11k-Enable-256_512MB-profiles.patch (70%) rename package/kernel/mac80211/patches/{ath11k_nss/902-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch => nss/ath11k/211-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch} (96%) rename package/kernel/mac80211/patches/{ath11k_nss/902-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch => nss/ath11k/211-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch} (93%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/214-ath11k-qos-null-frame-tx-over-wmi.patch (58%) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/218-ath11k-add-support-to-enable-disable-color-collision.patch rename package/kernel/mac80211/patches/{ath11k_nss/903-002-ath11k-add-support-for-ext-vdev-in-NSS-for-AP_VLAN-vif-handling.patch => nss/ath11k/235-002-ath11k-add-support-for-ext-vdev-in-NSS-for-AP_VLAN-vif-handling.patch} (93%) rename package/kernel/mac80211/patches/{ath11k_nss/903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch => nss/ath11k/235-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch} (88%) rename package/kernel/mac80211/patches/{ath11k_nss/904-002-ath11k-extend-ext-vdev-in-NSS-for-dynamic-VLAN-handling.patch => nss/ath11k/236-002-ath11k-extend-ext-vdev-in-NSS-for-dynamic-VLAN-handling.patch} (92%) rename package/kernel/mac80211/patches/{ath11k_nss/904-003-ath11k-add-dynamic-VLAN-support-in-NSS-offload.patch => nss/ath11k/236-003-ath11k-add-dynamic-VLAN-support-in-NSS-offload.patch} (91%) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/237-001-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/237-003-ath11k-allocate-dst-ring-descriptors-from-cacheable-.patch (96%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch (70%) rename package/kernel/mac80211/patches/{ath11k_nss/911-244-ath11k-dp-tx-perf.patch => nss/ath11k/244-ath11k-dp-tx-perf.patch} (88%) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/270-iphone-issue.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/300-ath11k-nss-mesh-offload-support.patch rename package/kernel/mac80211/patches/{ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch => nss/ath11k/301-ath11k-nss-mcbc-exception.patch} (69%) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/314-ath11k-Fix-peer-lookup-failure-in-mgmt-tx-completion.patch rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/318-ath11k-avoid-stack-corrupt-in-nwifi-undecap.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/319-ath11k-fix-double-free-of-peer-rx_tid-during-reo-cmd.patch (96%) rename package/kernel/mac80211/patches/{ath11k_nss/908-330-ath11k-sync-wds_ast_entry-updates.patch => nss/ath11k/330-ath11k-sync-wds_ast_entry-updates.patch} (94%) rename package/kernel/mac80211/patches/{ath11k_nss/911-335-0001-ath11k-optimize-tx-completions.patch => nss/ath11k/335-0001-ath11k-optimize-tx-completions.patch} (82%) rename package/kernel/mac80211/patches/{ath11k_nss/911-335-0002-ath11k-use-DECLARE_BITMAP-for-idr-operations.patch => nss/ath11k/335-0002-ath11k-use-DECLARE_BITMAP-for-idr-operations.patch} (90%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/335-0003-ath11k-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch (81%) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/336-ath11k-Fix-updating-rx-stats-with-monitor-vif-enable.patch rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/336-ath11k-skip-status-ring-entry-processing.patch (95%) rename package/kernel/mac80211/patches/{ath11k_nss/913-341-ath11k-fix-support-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch => nss/ath11k/341-ath11k-fix-support-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch} (97%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/342-ath11k-provide-access-of-the-dma-buffer-back-to-dma-.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss/913-353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch => nss/ath11k/353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch} (98%) rename package/kernel/mac80211/patches/{ath11k_nss/913-356-ath11k-invalid-desc-sanity-check.patch => nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch} (86%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/357-ath11k-fix-clear-peer-keys-during-disassoc.patch (92%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/359-ath11k-fix-tkip-encryption-traffic-failure.patch (93%) rename package/kernel/mac80211/patches/{ath11k_nss/908-362-ath11k-fix-incorrect-ast-index-assignment-for-wds-peer.patch => nss/ath11k/362-ath11k-fix-incorrect-ast-index-assignment-for-wds-peer.patch} (84%) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/371-ath11k-Fix-ppdu_id-from-firmware-PPDU-stats.patch rename package/kernel/mac80211/patches/{ath11k_nss/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch => nss/ath11k/373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch} (93%) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch rename package/kernel/mac80211/patches/{ath11k_nss => nss/ath11k}/376-ath11k-Add-nss-event-handler-support-for-link-desc.patch (92%) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/456-wifi-ath11k-Advertise-TX_QUEUE-mac-hw-flag.patch rename package/kernel/mac80211/patches/{ath11k_nss/913-830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch => nss/ath11k/457-wifi-ath11k-Avoid-memset-of-ppdu-info-for-next-skb.patch} (90%) rename package/kernel/mac80211/patches/{ath11k_nss/906-456-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch => nss/ath11k/458-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch} (86%) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/907-01-wifi-ath11k-remove-invalid-peer-create-logic.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/907-02-wifi-ath11k-rename-ath11k_start_vdev_delay.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/907-03-wifi-ath11k-avoid-forward-declaration-of-ath11k_mac_start_vdev_delay.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/907-04-wifi-ath11k-fix-connection-failure-due-to-unexpected-peer-delete.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/908-ath11k-make-debugfs-sta-htt-stats-modular.patch rename package/kernel/mac80211/patches/{ath11k_nss/900-fix-build.patch => nss/subsys/007-fix_compilation_issue.patch} (62%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/146-mac80211-enable-TKIP-when-using-encapsulation-offloading.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/199-001-mac80211-add-nss-support.patch (99%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/199-mac80211-fix-xmit-callback-when-hwencap-enable-in-st.patch (100%) create mode 100644 package/kernel/mac80211/patches/nss/subsys/203-mac80211-ath11k-fw-dynamic-muedca.patch rename package/kernel/mac80211/patches/{ath11k_nss/207-mac80211-Add-support-for-dynamic-vlan.patch => nss/subsys/207-ath11k-Add-support-for-dynamic-vlan.patch} (100%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/207-mac80211-add-nss-redirect-support.patch (100%) rename package/kernel/mac80211/patches/{ath11k_nss/902-000-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch => nss/subsys/235-001-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch} (86%) rename package/kernel/mac80211/patches/{ath11k_nss/902-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch => nss/subsys/236-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch} (78%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/245-compilation_fix.patch (93%) rename package/kernel/mac80211/patches/{ath11k_nss/300-mac80211-nss-mesh-offload-support.patch => nss/subsys/300-ath11k-nss-mesh-offload-support.patch} (96%) rename package/kernel/mac80211/patches/{ath11k_nss/335-0003-mac80211-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch => nss/subsys/335-0003-ath11k-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch} (94%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/335-0005-mac80211-simple-tx-for-AP-mode.patch (93%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/336-mac80211-Mesh-Fast-rx-support.patch (95%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/342-mac80211-fix-unconditional-sta-usage.patch (79%) create mode 100644 package/kernel/mac80211/patches/nss/subsys/345-mac80211-fix-mixed-declaration.patch create mode 100644 package/kernel/mac80211/patches/nss/subsys/346-mac80211-fix-bw-change-to-40Mhz-during-channel-switc.patch rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/353-mac80211-fix-dynamic-vlan-warning-with-monitor-interface-restart.patch (95%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch (94%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch (70%) rename package/kernel/mac80211/patches/{ath11k_nss/913-686-mac80211-fix-RCU-stall-in-mesh-fast-xmit-path.patch => nss/subsys/686-mac80211-fix-RCU-stall-in-mesh-fast-xmit-path.patch} (88%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch (94%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch (89%) create mode 100644 package/kernel/mac80211/patches/nss/subsys/785-wifi-mac80211-Add-mac-hw-flag-to-avoid-queue-skb.patch rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/829-mac80211-fix-mesh-ping-issue.patch (92%) rename package/kernel/mac80211/patches/{ath11k_nss => nss/subsys}/902-wifi-mac80211-Fix-memory-corruption-during-mesh-beac.patch (100%) diff --git a/package/kernel/ath10k-ct/patches/999-003-ath10k-add-nss-support.patch b/package/kernel/ath10k-ct/patches/999-003-ath10k-add-nss-support.patch new file mode 100644 index 00000000000000..2ef718625f011e --- /dev/null +++ b/package/kernel/ath10k-ct/patches/999-003-ath10k-add-nss-support.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 c65898aa46c0eb..080e07a43c8042 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/ @@ -307,6 +309,8 @@ ifdef CONFIG_ATH11K_NSS_SUPPORT IREMAP_CFLAGS+=-I$(STAGING_DIR)/usr/include/qca-nss-drv -I$(STAGING_DIR)/usr/include/qca-nss-clients endif +NSS_PATCHES:= subsys ath10k ath11k + config-$(CONFIG_PACKAGE_MAC80211_NSS_SUPPORT) += MAC80211_NSS_SUPPORT MAKE_OPTS:= \ @@ -377,7 +381,11 @@ define Build/Patch $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath9k,ath9k/) $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/) $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/) - $(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/) @@ -394,7 +402,11 @@ define Quilt/Refresh/Package $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath9k,ath9k/) $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/) $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/) - $(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/) diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk index af60c499ddde7c..574a3e2424dc90 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 += \ @@ -64,6 +67,10 @@ 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-$(CONFIG_ATH11K_NSS_MESH_SUPPORT) += ATH11K_NSS_MESH_SUPPORT config-$(call config_package,ath9k-htc) += ATH9K_HTC config-$(call config_package,ath10k,regular) += ATH10K ATH10K_PCI @@ -306,7 +313,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 @@ -320,6 +330,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 @@ -327,6 +341,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 || \ @@ -335,13 +365,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/etc/init.d/qca-nss-pbuf b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf index 02afd5f6c3d380..f4f45b9a4a4c60 100755 --- a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf +++ b/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf @@ -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 @@ -104,18 +125,25 @@ apply_nss_config() { 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 + } 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 1826e64bbcba05..00000000000000 --- 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 ddae9fcbc50e7d..00000000000000 --- 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/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch b/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch deleted file mode 100644 index 87314bc425d3d1..00000000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch +++ /dev/null @@ -1,920 +0,0 @@ -From 30f54666ae15128f26fbad787a35253885a10513 Mon Sep 17 00:00:00 2001 -From: Ramya Gnanasekar -Date: Fri, 25 Dec 2020 16:11:06 +0530 -Subject: [PATCH] ath11k: Disable rx_header tlv for 2K SKB - -On low memory platform hdr_status in hal_rx_desc is not subscribed to -get a savings of 128bytes in skb. This is required to reduce the skb -size from 4K to 2K. Use HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG message -to unsubscribe rx_pkt_header tlv for rxdma ring. - -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 - } - - ar->debug.rx_filter = tlv_filter.rx_filter; -+ tlv_filter.offset_valid = false; - - 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 - } - - /* Clear rx filter set for monitor mode and rx status */ -+ tlv_filter.offset_valid = false; - 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, 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 { - #define DP_REO_CMD_RING_SIZE 256 - #define DP_REO_STATUS_RING_SIZE 2048 - #define DP_RXDMA_BUF_RING_SIZE 4096 --#define DP_RXDMA_REFILL_RING_SIZE 2048 -+#define DP_RXDMA_REFILL_RING_SIZE ATH11K_DP_RXDMA_REFILL_RING_SIZE -+#define DP_RXDMA_NSS_REFILL_RING_SIZE ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE - #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 { - * - * |31 26|25|24|23 16|15 8|7 0| - * |-----------------+----------------+----------------+---------------| -- * | rsvd1 |PS|SS| ring_id | pdev_id | msg_type | -+ * | rsvd1|OV|PS|SS| ring_id | pdev_id | msg_type | - * |-------------------------------------------------------------------| - * | rsvd2 | ring_buffer_size | - * |-------------------------------------------------------------------| -@@ -623,6 +624,14 @@ enum htt_ppdu_stats_tag_type { - * |-------------------------------------------------------------------| - * | tlv_filter_in_flags | - * |-------------------------------------------------------------------| -+ * | rx_header_offset | rx_packet_offset | -+ * |-------------------------------------------------------------------| -+ * | rx_mpdu_start_offset | rx_mpdu_end_offset | -+ * |-------------------------------------------------------------------| -+ * | rx_msdu_start_offset | rx_msdu_end_offset | -+ * |-------------------------------------------------------------------| -+ * | rsvd3 | rx_attention_offset | -+ * |-------------------------------------------------------------------| - * Where: - * PS = pkt_swap - * SS = status_swap -@@ -636,6 +645,9 @@ enum htt_ppdu_stats_tag_type { - * 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 - rx_offset_valid (OV): flag to indicate rx offsets -+ * configuration fields are valid -+ * - * b'26: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 { - * dword6 - b'0:31 - tlv_filter_in_flags: - * Filter in Attention/MPDU/PPDU/Header/User tlvs - * Refer to CFG_TLV_FILTER_IN_FLAG defs -+ * dword7 - b'0:15 - rx_packet_offset: rx_packet_offset in byte units -+ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING -+ * A value of 0 will be considered as ignore this config. -+ * Refer to BUF_RING_CFG_1 defs within HW .h files, -+ * e.g. wmac_top_reg_seq_hwioreg.h -+ * - b'16:31 - rx_header_offset: rx_header_offset in byte units -+ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING -+ * A value of 0 will be considered as ignore this config. -+ * Refer to BUF_RING_CFG_1 defs within HW .h files, -+ * e.g. wmac_top_reg_seq_hwioreg.h -+ * dword8 - b'0:15 - rx_mpdu_end_offset: rx_mpdu_end_offset in byte units -+ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING -+ * A value of 0 will be considered as ignore this config. -+ * Refer to BUF_RING_CFG_2 defs within HW .h files, -+ * e.g. wmac_top_reg_seq_hwioreg.h -+ * - b'16:31 - rx_mpdu_start_offset: rx_mpdu_start_offset in byte units -+ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING -+ * A value of 0 will be considered as ignore this config. -+ * Refer to BUF_RING_CFG_2 defs within HW .h files, -+ * e.g. wmac_top_reg_seq_hwioreg.h -+ * dword9 - b'0:15 - rx_msdu_end_offset: rx_msdu_end_offset in byte units -+ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING -+ * A value of 0 will be considered as ignore this config. -+ * Refer to BUF_RING_CFG_3 defs within HW .h files, -+ * e.g. wmac_top_reg_seq_hwioreg.h -+ * - b'16:31 - rx_msdu_start_offset: rx_msdu_start_offset in byte units -+ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING -+ * A value of 0 will be considered as ignore this config. -+ * Refer to BUF_RING_CFG_3 defs within HW .h files, -+ * e.g. wmac_top_reg_seq_hwioreg.h -+ * dword10- b'0:15 - rx_attention_offset: rx_attention_offset in byte units -+ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING -+ * A value of 0 will be considered as ignore this config. -+ * Refer to BUF_RING_CFG_4 defs within HW .h files, -+ * e.g. wmac_top_reg_seq_hwioreg.h -+ * - b'16:31 - rsvd3 for future use - */ - - #define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) -@@ -672,8 +720,16 @@ enum htt_ppdu_stats_tag_type { - #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) -+#define HTT_RX_RING_SELECTION_CFG_CMD_OFFSET_VALID BIT(26) - - #define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE GENMASK(15, 0) -+#define HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET GENMASK(15, 0) -+#define HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET GENMASK(31, 16) -+#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET GENMASK(15, 0) -+#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET GENMASK(31, 16) -+#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET GENMASK(15, 0) -+#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET GENMASK(31, 16) -+#define HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET GENMASK(15, 0) - - 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 { - HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER | \ - HTT_RX_FILTER_TLV_FLAGS_ATTENTION) - -+#define HTT_RX_RXDMA_FILTER_TLV_FLAGS_BUF_RING \ -+ (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ -+ HTT_RX_FILTER_TLV_FLAGS_MSDU_START | \ -+ HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \ -+ HTT_RX_FILTER_TLV_FLAGS_MSDU_END | \ -+ HTT_RX_FILTER_TLV_FLAGS_MPDU_END | \ -+ HTT_RX_FILTER_TLV_FLAGS_ATTENTION) -+ - struct htt_rx_ring_selection_cfg_cmd { - u32 info0; - u32 info1; -@@ -985,6 +1049,10 @@ struct htt_rx_ring_selection_cfg_cmd { - u32 pkt_type_en_flags2; - u32 pkt_type_en_flags3; - u32 rx_filter_tlv; -+ u32 rx_packet_offset; -+ u32 rx_mpdu_offset; -+ u32 rx_msdu_offset; -+ u32 rx_attn_offset; - } __packed; - - struct htt_rx_ring_tlv_filter { -@@ -993,6 +1061,14 @@ struct htt_rx_ring_tlv_filter { - u32 pkt_filter_flags1; /* MGMT */ - u32 pkt_filter_flags2; /* CTRL */ - u32 pkt_filter_flags3; /* DATA */ -+ bool offset_valid; -+ u16 rx_packet_offset; -+ u16 rx_header_offset; -+ u16 rx_mpdu_end_offset; -+ u16 rx_mpdu_start_offset; -+ u16 rx_msdu_end_offset; -+ u16 rx_msdu_start_offset; -+ u16 rx_attn_offset; - }; - - #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 - return ab->hw_params.hw_ops->rx_desc_get_mpdu_fc_valid(desc); - } - -+static u16 ath11k_dp_rxdesc_get_mpdu_frame_ctrl(struct ath11k_base *ab, -+ struct hal_rx_desc *desc) -+{ -+ return ab->hw_params.hw_ops->rx_desc_get_mpdu_frame_ctl(desc); -+} -+ - 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 - return ab->hw_params.hw_ops->rx_desc_mpdu_start_addr2(desc); - } - -+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M -+static void ath11k_dp_get_rx_header_offset(struct ath11k_base *ab, -+ struct htt_rx_ring_tlv_filter *tlv_filter) -+{ -+ ab->hw_params.hw_ops->rx_desc_get_offset(tlv_filter); -+} -+#endif -+ -+static bool ath11k_dp_rx_desc_dot11_hdr_fields_valid(struct ath11k_base *ab, -+ struct hal_rx_desc *desc) -+{ -+ return ab->hw_params.hw_ops->rx_desc_dot11_hdr_fields_valid(desc); -+} -+ -+static void ath11k_dp_rx_desc_get_dot11_hdr(struct ath11k_base *ab, -+ struct hal_rx_desc *desc, -+ struct ieee80211_hdr *hdr) -+{ -+ ab->hw_params.hw_ops->rx_desc_get_dot11_hdr(desc, hdr); -+} -+ -+static void ath11k_dp_rx_desc_get_crypto_header(struct ath11k_base *ab, -+ struct hal_rx_desc *desc, -+ u8 *crypto_hdr, -+ enum hal_encrypt_type enctype) -+{ -+ ab->hw_params.hw_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); -+} -+ - 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 - return 0; - } - -+static void ath11k_get_dot11_hdr_from_rx_desc(struct ath11k *ar, -+ struct sk_buff *msdu, -+ struct ath11k_skb_rxcb *rxcb, -+ struct ieee80211_rx_status *status, -+ enum hal_encrypt_type enctype) -+{ -+ struct hal_rx_desc *rx_desc = rxcb->rx_desc; -+ struct ath11k_base *ab = ar->ab; -+ size_t hdr_len, crypto_len; -+ struct ieee80211_hdr *hdr; -+ u16 fc, qos_ctl = 0; -+ u8 *crypto_hdr; -+ -+ if (!(status->flag & RX_FLAG_IV_STRIPPED)) { -+ crypto_len = ath11k_dp_rx_crypto_param_len(ar, enctype); -+ crypto_hdr = skb_push(msdu, crypto_len); -+ ath11k_dp_rx_desc_get_crypto_header(ab, rx_desc, crypto_hdr, enctype); -+ } -+ -+ fc = ath11k_dp_rxdesc_get_mpdu_frame_ctrl(ab, rx_desc); -+ hdr_len = ieee80211_hdrlen(fc); -+ skb_push(msdu, hdr_len); -+ hdr = (struct ieee80211_hdr *)msdu->data; -+ hdr->frame_control = fc; -+ -+ /* Get wifi header from rx_desc */ -+ ath11k_dp_rx_desc_get_dot11_hdr(ab, rx_desc, hdr); -+ -+ if (rxcb->is_mcbc) -+ status->flag &= ~RX_FLAG_PN_VALIDATED; -+ -+ /* Add QOS header */ -+ if (ieee80211_is_data_qos(hdr->frame_control)) { -+ qos_ctl = rxcb->tid; -+ if (ath11k_dp_rx_h_msdu_start_mesh_ctl_present(ab, rx_desc)) -+ qos_ctl |= IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT; -+ -+ /* TODO Add other QoS ctl fields when required */ -+ memcpy(msdu->data + (hdr_len - IEEE80211_QOS_CTL_LEN), -+ &qos_ctl, IEEE80211_QOS_CTL_LEN); -+ } -+} -+ - 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 - u8 da[ETH_ALEN]; - u8 sa[ETH_ALEN]; - u16 qos_ctl = 0; -- u8 *qos; -+ u8 *qos, *crypto_hdr; -+ bool add_qos_ctrl = false; - - /* 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 - ether_addr_copy(sa, ieee80211_get_SA(hdr)); - skb_pull(msdu, ieee80211_hdrlen(hdr->frame_control)); - -- if (rxcb->is_first_msdu) { -+ if (rxcb->is_first_msdu && first_hdr) { - /* 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 - - /* copy decap header before overwriting for reuse below */ - memcpy(decap_hdr, (uint8_t *)hdr, hdr_len); -+ add_qos_ctrl = true; - } - - 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)); -+ if (first_hdr) { -+ memcpy(skb_push(msdu, -+ ath11k_dp_rx_crypto_param_len(ar, enctype)), -+ (void *)hdr + hdr_len, -+ ath11k_dp_rx_crypto_param_len(ar, enctype)); -+ } else { -+ crypto_hdr = skb_push(msdu, ath11k_dp_rx_crypto_param_len(ar, enctype)); -+ ath11k_dp_rx_desc_get_crypto_header(ar->ab, -+ rxcb->rx_desc, crypto_hdr, enctype); -+ } - } - -- if (!rxcb->is_first_msdu) { -+ if (!rxcb->is_first_msdu || add_qos_ctrl) { - 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 - u8 da[ETH_ALEN]; - u8 sa[ETH_ALEN]; - void *rfc1042; -+ struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); -+ struct ath11k_dp_rfc1042_hdr rfc = {0xaa, 0xaa, 0x03, {0x00, 0x00, 0x00}}; -+ -+ if (!first_hdr) { -+ eth = (struct ethhdr *)msdu->data; -+ ether_addr_copy(da, eth->h_dest); -+ ether_addr_copy(sa, eth->h_source); -+ rfc.snap_type = eth->h_proto; -+ skb_pull(msdu, sizeof(struct ethhdr)); -+ 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); -+ goto exit; -+ } - - 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 - - memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); - -+exit: - /* 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( - size_t hdr_len; - u8 l3_pad_bytes; - struct hal_rx_desc *rx_desc; -+ struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); - - /* Delivered decapped frame: - * [amsdu header] <-- replaced with 802.11 hdr -@@ -2212,6 +2314,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); - -+ if (!first_hdr) { -+ ath11k_get_dot11_hdr_from_rx_desc(ar, msdu, rxcb, status, enctype); -+ return; -+ } -+ - 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 - goto free_out; - } - -+ hdr_status = ath11k_dp_rx_h_80211_hdr(ab, rx_desc); -+ /* wifi hdr fields validation for 512M:: -+ * Mcast packets in ethernet frame mode -+ * will need wifi hdr in msdu to validate PN. -+ * Header will be added in undecap routine. -+ * Validation on wifi hdr fields from rx_desc. -+ */ -+ if (!hdr_status && ath11k_dp_rx_h_attn_is_mcbc(ab, rx_desc) && -+ !ath11k_dp_rx_desc_dot11_hdr_fields_valid(ab, rx_desc)) { -+ ath11k_warn(ab, "One or more invalid dot11 header fields\n"); -+ ret = -EIO; -+ goto free_out; -+ } -+ - 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 - hdr_status = ath11k_dp_rx_h_80211_hdr(ab, rx_desc); - ret = -EINVAL; - ath11k_warn(ab, "invalid msdu len %u\n", msdu_len); -- ath11k_dbg_dump(ab, ATH11K_DBG_DATA, NULL, "", hdr_status, -- sizeof(struct ieee80211_hdr)); -+ if (hdr_status) -+ ath11k_dbg_dump(ab, ATH11K_DBG_DATA, NULL, "", hdr_status, -+ sizeof(struct ieee80211_hdr)); - 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 - - hdr = (struct ieee80211_hdr *)(msdu->data + hal_rx_desc_sz); - hdr_len = ieee80211_hdrlen(hdr->frame_control); -+ - 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 - - static u64 ath11k_dp_rx_h_get_pn(struct ath11k *ar, struct sk_buff *skb) - { -- struct ieee80211_hdr *hdr; - u64 pn = 0; -+ struct ieee80211_hdr *hdr; - 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 - 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); -- ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", hdr_status, -- sizeof(struct ieee80211_hdr)); -+ if (hdr_status) -+ ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", hdr_status, -+ sizeof(struct ieee80211_hdr)); - 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 - ath11k_dp_rxdma_pdev_buf_free(ar); - } - -+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M -+static int ath11k_dp_rxdma_ring_sel_config(struct ath11k *ar) -+{ -+ struct ath11k_pdev_dp *dp = &ar->dp; -+ struct htt_rx_ring_tlv_filter tlv_filter = {0}; -+ u32 ring_id; -+ int ret; -+ u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; -+ -+ ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id; -+ -+ tlv_filter.rx_filter = HTT_RX_RXDMA_FILTER_TLV_FLAGS_BUF_RING; -+ tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR; -+ tlv_filter.pkt_filter_flags3 = HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST | -+ HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST; -+ tlv_filter.offset_valid = true; -+ tlv_filter.rx_packet_offset = hal_rx_desc_sz; -+ tlv_filter.rx_header_offset = 0; -+ -+ ath11k_dp_get_rx_header_offset(ar->ab, &tlv_filter); -+ -+ if (!ar->ab->nss.enabled) -+ ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, dp->mac_id, -+ HAL_RXDMA_BUF, -+ DP_RXDMA_REFILL_RING_SIZE, -+ &tlv_filter); -+ else -+ ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, dp->mac_id, -+ HAL_RXDMA_BUF, -+ DP_RXDMA_NSS_REFILL_RING_SIZE, -+ &tlv_filter); -+ -+ return ret; -+} -+#else -+static int ath11k_dp_rxdma_ring_sel_config(struct ath11k *ar) -+{ -+ return 0; -+} -+#endif -+ - 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: - } - } - -+ ret = ath11k_dp_rxdma_ring_sel_config(ar); -+ if (ret) { -+ ath11k_warn(ab, "failed to setup rxdma ring selection config\n"); -+ return ret; -+ } -+ - return 0; - } - ---- 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 - !!(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)); -+ cmd->info0 |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_OFFSET_VALID, -+ tlv_filter->offset_valid); - - 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 - cmd->pkt_type_en_flags3 = tlv_filter->pkt_filter_flags3; - cmd->rx_filter_tlv = tlv_filter->rx_filter; - -+ if (tlv_filter->offset_valid) { -+ cmd->rx_packet_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET, -+ tlv_filter->rx_packet_offset); -+ cmd->rx_packet_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET, -+ tlv_filter->rx_header_offset); -+ -+ cmd->rx_mpdu_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET, -+ tlv_filter->rx_mpdu_end_offset); -+ cmd->rx_mpdu_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET, -+ tlv_filter->rx_mpdu_start_offset); -+ -+ cmd->rx_msdu_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET, -+ tlv_filter->rx_msdu_end_offset); -+ cmd->rx_msdu_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET, -+ tlv_filter->rx_msdu_start_offset); -+ -+ cmd->rx_attn_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET, -+ tlv_filter->rx_attn_offset); -+ } -+ - 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 - } - - ring_id = dp->rxdma_mon_buf_ring.refill_buf_ring.ring_id; -+ tlv_filter.offset_valid = false; - - if (!reset) { - tlv_filter.rx_filter = HTT_RX_MON_FILTER_TLV_FLAGS_MON_BUF_RING; ---- a/drivers/net/wireless/ath/ath11k/hw.c -+++ b/drivers/net/wireless/ath/ath11k/hw.c -@@ -260,7 +260,11 @@ static u8 ath11k_hw_ipq8074_rx_desc_get_ - - static u8 *ath11k_hw_ipq8074_rx_desc_get_hdr_status(struct hal_rx_desc *desc) - { -+#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M - return desc->u.ipq8074.hdr_status; -+#else -+ return NULL; -+#endif - } - - 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 - desc->u.ipq8074.msdu_start.info1 = __cpu_to_le32(info); - } - -+static -+struct rx_attention *ath11k_hw_ipq8074_rx_desc_get_attention(struct hal_rx_desc *desc) -+{ -+ return &desc->u.ipq8074.attention; -+} -+ -+static u8 *ath11k_hw_ipq8074_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) -+{ -+ return &desc->u.ipq8074.msdu_payload[0]; -+} -+ -+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M -+static void ath11k_hw_ipq8074_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_ipq8074, mpdu_end_tag)); -+ tlv_filter->rx_mpdu_start_offset = __le16_to_cpu(offsetof -+ (struct hal_rx_desc_ipq8074, mpdu_start_tag)); -+ tlv_filter->rx_msdu_end_offset = __le16_to_cpu(offsetof -+ (struct hal_rx_desc_ipq8074, msdu_end_tag)); -+ tlv_filter->rx_msdu_start_offset = __le16_to_cpu(offsetof -+ (struct hal_rx_desc_ipq8074, msdu_start_tag)); -+ tlv_filter->rx_attn_offset = __le16_to_cpu(offsetof -+ (struct hal_rx_desc_ipq8074, rx_attn_tag)); -+} -+#endif -+ -+static u16 ath11k_hw_ipq8074_rx_desc_get_mpdu_frame_ctl(struct hal_rx_desc *desc) -+{ -+ return __le16_to_cpu(desc->u.ipq8074.mpdu_start.frame_ctrl); -+} -+ - static bool ath11k_hw_ipq8074_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) - { - return __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & - RX_MPDU_START_INFO1_MAC_ADDR2_VALID; - } - --static u8 *ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) -+static u8* ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) - { - return desc->u.ipq8074.mpdu_start.addr2; - } - --static --struct rx_attention *ath11k_hw_ipq8074_rx_desc_get_attention(struct hal_rx_desc *desc) -+static bool ath11k_hw_ipq8074_rx_desc_dot11_hdr_fields_valid(struct hal_rx_desc *desc) - { -- return &desc->u.ipq8074.attention; -+ if ((ath11k_hw_ipq8074_rx_desc_get_mpdu_seq_ctl_vld(desc) && -+ ath11k_hw_ipq8074_rx_desc_get_mpdu_fc_valid(desc) && -+ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & -+ RX_MPDU_START_INFO1_MAC_ADDR1_VALID && -+ ath11k_hw_ipq8074_rx_desc_mac_addr2_valid(desc) && -+ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & -+ RX_MPDU_START_INFO1_MAC_ADDR3_VALID && -+ FIELD_GET((RX_MPDU_START_INFO1_MPDU_DUR_VALID), -+ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1)))) { -+ return true; -+ } -+ return false; -+} -+ -+static void ath11k_hw_ipq8074_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, -+ struct ieee80211_hdr *hdr) -+{ -+ hdr->frame_control = __le16_to_cpu(desc->u.ipq8074.mpdu_start.frame_ctrl); -+ hdr->duration_id = __le16_to_cpu(desc->u.ipq8074.mpdu_start.duration); -+ ether_addr_copy(hdr->addr1, desc->u.ipq8074.mpdu_start.addr1); -+ ether_addr_copy(hdr->addr2, desc->u.ipq8074.mpdu_start.addr2); -+ ether_addr_copy(hdr->addr3, desc->u.ipq8074.mpdu_start.addr3); -+ if (__le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & -+ RX_MPDU_START_INFO1_MAC_ADDR4_VALID) { -+ ether_addr_copy(hdr->addr4, desc->u.ipq8074.mpdu_start.addr4); -+ } -+ hdr->seq_ctrl = __le16_to_cpu(desc->u.ipq8074.mpdu_start.seq_ctrl); -+} -+ -+static void ath11k_hw_ipq8074_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.ipq8074.mpdu_start.pn[0]); -+ crypto_hdr[1] = 0; -+ crypto_hdr[2] = -+ HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.ipq8074.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.ipq8074.mpdu_start.pn[0]); -+ crypto_hdr[1] = -+ HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.ipq8074.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_INFO5_KEY_ID, -+ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info5)); -+ crypto_hdr[3] = 0x20 | (key_id << 6); -+ crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.ipq8074.mpdu_start.pn[0]); -+ crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.ipq8074.mpdu_start.pn[0]); -+ crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.ipq8074.mpdu_start.pn[1]); -+ crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.ipq8074.mpdu_start.pn[1]); - } - --static u8 *ath11k_hw_ipq8074_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) -+static bool ath11k_hw_qcn9074_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) - { -- return &desc->u.ipq8074.msdu_payload[0]; -+ return __le32_to_cpu(desc->u.qcn9074.mpdu_start.info11) & -+ RX_MPDU_START_INFO11_MAC_ADDR2_VALID; -+} -+ -+static u8* ath11k_hw_qcn9074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) -+{ -+ return desc->u.qcn9074.mpdu_start.addr2; - } - - 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_ - - static u8 *ath11k_hw_qcn9074_rx_desc_get_hdr_status(struct hal_rx_desc *desc) - { -+#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M - return desc->u.qcn9074.hdr_status; -+#else -+ return NULL; -+#endif - } - - 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_ - - static u8 *ath11k_hw_wcn6855_rx_desc_get_hdr_status(struct hal_rx_desc *desc) - { -+#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M - return desc->u.wcn6855.hdr_status; -+#else -+ return NULL; -+#endif - } - - 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, - .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2, - .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, -+#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 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 = - .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, - .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, - }; - ---- a/drivers/net/wireless/ath/ath11k/hw.h -+++ b/drivers/net/wireless/ath/ath11k/hw.h -@@ -22,7 +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 -+ */ -+#define ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE 1816 - #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 @@ - #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 -+#define ATH11K_DP_RXDMA_REFILL_RING_SIZE 2048 -+#define ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE 2048 - #endif - - /* Num of peers for Single Radio mode */ -@@ -142,6 +152,8 @@ 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_desc_mpdu_start_addr2)(struct hal_rx_desc *desc); - u32 (*get_ring_selector)(struct sk_buff *skb); -+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M -+ void (*rx_desc_get_offset)(struct htt_rx_ring_tlv_filter *tlv_filter); -+#endif -+ u16 (*rx_desc_get_mpdu_frame_ctl)(struct hal_rx_desc *desc); -+ bool (*rx_desc_dot11_hdr_fields_valid)(struct hal_rx_desc *desc); -+ void (*rx_desc_get_dot11_hdr)(struct hal_rx_desc *desc, -+ struct ieee80211_hdr *hdr); -+ void (*rx_desc_get_crypto_header)(struct hal_rx_desc *desc, -+ u8 *crypto_hdr, -+ enum hal_encrypt_type enctype); - }; - - 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_ - tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar); - } - -+ tlv_filter.offset_valid = false; - 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 { - __le32 mpdu_end_tag; - struct rx_mpdu_end mpdu_end; - u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES]; -+#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M - __le32 hdr_status_tag; - __le32 phy_ppdu_id; - u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN]; -+#endif - u8 msdu_payload[]; - } __packed; - -@@ -1461,9 +1463,11 @@ struct hal_rx_desc_qcn9074 { - __le32 mpdu_end_tag; - struct rx_mpdu_end mpdu_end; - u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES]; -+#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M - __le32 hdr_status_tag; - __le32 phy_ppdu_id; - u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN]; -+#endif - u8 msdu_payload[]; - } __packed; - -@@ -1480,9 +1484,11 @@ struct hal_rx_desc_wcn6855 { - __le32 mpdu_end_tag; - struct rx_mpdu_end mpdu_end; - u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES]; -+#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M - __le32 hdr_status_tag; - __le32 phy_ppdu_id; - u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN]; -+#endif - u8 msdu_payload[]; - } __packed; - -@@ -1502,4 +1508,17 @@ struct hal_rx_desc { - #define RU_484 18 - #define RU_996 37 - -+#define HAL_RX_MPDU_INFO_PN_GET_BYTE1(__val) \ -+ FIELD_GET(GENMASK(7, 0), __le32_to_cpu(__val)) -+ -+#define HAL_RX_MPDU_INFO_PN_GET_BYTE2(__val) \ -+ FIELD_GET(GENMASK(15, 8), __le32_to_cpu(__val)) -+ -+#define HAL_RX_MPDU_INFO_PN_GET_BYTE3(__val) \ -+ FIELD_GET(GENMASK(23, 16), __le32_to_cpu(__val)) -+ -+#define HAL_RX_MPDU_INFO_PN_GET_BYTE4(__val) \ -+ FIELD_GET(GENMASK(31, 24), __le32_to_cpu(__val)) -+ -+ - #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 - - /* fill rx parameters to initialize rx context */ - wim->wrip.tlv_size = ab->hw_params.hal_desc_sz; -- wim->wrip.rx_buf_len = DP_RX_BUFFER_SIZE; -+ wim->wrip.rx_buf_len = DP_RXDMA_NSS_REFILL_RING_SIZE; - - /* fill hal srng message */ - wim->hssm.dev_base_addr = (u32)ab->mem_pa; 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 08e158a407ca8f..00000000000000 --- 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 7488f0c2bfce6b..00000000000000 --- 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 5d5a83911d8519..00000000000000 --- 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 6fb460f6b4f740..00000000000000 --- 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 83c019b871e81b..00000000000000 --- 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 6f7c1aadd95b64..00000000000000 --- 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/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch b/package/kernel/mac80211/patches/ath11k_nss/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch deleted file mode 100644 index 0a7dcf5e845780..00000000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 246e530a47d9adab9106fb6f2b92197cace17e53 Mon Sep 17 00:00:00 2001 -From: Seevalamuthu Mariappan -Date: Fri, 21 May 2021 14:16:22 +0530 -Subject: [PATCH] ath11k: configure nss radio priority during pdev_init - -pdev's priority value is read from dts. Get scheme_id -using pdev priority. Configure scheme_id during pdev_init. - -Signed-off-by: Seevalamuthu Mariappan ---- - drivers/net/wireless/ath/ath11k/nss.c | 20 +++++++++++++++++++- - drivers/net/wireless/ath/ath11k/nss.h | 3 +++ - 2 files changed, 22 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/ath/ath11k/nss.c -+++ b/drivers/net/wireless/ath/ath11k/nss.c -@@ -2,6 +2,7 @@ - /* - * Copyright (c) 2020 The Linux Foundation. All rights reserved. - */ -+#include - - #include "debug.h" - #include "mac.h" -@@ -1782,6 +1783,7 @@ static int ath11k_nss_init(struct ath11k - nss_tx_status_t status; - struct ath11k_dp *dp; - int i, ret; -+ struct device *dev = ab->dev; - - dp = &ab->dp; - -@@ -1801,6 +1803,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; -+ if (of_property_read_bool(dev->of_node, "nss-radio-priority")) -+ wim->flags |= WIFILI_MULTISOC_THREAD_MAP_ENABLE; - - /* 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 - struct nss_wifili_msg *wlmsg = NULL; - nss_wifili_msg_callback_t msg_cb; - nss_tx_status_t status; -+ struct device *dev = ab->dev; - int radio_if_num = -1; - int refill_ring_id; - int features = 0; - int dyn_if_type; -- int ret, i; -+ int ret, i, scheme_id = 0; -+ u32 nss_radio_priority; - - dyn_if_type = ath11k_nss_get_dynamic_interface_type(ab); - -@@ -2010,6 +2016,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); - -+ if (!of_property_read_u32(dev->of_node, "nss-radio-priority", &nss_radio_priority)) { -+ scheme_id = nss_wifili_thread_scheme_alloc(ab->nss.ctx, ar->nss.if_num, nss_radio_priority); -+ if (scheme_id == WIFILI_SCHEME_ID_INVALID) { -+ ath11k_warn(ab, "received invalid scheme_id, configuring default value\n"); -+ scheme_id = 0; -+ } -+ } -+ ath11k_dbg(ab, ATH11K_DBG_NSS, "ifnum: %d scheme_id: %d nss_radio_priority: %d\n", ar->nss.if_num, scheme_id, nss_radio_priority); -+ - 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 - 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; -+ pdevmsg->scheme_id = scheme_id; - - /* 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 - /* pdev deinit msg success, dealloc, deregister and return */ - ret = 0; - -+ /* reset thread scheme*/ -+ nss_wifili_thread_scheme_dealloc(ab->nss.ctx, ar->nss.if_num); -+ - nss_dynamic_interface_dealloc_node(ar->nss.if_num, dyn_if_type); - nss_unregister_wifili_radio_if(ar->nss.if_num); - 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; - /* Init Flags */ - #define WIFILI_NSS_CCE_DISABLED 0x1 - #define WIFILI_ADDTL_MEM_SEG_SET 0x000000002 -+#define WIFILI_MULTISOC_THREAD_MAP_ENABLE 0x10 - - /* 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, - }; - -+#define WIFILI_SCHEME_ID_INVALID -1 -+ - enum ath11k_nss_opmode { - ATH11K_NSS_OPMODE_UNKNOWN, - ATH11K_NSS_OPMODE_AP, 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 79146df5447b8b..00000000000000 --- 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 4a8328f4e3ca83..00000000000000 --- 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 1bfa9b89b45c5f..00000000000000 --- 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/902-020-ath11k-add-btcoex-config.patch b/package/kernel/mac80211/patches/ath11k_nss/902-020-ath11k-add-btcoex-config.patch deleted file mode 100644 index 495245f9662462..00000000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/902-020-ath11k-add-btcoex-config.patch +++ /dev/null @@ -1,612 +0,0 @@ ---- a/drivers/net/wireless/ath/ath11k/Makefile -+++ b/drivers/net/wireless/ath/ath11k/Makefile -@@ -17,7 +17,8 @@ ath11k-y += core.o \ - peer.o \ - dbring.o \ - hw.o \ -- pcic.o -+ pcic.o \ -+ vendor.o - - ath11k-$(CPTCFG_ATH11K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o - ath11k-$(CPTCFG_NL80211_TESTMODE) += testmode.o ---- a/drivers/net/wireless/ath/ath11k/core.h -+++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -637,6 +637,16 @@ struct ath11k_per_peer_tx_stats { - #define ATH11K_FLUSH_TIMEOUT (5 * HZ) - #define ATH11K_VDEV_DELETE_TIMEOUT_HZ (5 * HZ) - -+struct ath11k_coex_info { -+ bool coex_support; -+ u32 pta_num; -+ u32 coex_mode; -+ u32 bt_active_time_slot; -+ u32 bt_priority_time_slot; -+ u32 coex_algo_type; -+ u32 pta_priority; -+}; -+ - struct ath11k { - struct ath11k_base *ab; - struct ath11k_pdev *pdev; -@@ -760,6 +770,8 @@ struct ath11k { - struct ath11k_per_peer_tx_stats cached_stats; - u32 last_ppdu_id; - u32 cached_ppdu_id; -+ -+ struct ath11k_coex_info coex; - int monitor_vdev_id; - struct completion fw_mode_reset; - u8 ftm_msgref; ---- a/drivers/net/wireless/ath/ath11k/mac.c -+++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -24,6 +25,7 @@ - #include "debugfs_sta.h" - #include "hif.h" - #include "wow.h" -+#include "vendor.h" - #include "nss.h" - - #define CHAN2G(_channel, _freq, _flags) { \ -@@ -9286,6 +9288,91 @@ err_fallback: - return 0; - } - -+#define ATH11K_WLAN_PRIO_MAX 0x63 -+#define ATH11K_WLAN_PRIO_WEIGHT 0xff -+ -+int ath11k_mac_coex_config(struct ath11k *ar, struct ath11k_vif *arvif, -+ int coex, u32 wlan_prio_mask, u8 wlan_weight) -+{ -+ struct coex_config_arg coex_config; -+ int ret; -+ -+ if (ar->state != ATH11K_STATE_ON && -+ ar->state != ATH11K_STATE_RESTARTED) -+ return -ENETDOWN; -+ -+ if (coex == -1 || !(test_bit(ATH11K_FLAG_BTCOEX, &ar->ab->dev_flags) ^ coex)) -+ goto next; -+ -+ coex_config.vdev_id = arvif->vdev_id; -+ if (coex == 1) { -+ coex_config.config_type = WMI_COEX_CONFIG_PTA_INTERFACE; -+ coex_config.pta_num = ar->coex.pta_num; -+ coex_config.coex_mode = ar->coex.coex_mode; -+ coex_config.bt_txrx_time = ar->coex.bt_active_time_slot; -+ coex_config.bt_priority_time = ar->coex.bt_priority_time_slot; -+ coex_config.pta_algorithm = ar->coex.coex_algo_type; -+ coex_config.pta_priority = ar->coex.pta_priority; -+ ret = ath11k_send_coex_config_cmd(ar, &coex_config); -+ if (ret) { -+ ath11k_warn(ar->ab, -+ "failed to set coex config vdev_id %d ret %d\n", -+ coex_config.vdev_id, ret); -+ goto out; -+ } -+ } -+ -+ memset(&coex_config, 0, sizeof(struct coex_config_arg)); -+ coex_config.vdev_id = arvif->vdev_id; -+ coex_config.config_type = WMI_COEX_CONFIG_BTC_ENABLE; -+ coex_config.coex_enable = coex; -+ ret = ath11k_send_coex_config_cmd(ar, &coex_config); -+ if (ret) { -+ ath11k_warn(ar->ab, -+ "failed to set coex config vdev_id %d ret %d\n", -+ coex_config.vdev_id, ret); -+ goto out; -+ } -+ -+ if (coex) -+ set_bit(ATH11K_FLAG_BTCOEX, &ar->ab->dev_flags); -+ else -+ clear_bit(ATH11K_FLAG_BTCOEX, &ar->ab->dev_flags); -+ -+next: -+ if (!wlan_prio_mask) { -+ ret = 0; -+ goto out; -+ } -+ -+ if (!(test_bit(ATH11K_FLAG_BTCOEX, &ar->ab->dev_flags))) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ if (wlan_prio_mask > ATH11K_WLAN_PRIO_MAX || -+ wlan_weight > ATH11K_WLAN_PRIO_WEIGHT) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ memset(&coex_config, 0, sizeof(struct coex_config_arg)); -+ coex_config.vdev_id = arvif->vdev_id; -+ coex_config.config_type = WMI_COEX_CONFIG_WLAN_PKT_PRIORITY; -+ coex_config.wlan_pkt_type = wlan_prio_mask; -+ coex_config.wlan_pkt_weight = wlan_weight; -+ ret = ath11k_send_coex_config_cmd(ar, &coex_config); -+ if (ret) { -+ ath11k_warn(ar->ab, -+ "failed to set coex config vdev_id %d ret %d\n", -+ coex_config.vdev_id, ret); -+ goto out; -+ } -+ -+out: -+ return ret; -+} -+ - static const struct ieee80211_ops ath11k_ops = { - .tx = ath11k_mac_op_tx, - .wake_tx_queue = ieee80211_handle_wake_tx_queue, -@@ -9525,6 +9612,56 @@ static int ath11k_mac_setup_iface_combin - return 0; - } - -+static void ath11k_mac_fetch_coex_info(struct ath11k *ar) -+{ -+ struct ath11k_pdev_cap *cap = &ar->pdev->cap; -+ struct ath11k_base *ab = ar->ab; -+ struct device *dev = ab->dev; -+ -+ ar->coex.coex_support = false; -+ -+ if (!(cap->supported_bands & WMI_HOST_WLAN_2G_CAP)) -+ return; -+ -+ if (of_property_read_u32(dev->of_node, "qcom,pta-num", -+ &ar->coex.pta_num)) { -+ ath11k_err(ab, "No qcom,pta_num entry in dev-tree.\n"); -+ } -+ -+ if (of_property_read_u32(dev->of_node, "qcom,coex-mode", -+ &ar->coex.coex_mode)) { -+ ath11k_err(ab, "No qcom,coex_mode entry in dev-tree.\n"); -+ } -+ -+ if (of_property_read_u32(dev->of_node, "qcom,bt-active-time", -+ &ar->coex.bt_active_time_slot)) { -+ ath11k_err(ab, "No qcom,bt-active-time entry in dev-tree.\n"); -+ } -+ -+ if (of_property_read_u32(dev->of_node, "qcom,bt-priority-time", -+ &ar->coex.bt_priority_time_slot)) { -+ ath11k_err(ab, "No qcom,bt-priority-time entry in dev-tree.\n"); -+ } -+ -+ if (of_property_read_u32(dev->of_node, "qcom,coex-algo", -+ &ar->coex.coex_algo_type)) { -+ ath11k_err(ab, "No qcom,coex-algo entry in dev-tree.\n"); -+ } -+ -+ if (of_property_read_u32(dev->of_node, "qcom,pta-priority", -+ &ar->coex.pta_priority)) { -+ ath11k_err(ab, "No qcom,pta-priority entry in dev-tree.\n"); -+ } -+ -+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "coex pta_num %u coex_mode %u" -+ " bt_active_time_slot %u bt_priority_time_slot %u" -+ " coex_algorithm %u pta_priority %u\n", ar->coex.pta_num, -+ ar->coex.coex_mode, ar->coex.bt_active_time_slot, -+ ar->coex.bt_priority_time_slot, ar->coex.coex_algo_type, -+ ar->coex.pta_priority); -+ ar->coex.coex_support = true; -+} -+ - static const u8 ath11k_if_types_ext_capa[] = { - [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, - [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT, -@@ -9786,6 +9923,7 @@ static int __ath11k_mac_register(struct - ar->hw->wiphy->ema_max_profile_periodicity = TARGET_EMA_MAX_PROFILE_PERIOD; - - ath11k_reg_init(ar); -+ ath11k_vendor_register(ar); - - if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) { - ar->hw->netdev_features = NETIF_F_HW_CSUM; -@@ -9948,6 +10086,7 @@ int ath11k_mac_allocate(struct ath11k_ba - */ - ath11k_wmi_pdev_attach(ab, i); - -+ ath11k_mac_fetch_coex_info(ar); - ar->cfg_tx_chainmask = pdev->cap.tx_chain_mask; - ar->cfg_rx_chainmask = pdev->cap.rx_chain_mask; - ar->num_tx_chains = get_num_chains(pdev->cap.tx_chain_mask); ---- a/drivers/net/wireless/ath/ath11k/mac.h -+++ b/drivers/net/wireless/ath/ath11k/mac.h -@@ -150,8 +150,9 @@ void __ath11k_mac_scan_finish(struct ath - void ath11k_mac_scan_finish(struct ath11k *ar); - - struct ath11k_vif *ath11k_mac_get_arvif(struct ath11k *ar, u32 vdev_id); --struct ath11k_vif *ath11k_mac_get_arvif_by_vdev_id(struct ath11k_base *ab, -- u32 vdev_id); -+struct ath11k_vif *ath11k_mac_get_arvif_by_vdev_id(struct ath11k_base *ab, u32 vdev_id); -+int ath11k_mac_coex_config(struct ath11k *ar, struct ath11k_vif *arvif, -+ int coex, u32 wlan_prio_mask, u8 wlan_weight); - u8 ath11k_mac_get_target_pdev_id(struct ath11k *ar); - u8 ath11k_mac_get_target_pdev_id_from_vif(struct ath11k_vif *arvif); - struct ath11k_vif *ath11k_mac_get_vif_up(struct ath11k_base *ab); ---- /dev/null -+++ b/drivers/net/wireless/ath/ath11k/vendor.c -@@ -0,0 +1,121 @@ -+// SPDX-License-Identifier: ISC -+/* -+ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. -+ */ -+ -+#include -+#include -+#include "core.h" -+#include "vendor.h" -+#include "debug.h" -+ -+static const struct nla_policy -+ath11k_vendor_btcoex_config_policy[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_MAX + 1] = { -+ [QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE] = { .type = NLA_U8 }, -+ [QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY] = { .type = NLA_NESTED }, -+}; -+ -+static const struct nla_policy -+ath11k_vendor_wlan_prio_policy[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MAX + 1] = { -+ [QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK] = { .type = NLA_U8 }, -+ [QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT] = { .type = NLA_U8 }, -+}; -+ -+static int ath11k_vendor_btcoex_configure(struct wiphy *wiphy, -+ 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_BTCOEX_CONFIG_MAX + 1]; -+ struct nlattr *tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MAX + 1]; -+ struct nlattr *wlan_prio; -+ enum qca_wlan_priority_type wlan_prio_mask = 0; -+ int ret, coex = -1, rem_conf; -+ u8 wlan_weight = 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_BTCOEX_CONFIG_MAX, data, data_len, -+ ath11k_vendor_btcoex_config_policy, NULL); -+ if (ret) { -+ ath11k_warn(ar->ab, "invalid BTCOEX config policy attribute\n"); -+ goto out; -+ } -+ -+ if (!tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE] && -+ !tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY]) { -+ ath11k_warn(ar->ab, "invalid BTCOEX config attributes\n"); -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ if (tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE]) { -+ coex = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE]); -+ ret = ath11k_mac_coex_config(ar, arvif, coex, wlan_prio_mask, wlan_weight); -+ if (ret) -+ goto out; -+ } -+ if (tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY]) { -+ nla_for_each_nested(wlan_prio, -+ tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY], -+ rem_conf) { -+ ret = -+ nla_parse_nested(tb_wlan_prio, QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MAX, -+ wlan_prio, ath11k_vendor_wlan_prio_policy, -+ NULL); -+ if (ret) -+ goto out; -+ wlan_prio_mask = -+ nla_get_u8(tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK]); -+ if (tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT]) -+ wlan_weight = -+ nla_get_u8(tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT]); -+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, -+ "BTCOEX enable %u WLAN Priority %u wlan weight %u\n", -+ coex, wlan_prio_mask, wlan_weight); -+ -+ ret = ath11k_mac_coex_config(ar, arvif, coex, wlan_prio_mask, wlan_weight); -+ if (ret) -+ goto out; -+ } -+ } -+ -+out: -+ mutex_unlock(&ar->conf_mutex); -+ return ret; -+} -+ -+static struct wiphy_vendor_command ath11k_vendor_commands[] = { -+ { -+ .info.vendor_id = QCA_NL80211_VENDOR_ID, -+ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_BTCOEX_CONFIG, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | -+ WIPHY_VENDOR_CMD_NEED_RUNNING, -+ .doit = ath11k_vendor_btcoex_configure, -+ .policy = ath11k_vendor_btcoex_config_policy -+ } -+}; -+ -+int ath11k_vendor_register(struct ath11k *ar) -+{ -+ ar->hw->wiphy->vendor_commands = ath11k_vendor_commands; -+ ar->hw->wiphy->n_vendor_commands = ARRAY_SIZE(ath11k_vendor_commands); -+ -+ return 0; -+} ---- /dev/null -+++ b/drivers/net/wireless/ath/ath11k/vendor.h -@@ -0,0 +1,83 @@ -+/* SPDX-License-Identifier: ISC */ -+/* -+ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. -+ */ -+ -+#ifndef ATH11K_VENDOR_H -+#define ATH11K_VENDOR_H -+ -+#define QCA_NL80211_VENDOR_ID 0x001374 -+ -+enum qca_nl80211_vendor_subcmds { -+ /* 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 -+ * enum qca-vendor_attr_btcoex_config. -+ */ -+ QCA_NL80211_VENDOR_SUBCMD_BTCOEX_CONFIG = 182, -+}; -+ -+/* -+ * enum qca_wlan_priority_type - priority mask -+ * This enum defines priority mask that user can configure -+ * over BT traffic type which can be passed through -+ * QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY attribute. -+ * -+ * @QCA_WLAN_PRIORITY_BE: Bit mask for WLAN Best effort traffic -+ * @QCA_WLAN_PRIORITY_BK: Bit mask for WLAN Background traffic -+ * @QCA_WLAN_PRIORITY_VI: Bit mask for WLAN Video traffic -+ * @QCA_WLAN_PRIORITY_VO: Bit mask for WLAN Voice traffic -+ * @QCA_WLAN_PRIORITY_BEACON: Bit mask for WLAN BEACON frame -+ * @QCA_WLAN_PRIORITY_MGMT: Bit mask for WLAN Management frame -+*/ -+enum qca_wlan_priority_type { -+ QCA_WLAN_PRIORITY_BE = BIT(0), -+ QCA_WLAN_PRIORITY_BK = BIT(1), -+ QCA_WLAN_PRIORITY_VI = BIT(2), -+ QCA_WLAN_PRIORITY_VO = BIT(3), -+ QCA_WLAN_PRIORITY_BEACON = BIT(4), -+ QCA_WLAN_PRIORITY_MGMT = BIT(5), -+}; -+ -+/** -+ * enum qca_wlan_vendor_attr_wlan_prio - Used to configure -+ * WLAN priority mask and its respective weight value. -+ * @QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK - This is u8 attribute -+ * used to pass traffic type mask value see %qca_wlan_priority_type -+ * @QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT - This is u8 attribute -+ * accepts value between 0 and 255 and used to configure weight for -+ * traffic type mentioned in %QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK. -+ */ -+enum qca_wlan_vendor_attr_wlan_prio { -+ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_INVALID = 0, -+ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK = 1, -+ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT = 2, -+ -+ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_LAST, -+ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MAX = -+ QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_LAST - 1, -+}; -+ -+ -+ -+/** -+ * enum qca_wlan_vendor_attr_btcoex_config - Used by the vendor command -+ * The use can enable/disable BTCOEX and configure WLAN priority for -+ * different traffic type over BT. -+ * QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE, enable/disable BTCOEX -+ * QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY, This is a nested -+ * attribute pass the attributes in %qca_wlan_vendor_attr_wlan_prio. -+ */ -+enum qca_wlan_vendor_attr_btcoex_config { -+ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_INVALID = 0, -+ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE = 1, -+ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY = 2, -+ -+ /* keep last */ -+ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_LAST, -+ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_MAX = -+ QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_LAST - 1 -+}; -+ -+int ath11k_vendor_register(struct ath11k *ar); -+#endif /* QCA_VENDOR_H */ ---- a/drivers/net/wireless/ath/ath11k/wmi.c -+++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -1743,6 +1743,71 @@ int ath11k_wmi_vdev_set_param_cmd(struct - return ret; - } - -+static void ath11k_wmi_copy_coex_config(struct ath11k *ar, struct wmi_coex_config_cmd *cmd, -+ struct coex_config_arg *coex_config) -+{ -+ if (coex_config->config_type == WMI_COEX_CONFIG_BTC_ENABLE) { -+ cmd->coex_enable = coex_config->coex_enable; -+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, -+ "WMI coex config type %u vdev id %d coex_enable %u\n", -+ coex_config->config_type, coex_config->vdev_id, -+ coex_config->coex_enable); -+ } -+ -+ if (coex_config->config_type == WMI_COEX_CONFIG_WLAN_PKT_PRIORITY) { -+ cmd->wlan_pkt_type = coex_config->wlan_pkt_type; -+ cmd->wlan_pkt_weight = coex_config->wlan_pkt_weight; -+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, -+ "WMI coex config type %u vdev id %d wlan pkt type 0x%x wlan pkt weight %u\n", -+ coex_config->config_type, coex_config->vdev_id, -+ coex_config->wlan_pkt_type, coex_config->wlan_pkt_weight); -+ } -+ -+ if (coex_config->config_type == WMI_COEX_CONFIG_PTA_INTERFACE) { -+ cmd->pta_num = coex_config->pta_num; -+ cmd->coex_mode = coex_config->coex_mode; -+ cmd->bt_txrx_time = coex_config->bt_txrx_time; -+ cmd->bt_priority_time = coex_config->bt_priority_time; -+ cmd->pta_algorithm = coex_config->pta_algorithm; -+ cmd->pta_priority = coex_config->pta_priority; -+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, -+ "WMI coex config type %u vdev id %d pta num %u coex mode %u bt_txrx_time %u bt_priority_time %u pta alogrithm %u pta priority %u\n", -+ coex_config->config_type, coex_config->vdev_id, -+ coex_config->pta_num, coex_config->coex_mode, -+ coex_config->bt_txrx_time, coex_config->bt_priority_time, -+ coex_config->pta_algorithm, coex_config->pta_priority); -+ } -+} -+ -+int ath11k_send_coex_config_cmd(struct ath11k *ar, -+ struct coex_config_arg *coex_config) -+{ -+ struct ath11k_pdev_wmi *wmi = ar->wmi; -+ struct wmi_coex_config_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_coex_config_cmd *)skb->data; -+ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_COEX_CONFIG_CMD) | -+ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); -+ -+ cmd->vdev_id = coex_config->vdev_id; -+ cmd->config_type = coex_config->config_type; -+ ath11k_wmi_copy_coex_config(ar, cmd, coex_config); -+ -+ ret = ath11k_wmi_cmd_send(wmi, skb, WMI_COEX_CONFIG_CMDID); -+ if (ret) { -+ ath11k_warn(ar->ab, "failed to send WMI_COEX_CONFIG_CMD cmd\n"); -+ dev_kfree_skb(skb); -+ } -+ -+ return ret; -+} -+ - int ath11k_wmi_send_stats_request_cmd(struct ath11k *ar, - struct stats_request_params *param) - { ---- a/drivers/net/wireless/ath/ath11k/wmi.h -+++ b/drivers/net/wireless/ath/ath11k/wmi.h -@@ -5333,6 +5333,79 @@ struct wmi_wmm_params_arg { - u8 no_ack; - }; - -+enum wmi_coex_config_type { -+ WMI_COEX_CONFIG_PAGE_P2P_TDM = 1, -+ WMI_COEX_CONFIG_PAGE_STA_TDM = 2, -+ WMI_COEX_CONFIG_PAGE_SAP_TDM = 3, -+ WMI_COEX_CONFIG_DURING_WLAN_CONN = 4, -+ WMI_COEX_CONFIG_BTC_ENABLE = 5, -+ WMI_COEX_CONFIG_COEX_DBG = 6, -+ WMI_COEX_CONFIG_PAGE_P2P_STA_TDM = 7, -+ WMI_COEX_CONFIG_INQUIRY_P2P_TDM = 8, -+ WMI_COEX_CONFIG_INQUIRY_STA_TDM = 9, -+ WMI_COEX_CONFIG_INQUIRY_SAP_TDM = 10, -+ WMI_COEX_CONFIG_INQUIRY_P2P_STA_TDM = 11, -+ WMI_COEX_CONFIG_TX_POWER = 12, -+ WMI_COEX_CONFIG_PTA_CONFIG = 13, -+ WMI_COEX_CONFIG_AP_TDM = 14, -+ WMI_COEX_CONFIG_WLAN_SCAN_PRIORITY = 15, -+ WMI_COEX_CONFIG_WLAN_PKT_PRIORITY = 16, -+ WMI_COEX_CONFIG_PTA_INTERFACE = 17, -+}; -+ -+struct coex_config_arg { -+ u32 vdev_id; -+ u32 config_type; -+ union { -+ struct { -+ u32 coex_enable; -+ }; -+ -+ struct { -+ u32 pta_num; -+ u32 coex_mode; -+ u32 bt_txrx_time; -+ u32 bt_priority_time; -+ u32 pta_algorithm; -+ u32 pta_priority; -+ }; -+ -+ struct { -+ u32 wlan_pkt_type; -+ u32 wlan_pkt_type_continued; -+ u32 wlan_pkt_weight; -+ u32 bt_pkt_weight; -+ }; -+ }; -+}; -+ -+struct wmi_coex_config_cmd { -+ u32 tlv_header; -+ u32 vdev_id; -+ u32 config_type; -+ union { -+ struct { -+ u32 coex_enable; -+ } __packed; -+ -+ struct { -+ u32 pta_num; -+ u32 coex_mode; -+ u32 bt_txrx_time; -+ u32 bt_priority_time; -+ u32 pta_algorithm; -+ u32 pta_priority; -+ } __packed; -+ -+ struct { -+ u32 wlan_pkt_type; -+ u32 wlan_pkt_type_continued; -+ u32 wlan_pkt_weight; -+ u32 bt_pkt_weight; -+ } __packed; -+ } __packed; -+} __packed; -+ - struct wmi_vdev_set_wmm_params_cmd { - u32 tlv_header; - u32 vdev_id; -@@ -6553,6 +6626,8 @@ int ath11k_wmi_pdev_non_srg_obss_color_e - u32 *bitmap); - int ath11k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(struct ath11k *ar, - u32 *bitmap); -+int ath11k_send_coex_config_cmd(struct ath11k *ar, -+ struct coex_config_arg *coex_config); - 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/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 52037816a113b1..00000000000000 --- 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 86812a1830d817..00000000000000 --- 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 734b6fb8c4b160..00000000000000 --- 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 c61c206c417de7..00000000000000 --- 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 ffae27277d7316..00000000000000 --- 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-374-ath11k-Check-skb_headroom-before-using-skb_push.patch b/package/kernel/mac80211/patches/ath11k_nss/913-374-ath11k-Check-skb_headroom-before-using-skb_push.patch deleted file mode 100644 index 1bbbdd6c7446da..00000000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/913-374-ath11k-Check-skb_headroom-before-using-skb_push.patch +++ /dev/null @@ -1,209 +0,0 @@ -From efecc6e8355d02aeac7bf1a43397551440a8d0d8 Mon Sep 17 00:00:00 2001 -From: Tamizh Chelvam Raja -Date: Thu, 30 Mar 2023 22:12:56 +0530 -Subject: [PATCH] ath11k: Check skb_headroom before using skb_push - -Below kernel panic may occur if there is no -skb_headroom available for performing skb_push. - -<4>[67506.565072] CPU: 1 PID: 1741 Comm: ap-wireless-opt Not tainted 5.4.89+ #0 -<4>[67506.578860] Hardware name: Generic DT based system -<4>[67506.585728] PC is at fortify_panic+0x10/0x18 -<4>[67506.590406] LR is at fortify_panic+0x10/0x18 - -(fortify_panic) from [<7f2cd3cc>] (ath11k_dp_rx_crypto_icv_len+0x1e0/0x161c [ath11k]) -(ath11k_dp_rx_crypto_icv_len [ath11k]) from [<7f2cdbac>] (ath11k_dp_rx_crypto_icv_len+0x9c0/0x161c [ath11k]) -(ath11k_dp_rx_crypto_icv_len [ath11k]) from [<7f2ce0e8>] (ath11k_dp_rx_crypto_icv_len+0xefc/0x161c [ath11k]) -(ath11k_dp_rx_crypto_icv_len [ath11k]) from [<7f2cedb0>] (ath11k_dp_process_rx+0x4ec/0x544 [ath11k]) -(ath11k_dp_process_rx [ath11k]) from [<7f2c417c>] (ath11k_dp_service_srng+0xdc/0x2a0 [ath11k]) -(ath11k_dp_service_srng [ath11k]) from [<7f0d78c8>] (ath11k_pci_ext_grp_napi_poll+0x20/0x50 [ath11k_pci]) -(ath11k_pci_ext_grp_napi_poll [ath11k_pci]) from [<806a6a74>] (__napi_poll+0x28/0xb8) -(__napi_poll) from [<806a6c9c>] (net_rx_action+0xec/0x280) -(net_rx_action) from [<8010226c>] (__do_softirq+0xc4/0x248) -(__do_softirq) from [<8011f230>] (irq_exit+0x6c/0xcc) -(irq_exit) from [<80162a08>] (__handle_domain_irq+0x8c/0xb0) -(__handle_domain_irq) from [<803f0188>] (gic_handle_irq+0x54/0x8c) -(gic_handle_irq) from [<80101a8c>] (__irq_svc+0x6c/0xa8) - -Fix this by checking skb_headroom and expand the -headroom if required size is not available. - -Signed-off-by: Tamizh Chelvam Raja ---- - drivers/net/wireless/ath/ath11k/dp_rx.c | 70 +++++++++++++++++++++++++ - 1 file changed, 70 insertions(+) - ---- 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 - size_t hdr_len, crypto_len; - struct ieee80211_hdr *hdr; - u16 fc, qos_ctl = 0; -+ int expand_by; - u8 *crypto_hdr; - - if (!(status->flag & RX_FLAG_IV_STRIPPED)) { - crypto_len = ath11k_dp_rx_crypto_param_len(ar, enctype); -+ if (skb_headroom(msdu) < crypto_len) { -+ expand_by = crypto_len - skb_headroom(msdu); -+ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) -+ return; -+ } - crypto_hdr = skb_push(msdu, crypto_len); - ath11k_dp_rx_desc_get_crypto_header(ab, rx_desc, crypto_hdr, enctype); - } - - fc = ath11k_dp_rxdesc_get_mpdu_frame_ctrl(ab, rx_desc); - hdr_len = ieee80211_hdrlen(fc); -+ 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; -+ } - 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 - u8 da[ETH_ALEN]; - u8 sa[ETH_ALEN]; - u16 qos_ctl = 0; -+ int expand_by = 0; - u8 *qos, *crypto_hdr; - bool add_qos_ctrl = false; - -@@ -2359,26 +2371,46 @@ static void ath11k_dp_rx_h_undecap_nwifi - } - - if (!(status->flag & RX_FLAG_IV_STRIPPED)) { -+ 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; -+ } - if (first_hdr) { -- memcpy(skb_push(msdu, -- ath11k_dp_rx_crypto_param_len(ar, enctype)), -- (void *)hdr + hdr_len, -- ath11k_dp_rx_crypto_param_len(ar, enctype)); -+ memcpy(skb_push(msdu, crypto_param_len), -+ (void *)hdr + hdr_len, crypto_param_len); - } else { -- crypto_hdr = skb_push(msdu, ath11k_dp_rx_crypto_param_len(ar, enctype)); -+ crypto_hdr = skb_push(msdu, crypto_param_len); - ath11k_dp_rx_desc_get_crypto_header(ar->ab, - rxcb->rx_desc, crypto_hdr, enctype); - } - } - - if (!rxcb->is_first_msdu || add_qos_ctrl) { -+ if (skb_headroom(msdu) < IEEE80211_QOS_CTL_LEN) { -+ expand_by = IEEE80211_QOS_CTL_LEN - skb_headroom(msdu); -+ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) -+ return; -+ } - memcpy(skb_push(msdu, - IEEE80211_QOS_CTL_LEN), &qos_ctl, - IEEE80211_QOS_CTL_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), decap_hdr, hdr_len); - return; - } - -+ 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); - - /* original 802.11 header has a different DA and in -@@ -2487,6 +2519,7 @@ static void ath11k_dp_rx_h_undecap_eth(s - u8 da[ETH_ALEN]; - u8 sa[ETH_ALEN]; - void *rfc1042; -+ int expand_by; - 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 - ether_addr_copy(sa, eth->h_source); - rfc.snap_type = eth->h_proto; - skb_pull(msdu, sizeof(struct ethhdr)); -+ if (skb_headroom(msdu) < sizeof(struct ath11k_dp_rfc1042_hdr)) { -+ expand_by = sizeof(struct ath11k_dp_rfc1042_hdr) - skb_headroom(msdu); -+ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) -+ return; -+ } - 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 - skb_pull(msdu, sizeof(struct ethhdr)); - - /* push rfc1042/llc/snap */ -+ if (skb_headroom(msdu) < sizeof(struct ath11k_dp_rfc1042_hdr)) { -+ expand_by = sizeof(struct ath11k_dp_rfc1042_hdr) - skb_headroom(msdu); -+ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) -+ return; -+ } - 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 - 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); - - exit: -@@ -2954,10 +3007,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; -+ int expand_by; - - if (status->encoding == RX_ENC_HE && - !(status->flag & RX_FLAG_RADIOTAP_HE) && - !(status->flag & RX_FLAG_SKIP_MONITOR)) { -+ if (skb_headroom(msdu) < sizeof(known)) { -+ expand_by = sizeof(known) - skb_headroom(msdu); -+ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) -+ goto exit; -+ } - 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 - !(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/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 8e60a5f6b255f7..00000000000000 --- 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 00000000000000..d413514144f161 --- /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 d3ffa5bd8da8e7..c4b6d2339deea1 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: +@@ -2756,10 +2756,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 +@@ -2769,6 +2802,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 +@@ -2785,18 +2820,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 +@@ -2825,8 +2848,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 +@@ -2835,6 +2856,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_ipq8074_rx_desc_get_hal_mpdu_len, ++ .rx_desc_get_hal_mpdu_len = ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_len, }; const struct ath11k_hw_ops wcn6855_ops = { -@@ -1339,6 +1354,7 @@ const struct ath11k_hw_ops ipq5018_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 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 4831424fa40810..5c29297c3363f8 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 00000000000000..d5e6ec621fcbb3 --- /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 +@@ -26,10 +26,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))"); + + struct ath11k_base *ath11k_soc[MAX_SOCS]; + 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 00000000000000..6a96689002eedb --- /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 +@@ -1480,6 +1480,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 +@@ -1489,6 +1490,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 +@@ -408,6 +408,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 96% 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 326db09145b342..1365bff54c1bbe 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 +@@ -5376,8 +5376,11 @@ int ath11k_dp_rx_process_mon_status(stru goto next_skb; } 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 9be70411b10996..c9dc6912d0d185 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: +@@ -2893,11 +2893,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 +@@ -2919,10 +2920,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 +@@ -2980,7 +2984,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 +@@ -2998,10 +3001,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 +@@ -3034,7 +3037,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 +@@ -5372,6 +5488,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; - } +@@ -5445,8 +5610,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 8ef3d9ba7c4d91..0dfdd6a297a7a1 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 +@@ -2297,6 +2297,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 +@@ -2338,7 +2374,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 93% 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 f1dfc0f7b9a887..9b74a712452d8b 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 { +@@ -312,6 +312,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 { +@@ -370,6 +380,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", @@ -128,7 +128,7 @@ debugfs_create_file("dfs_simulate_radar", 0200, --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6148,9 +6148,9 @@ static int ath11k_mac_mgmt_tx(struct ath +@@ -6151,9 +6151,9 @@ static int ath11k_mac_mgmt_tx(struct ath */ if (is_prb_rsp && atomic_read(&ar->num_pending_mgmt_tx) > ATH11K_PRB_RSP_DROP_THRESHOLD) { @@ -140,7 +140,7 @@ } if (skb_queue_len_lockless(q) >= ATH11K_TX_MGMT_NUM_PENDING_MAX) { -@@ -6176,9 +6176,11 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6179,9 +6179,11 @@ static void ath11k_mac_op_tx(struct ieee struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_key_conf *key = info->control.hw_key; @@ -152,7 +152,7 @@ int ret; memset(skb_cb, 0, sizeof(*skb_cb)); -@@ -6192,12 +6194,21 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6195,12 +6197,21 @@ static void ath11k_mac_op_tx(struct ieee if (info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { skb_cb->flags |= ATH11K_SKB_HW_80211_ENCAP; } else if (ieee80211_is_mgmt(hdr->frame_control)) { @@ -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; @@ -198,7 +198,7 @@ int peer_id; --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -5823,6 +5823,12 @@ static int wmi_process_mgmt_tx_comp(stru +@@ -5825,6 +5825,12 @@ static int wmi_process_mgmt_tx_comp(stru struct sk_buff *msdu; struct ieee80211_tx_info *info; struct ath11k_skb_cb *skb_cb; @@ -211,7 +211,7 @@ int num_mgmt; spin_lock_bh(&ar->txmgmt_idr_lock); -@@ -5850,6 +5856,31 @@ static int wmi_process_mgmt_tx_comp(stru +@@ -5852,6 +5858,31 @@ static int wmi_process_mgmt_tx_comp(stru info->status.ack_signal = tx_compl_param->ack_rssi; } @@ -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]++; @@ -243,7 +243,7 @@ ieee80211_tx_status_irqsafe(ar->hw, msdu); num_mgmt = atomic_dec_if_positive(&ar->num_pending_mgmt_tx); -@@ -7519,6 +7550,11 @@ static void ath11k_mgmt_rx_event(struct +@@ -7521,6 +7552,11 @@ static void ath11k_mgmt_rx_event(struct struct ieee80211_hdr *hdr; u16 fc; struct ieee80211_supported_band *sband; @@ -255,7 +255,7 @@ if (ath11k_pull_mgmt_rx_params_tlv(ab, skb, &rx_ev) != 0) { ath11k_warn(ab, "failed to extract mgmt rx event"); -@@ -7584,7 +7620,34 @@ static void ath11k_mgmt_rx_event(struct +@@ -7586,7 +7622,34 @@ static void ath11k_mgmt_rx_event(struct hdr = (struct ieee80211_hdr *)skb->data; fc = le16_to_cpu(hdr->frame_control); 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 b47785828a2bd9..ca21c0b14297b2 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 100% 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 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 57% 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 dea5600324f536..55701c68d08760 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 @@ -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 79f8190d5b990f..c39580e79e1a43 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(); @@ -2841,7 +2845,7 @@ Signed-off-by: Sriram R enum hal_pn_type pn_type) --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -1164,6 +1164,44 @@ int ath11k_wmi_send_pdev_set_regdomain(s +@@ -1166,6 +1166,44 @@ int ath11k_wmi_send_pdev_set_regdomain(s return ret; } @@ -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); @@ -2991,7 +2995,7 @@ Signed-off-by: Sriram R int ath11k_dp_pdev_reo_setup(struct ath11k_base *ab); --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6367,6 +6367,16 @@ static int ath11k_mac_op_start(struct ie +@@ -6370,6 +6370,16 @@ static int ath11k_mac_op_start(struct ie goto err; } @@ -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 34b30984ca76d2..2f043fd65c86b9 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( +@@ -2029,7 +2032,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 +@@ -2056,7 +2059,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 +@@ -2084,7 +2087,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 +@@ -2820,6 +2823,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) + { +@@ -3127,6 +3146,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; + +@@ -3203,8 +3229,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) +@@ -5607,7 +5635,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; +@@ -5675,6 +5703,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 @@ @@ -557,7 +623,7 @@ Signed-off-by: Sriram R exit: mutex_unlock(&ar->conf_mutex); return ret; -@@ -6216,10 +6279,14 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6219,10 +6282,14 @@ static void ath11k_mac_op_tx(struct ieee if (control->sta) arsta = ath11k_sta_to_arsta(control->sta); @@ -573,7 +639,7 @@ Signed-off-by: Sriram R } } -@@ -6241,6 +6310,8 @@ static int ath11k_mac_config_mon_status_ +@@ -6244,6 +6311,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_ +@@ -6542,7 +6611,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 +@@ -6588,6 +6657,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 +@@ -6718,6 +6789,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 +@@ -6858,7 +6931,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: +@@ -6982,6 +7082,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 +@@ -7492,6 +7593,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 +@@ -8720,6 +8825,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 +@@ -9139,6 +9246,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 +@@ -9524,7 +9632,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 +@@ -9637,6 +9746,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/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 a937ffba79961c..d90c39c77c9a4f 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 { +@@ -117,6 +117,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 +@@ -9763,6 +9763,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 70% 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 4d7af8641311dc..d18b213cf27607 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,7 +228,7 @@ 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 +@@ -95,7 +97,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = true, @@ -267,26 +237,15 @@ Signed-off-by: Ramya Gnanasekar .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 +@@ -177,7 +180,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = true, .coldboot_cal_ftm = true, .cbcal_restart_fw = true, @@ -295,7 +254,7 @@ Signed-off-by: Ramya Gnanasekar .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 +263,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 +272,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 +289,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 +306,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 +315,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 +335,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 47146c459e796e..0d2de0ae895d6f 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); +@@ -306,6 +306,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 +@@ -416,13 +432,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 +@@ -546,11 +555,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_ +@@ -590,28 +827,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 +@@ -1320,7 +1545,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 +@@ -1334,9 +1559,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: +@@ -1409,8 +1635,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 +@@ -1467,17 +1694,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: +@@ -1496,6 +1729,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 +@@ -1886,7 +2312,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 +@@ -1940,7 +2366,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 0e6c0d92d2abde..016ace4edd7501 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; +@@ -1042,6 +1043,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 +@@ -1849,6 +1849,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 +@@ -1884,15 +1886,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" }, +@@ -154,6 +154,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 +@@ -6362,6 +6409,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 +@@ -7277,6 +7354,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 +@@ -8717,6 +8795,22 @@ static void ath11k_wmi_gtk_offload_statu 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); +@@ -8844,6 +8938,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 { +@@ -3009,6 +3009,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 { +@@ -4611,6 +4626,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 +@@ -6400,6 +6430,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 58% 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 a69c5b2af244f8..59816b1883be1d 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 @@ -22,7 +22,7 @@ Signed-off-by: Sowmiya Sree Elavalagan --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6129,6 +6129,16 @@ static int ath11k_mac_mgmt_tx_wmi(struct +@@ -6132,6 +6132,16 @@ static int ath11k_mac_mgmt_tx_wmi(struct ATH11K_SKB_CB(skb)->paddr = paddr; @@ -39,7 +39,7 @@ Signed-off-by: Sowmiya Sree Elavalagan ret = ath11k_wmi_mgmt_send(ar, arvif->vdev_id, buf_id, skb); if (ret) { ath11k_warn(ar->ab, "failed to send mgmt frame: %d\n", ret); -@@ -6196,8 +6206,8 @@ static void ath11k_mgmt_over_wmi_tx_work +@@ -6199,8 +6209,8 @@ static void ath11k_mgmt_over_wmi_tx_work } } @@ -50,7 +50,7 @@ Signed-off-by: Sowmiya Sree Elavalagan { struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue; -@@ -6259,7 +6269,7 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6262,7 +6272,7 @@ static void ath11k_mac_op_tx(struct ieee } else if (ieee80211_is_mgmt(hdr->frame_control)) { frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, hdr->frame_control); is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control); @@ -59,7 +59,7 @@ Signed-off-by: Sowmiya Sree Elavalagan if (ret) { if (ret != -EBUSY) ath11k_warn(ar->ab, "failed to queue management frame %d\n", -@@ -6274,6 +6284,20 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6277,6 +6287,20 @@ static void ath11k_mac_op_tx(struct ieee spin_unlock_bh(&ar->data_lock); } return; @@ -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 * +@@ -699,6 +699,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 +@@ -5857,8 +5906,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 +@@ -5896,6 +5945,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 +@@ -5914,10 +5968,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: +@@ -5939,12 +5996,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 +@@ -5954,7 +6012,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: +@@ -7731,10 +7789,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 +@@ -7747,7 +7806,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: +@@ -7758,6 +7817,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 +@@ -8844,6 +8933,10 @@ 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_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; @@ -424,16 +305,16 @@ Signed-off-by: Sowmiya Sree Elavalagan WMI_TX_DELBA_COMPLETE_EVENTID = WMI_TLV_CMD(WMI_GRP_BA_NEG), WMI_TX_ADDBA_COMPLETE_EVENTID, WMI_BA_RSP_SSN_EVENTID, -@@ -1880,6 +1883,9 @@ enum wmi_tlv_tag { +@@ -1878,6 +1881,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 { WMI_TLV_SERVICE_PEER_POWER_SAVE_DURATION_SUPPORT = 246, WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT = 249, @@ -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 { +@@ -4917,7 +4935,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 +@@ -5748,6 +5766,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 +@@ -6358,6 +6387,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/nss/ath11k/218-ath11k-add-support-to-enable-disable-color-collision.patch b/package/kernel/mac80211/patches/nss/ath11k/218-ath11k-add-support-to-enable-disable-color-collision.patch new file mode 100644 index 00000000000000..24520cbeafbc7a --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/218-ath11k-add-support-to-enable-disable-color-collision.patch @@ -0,0 +1,46 @@ +From ee8c401bdfa08c6b98fb5b016841db5603ba4059 Mon Sep 17 00:00:00 2001 +From: Lavanya Suresh +Date: Wed, 23 Sep 2020 21:54:34 +0530 +Subject: [PATCH] ath11k: add support to enable/disable bss color collision + detection + +Added module param to enable or disable bss color collision detection. +By default, it is disabled. This config should be changed before VAP +bringup only. + + +Signed-off-by: Lavanya Suresh +--- + drivers/net/wireless/ath/ath11k/mac.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -53,6 +54,10 @@ + .max_power = 30, \ + } + ++unsigned int color_collision_enable = 0; ++module_param_named(color_collision_detect, color_collision_enable, uint, 0644); ++MODULE_PARM_DESC(color_collision_detect, "BSS color collision detecion: 0-disable 1-enable"); ++ + static const struct ieee80211_channel ath11k_2ghz_channels[] = { + CHAN2G(1, 2412, 0), + CHAN2G(2, 2417, 0), +@@ -3723,7 +3728,7 @@ static void ath11k_mac_op_bss_info_chang + ret = ath11k_wmi_send_obss_color_collision_cfg_cmd( + ar, arvif->vdev_id, info->he_bss_color.color, + ATH11K_BSS_COLOR_COLLISION_DETECTION_AP_PERIOD_MS, +- info->he_bss_color.enabled); ++ (info->he_bss_color.enabled & color_collision_enable)); + if (ret) + ath11k_warn(ar->ab, "failed to set bss color collision on vdev %i: %d\n", + arvif->vdev_id, ret); 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 6f5fffe596172b..7a935968261d33 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 88% 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 de7bc77ef53456..429b781199f132 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,20 +33,17 @@ 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; }; struct ath11k_vif_iter { --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -4739,6 +4739,11 @@ static void ath11k_sta_rc_update_wk(stru +@@ -4748,6 +4748,11 @@ static void ath11k_sta_rc_update_wk(stru arvif = arsta->arvif; ar = arvif->ar; @@ -58,7 +55,7 @@ Signed-off-by: Sathishkumar Muruganandam if (WARN_ON(ath11k_mac_vif_chan(arvif->vif, &def))) return; -@@ -4910,17 +4915,28 @@ err_rc_bw_changed: +@@ -4919,17 +4924,28 @@ err_rc_bw_changed: static void ath11k_sta_set_4addr_wk(struct work_struct *wk) { struct ath11k *ar; @@ -89,7 +86,7 @@ Signed-off-by: Sathishkumar Muruganandam "setting USE_4ADDR for peer %pM\n", sta->addr); ret = ath11k_wmi_set_peer_param(ar, sta->addr, -@@ -4928,8 +4944,93 @@ static void ath11k_sta_set_4addr_wk(stru +@@ -4937,8 +4953,93 @@ static void ath11k_sta_set_4addr_wk(stru WMI_PEER_USE_4ADDR, 1); if (ret) @@ -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( +@@ -5268,9 +5369,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 +@@ -6654,6 +6778,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 +@@ -6874,7 +7001,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 +@@ -6894,6 +7022,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 +@@ -6923,6 +7073,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 +@@ -7145,13 +7296,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 +@@ -7168,6 +7336,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: +@@ -7211,8 +7387,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 +@@ -7272,16 +7447,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 +@@ -8804,6 +8980,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 +@@ -8860,7 +9037,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 { +@@ -5070,6 +5070,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: +@@ -1156,12 +1156,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 +@@ -1173,13 +1174,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 14274b6a72680a..bad782747c57a1 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( +@@ -1526,14 +1526,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 +@@ -1561,7 +1558,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 +@@ -1570,14 +1568,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 +@@ -1586,8 +1589,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 +@@ -1616,7 +1619,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: +@@ -1729,6 +1732,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 2361523d394ac4..3687af833b5082 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 { +@@ -97,6 +97,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 { +@@ -324,6 +329,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; +@@ -388,6 +407,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 +@@ -7027,7 +7256,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 +@@ -7040,6 +7269,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 +@@ -7064,6 +7294,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 +@@ -7104,7 +7348,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: +@@ -7263,7 +7507,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: +@@ -7274,6 +7518,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: +@@ -7371,6 +7617,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 +@@ -9959,8 +10206,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 +@@ -1939,6 +1939,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)); @@ -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 { +@@ -5774,6 +5775,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 00000000000000..ee1e977310c046 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/237-001-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch @@ -0,0 +1,102 @@ +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -1048,6 +1049,7 @@ struct ath11k_base { + } testmode; + #endif + ++ 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 c054ee146f748a..db2bbfa0d2845d 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 9bc2b50f7cbd45..8034b6186ee671 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; + } +@@ -2448,10 +2454,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 +@@ -2462,9 +2518,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) { +@@ -2475,6 +2535,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 +@@ -2484,6 +2564,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) +@@ -2725,7 +2807,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 +@@ -2792,8 +2875,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 +@@ -2808,10 +2896,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 +@@ -2828,7 +2918,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 +@@ -2836,7 +2931,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; -+ bool fast_rx; +@@ -2845,11 +2943,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; - msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(ar->ab, desc); + 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; -@@ -4160,7 +4260,8 @@ static int ath11k_dp_rx_h_null_q_desc(st +@@ -4316,6 +4415,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; + u16 msdu_len; + struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; + struct rx_attention *rx_attention; +@@ -4365,7 +4465,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 +@@ -5536,6 +5536,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 88% 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 79906c8d3a4ab3..3c4d324161644c 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 +@@ -6643,12 +6643,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: +@@ -7596,7 +7606,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 +@@ -186,7 +186,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 +@@ -212,6 +211,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,7 @@ Signed-off-by: P Praneesh }, { .name = "qca6390 hw2.0", -@@ -384,6 +384,8 @@ static struct ath11k_hw_params ath11k_hw +@@ -381,6 +382,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 +516,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; +@@ -2146,6 +2149,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 +571,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 +582,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 +603,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 +614,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/270-iphone-issue.patch b/package/kernel/mac80211/patches/nss/ath11k/270-iphone-issue.patch new file mode 100644 index 00000000000000..5890fa6a784a08 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/270-iphone-issue.patch @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -5898,6 +5898,8 @@ static int ath11k_mac_copy_he_cap(struct + memcpy(he_cap_elem->phy_cap_info, band_cap->he_cap_phy_info, + sizeof(he_cap_elem->phy_cap_info)); + ++ he_cap_elem->mac_cap_info[0] &= ~IEEE80211_HE_MAC_CAP0_HTC_HE; ++ + he_cap_elem->mac_cap_info[1] &= + IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_MASK; + 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 00000000000000..f11c9d28710d53 --- /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 +@@ -1403,6 +1403,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) +@@ -1426,6 +1491,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); +@@ -1559,6 +1627,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(); + } +@@ -1679,6 +1749,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) + { +@@ -1697,6 +1830,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) { +@@ -1764,6 +1906,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 +@@ -3474,6 +3474,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); + } + +@@ -9700,6 +9712,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, +@@ -9757,6 +9791,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, +@@ -10215,6 +10252,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 69% 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 47c6b7ec3e5ae2..6f4793b5a0afd5 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 +@@ -568,7 +568,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 +@@ -604,8 +604,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 +@@ -649,8 +647,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_ +@@ -672,7 +669,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; - 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; +@@ -739,10 +736,12 @@ ath11k_nss_vdev_special_data_receive(str 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 + if (!dev) { + dev_kfree_skb_any(skb); +@@ -791,15 +790,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 +@@ -1006,6 +1040,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 +@@ -1247,12 +1284,31 @@ int ath11k_nss_vdev_create(struct ath11k goto free_vdev; switch (arvif->vif->type) { @@ -173,16 +169,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 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( +@@ -1526,7 +1582,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( +@@ -1540,7 +1595,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 { +@@ -109,8 +109,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 00000000000000..ed3cde7c8e00ec --- /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 +@@ -7640,8 +7640,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 +@@ -6125,13 +6125,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); + +@@ -6139,6 +6139,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; + } + +@@ -6147,6 +6148,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)) && !tx_compl_param->status) +@@ -6161,34 +6184,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 7ea6b471e340aa..6bf1ba225e0bd5 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_ +@@ -1440,6 +1440,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 6ebd709e7d3298..98fb7325850498 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 +@@ -2235,6 +2235,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 +@@ -2248,6 +2249,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 +@@ -288,8 +288,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 +@@ -409,8 +409,8 @@ static inline int ath11k_nss_map_wds_pee return 0; } @@ -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 3cc13d1ba98543..60f3b246550641 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 7b87edb0ae6baa..f567ec640942c9 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 1bfbd0ebdbb27e..3b118c3fb5093c 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 +@@ -10114,6 +10114,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 00000000000000..8cd0b134bdf77e --- /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 +@@ -6197,12 +6197,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); +@@ -6524,6 +6535,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; + +@@ -6563,7 +6581,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; +@@ -6594,16 +6611,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 2e874d321d0ad1..f03b4e2d7e5df6 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 +@@ -3464,6 +3464,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_ +@@ -3477,6 +3517,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_ +@@ -3496,8 +3537,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_ +@@ -3528,18 +3568,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 a1b885c8b50e5a..af64057faf823f 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 +@@ -1839,6 +1839,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 e8ac589acfc8ec..0e99521c4d5ff0 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 4e7e37957b1f31..e1d407e57d2e6f 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; +@@ -3134,6 +3134,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: +@@ -3164,8 +3174,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 414cb06d87bd4b..3c765c9c2df46e 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 +@@ -4882,12 +4882,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 +@@ -5478,6 +5472,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/359-ath11k-fix-tkip-encryption-traffic-failure.patch b/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch similarity index 93% rename from package/kernel/mac80211/patches/ath11k_nss/359-ath11k-fix-tkip-encryption-traffic-failure.patch rename to package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch index d8c907556645cf..ec9d831abded55 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/359-ath11k-fix-tkip-encryption-traffic-failure.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch @@ -13,7 +13,7 @@ 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 +@@ -2515,7 +2515,8 @@ static void ath11k_dp_rx_h_undecap(struc ehdr = (struct ethhdr *)msdu->data; /* mac80211 allows fast path only for authorized STA */ 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 84% 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 f734c5aea8d876..b4e399144ac1ae 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: +@@ -2410,13 +2410,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 +@@ -2426,7 +2427,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; @@ -84,7 +75,7 @@ Signed-off-by: Raj Kumar Bhagat } --- a/drivers/net/wireless/ath/ath11k/peer.c +++ b/drivers/net/wireless/ath/ath11k/peer.c -@@ -373,8 +373,7 @@ void ath11k_peer_map_ast(struct ath11k * +@@ -359,8 +359,7 @@ void ath11k_peer_map_ast(struct ath11k * if ((ast_entry->type == ATH11K_AST_TYPE_WDS) || (ast_entry->type == ATH11K_AST_TYPE_MEC)) 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 00000000000000..fd4f0938cdb83b --- /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 +@@ -1501,6 +1501,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 +@@ -1323,7 +1323,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; + +@@ -1404,6 +1404,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, +@@ -1415,6 +1417,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 93% 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 90f335efbca6fb..832a7d92b35a0a 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,9 +41,9 @@ 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 { - u32 rxdma_error[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX]; +@@ -1176,6 +1176,9 @@ struct ath11k_soc_dp_stats { u32 reo_error[HAL_REO_DEST_RING_ERROR_CODE_MAX]; + u32 reo_error_drop[HAL_REO_DEST_RING_ERROR_CODE_MAX]; u32 hal_reo_error[DP_REO_DST_RING_MAX]; + u32 hal_reo_cmd_drain; + u32 reo_cmd_cache_error; @@ -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 +@@ -1416,6 +1416,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 * +@@ -1185,8 +1185,10 @@ int ath11k_dp_alloc(struct ath11k_base * INIT_LIST_HEAD(&dp->reo_cmd_list); INIT_LIST_HEAD(&dp->reo_cmd_cache_flush_list); @@ -95,7 +95,7 @@ Signed-off-by: Tamizh Chelvam Raja u32 ba_win_sz; bool active; -@@ -51,6 +52,14 @@ struct dp_reo_cache_flush_elem { +@@ -53,6 +54,14 @@ struct dp_reo_cache_flush_elem { unsigned long ts; }; @@ -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 { +@@ -298,6 +307,12 @@ struct ath11k_dp { * - reo_cmd_cache_flush_count */ spinlock_t reo_cmd_lock; @@ -122,10 +122,10 @@ Signed-off-by: Tamizh Chelvam Raja + spinlock_t reo_cmd_update_queue_lock; struct ath11k_hp_update_timer reo_cmd_timer; struct ath11k_hp_update_timer tx_ring_timer[DP_TCL_NUM_RING_MAX]; - }; + --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -21,6 +21,9 @@ +@@ -22,6 +22,9 @@ #define ATH11K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ) @@ -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( +@@ -729,13 +732,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 +@@ -781,14 +821,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 +@@ -799,11 +843,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 +@@ -811,24 +861,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 +@@ -837,6 +884,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 +@@ -854,13 +924,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: +@@ -876,34 +953,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/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch b/package/kernel/mac80211/patches/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch new file mode 100644 index 00000000000000..144d5a9ca4d36c --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch @@ -0,0 +1,49 @@ +From c9bcb26f30a1b2e3434d851aea19200a6d757cca Mon Sep 17 00:00:00 2001 +From: Aaradhana Sahu +Date: Sat, 3 Jun 2023 18:33:54 +0530 +Subject: [PATCH] ath11k: fix VLC streaming not working for wan to wlan when + multicast to unicast flag enable + +Currently, additional two bytes after 802.11 header are seen on the air. +When per-packet encap mode is native wifi and vdev level encap mode is +eth mode, native wifi encap functionality is skipped. + +This leaves QoS header unremoved in the 802.11 header of the packet. When +sending the packet HW will also add (one more) QoS header. The additional +two bytes before LLC/SNAP header confuses the receiver and those packets +will get dropped at receiver. + +Fix this issue by removing QoS header (native wifi encap functionality) +for all the packets which will be enqueued to hw in native wifi mode. + +Signed-off-by: Aaradhana Sahu +--- + drivers/net/wireless/ath/ath11k/dp_tx.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.c b/drivers/net/wireless/ath/ath11k/dp_tx.c +index 3d8417d..5c034e6 100644 +--- a/drivers/net/wireless/ath/ath11k/dp_tx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_tx.c +@@ -347,7 +347,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)) + is_diff_encap = true; + else + ath11k_dp_tx_encap_nwifi(skb); +@@ -375,7 +376,7 @@ tcl_ring_sel: + if ((!test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) && + !(info->control.flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && + !info->control.hw_key && ieee80211_has_protected(hdr->frame_control)) || +- (skb->protocol == cpu_to_be16(ETH_P_PAE) && is_diff_encap)) { ++ is_diff_encap) { + /* HW requirement is that metadata should always point to a + * 8-byte aligned address. So we add alignment pad to start of + * buffer. HTT Metadata should be ensured to be multiple of 8-bytes +-- +2.17.1 + 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 92% 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 7b3df32c05b69e..6b4433aafa4f41 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 @@ -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 */ +@@ -333,6 +370,10 @@ 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_LINK_DESC_INFO_MSG: + ath11k_nss_wifili_link_desc_return(ab, 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 00000000000000..2b7d9c50c0c776 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/456-wifi-ath11k-Advertise-TX_QUEUE-mac-hw-flag.patch @@ -0,0 +1,28 @@ +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(+) + +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index 3e79e07..32ff5c9 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -13034,6 +13034,7 @@ static int __ath11k_mac_register(struct ath11k *ar) + 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); +-- +2.34.1 + 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 90% 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 28b4fdf6468337..de7f697c7ccb7c 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 +@@ -6292,7 +6292,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 +@@ -6310,7 +6312,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,7 +67,7 @@ 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 +@@ -6326,6 +6327,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); @@ -77,11 +77,11 @@ Signed-off-by: Yuvasree Sivasankaran --- 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 86% 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 10c39288094b5f..04d842e96a107b 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,12 +18,11 @@ 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: - +@@ -217,7 +217,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) && + if ((arvif->vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) && +- skb->protocol == cpu_to_be16(ETH_P_PAE)) + (skb->protocol == cpu_to_be16(ETH_P_PAE) || + ieee80211_is_qos_nullfunc(hdr->frame_control))) is_diff_encap = true; 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 00000000000000..f5301ca9e4890f --- /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 +@@ -8232,7 +8232,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); + +@@ -8255,21 +8254,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 00000000000000..2490a8139d452a --- /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 +@@ -261,8 +261,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) + { +@@ -5323,7 +5323,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; +@@ -8175,8 +8175,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 00000000000000..3b6e24ae508bbe --- /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 +@@ -261,9 +261,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; +@@ -5253,100 +5250,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) + { +@@ -5402,187 +5305,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) +@@ -9735,6 +9457,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 00000000000000..e8e663431217c5 --- /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 +@@ -7937,6 +7937,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, +@@ -7981,15 +8005,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)) { +@@ -8029,8 +8055,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); +@@ -8054,24 +8078,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 && +@@ -9551,6 +9564,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, +@@ -9586,31 +9639,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); +@@ -9621,12 +9658,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 || +@@ -10195,6 +10226,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 00000000000000..3bcf93279c5a2f --- /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 +@@ -1919,7 +1919,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 +@@ -1664,8 +1664,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; +@@ -2105,7 +2107,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" +@@ -551,7 +553,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; +@@ -640,8 +644,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 +@@ -9869,7 +9869,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/900-fix-build.patch b/package/kernel/mac80211/patches/nss/subsys/007-fix_compilation_issue.patch similarity index 62% 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 12feacda8555f7..3b9f555b3bce51 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 +@@ -9224,7 +9224,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 +@@ -9234,9 +9234,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 +@@ -9250,7 +9250,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_ +@@ -9262,7 +9262,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_ +@@ -9274,7 +9274,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 +@@ -4771,7 +4771,7 @@ void ieee80211_color_collision_detection struct ieee80211_sub_if_data *sdata = link->sdata; sdata_lock(sdata); @@ -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 +@@ -19406,7 +19406,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 +@@ -19420,7 +19420,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 +@@ -19443,7 +19443,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 100% 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 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 99% 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 a06ef7652df538..1c508dc8884c96 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 @@ -123,7 +123,7 @@ Signed-off-by: Sriram R - + 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, @@ -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 +@@ -2368,6 +2368,9 @@ sta_get_last_rx_stats(struct sta_info *s struct ieee80211_sta_rx_stats *stats = &sta->deflink.rx_stats; int cpu; 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 100% 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 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 00000000000000..db6550ab79c2cc --- /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 +@@ -9229,4 +9229,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 +@@ -7353,6 +7353,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 */ +@@ -2818,6 +2823,8 @@ enum nl80211_commands { + * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce + * transmit power to stay within regulatory limits. u32, dBi. + * ++ * @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 +@@ -3358,6 +3365,8 @@ enum nl80211_attrs { + + NL80211_ATTR_WIPHY_ANTENNA_GAIN, + ++ 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 +@@ -7910,3 +7910,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 +@@ -3085,6 +3085,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 +@@ -20170,6 +20170,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 100% 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 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 100% 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 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 7dc88faed71f9f..cf3784afa29b2a 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 +@@ -5095,6 +5095,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 +@@ -2176,7 +2176,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 + 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 && + !is_multicast_ether_addr(skb->data)) { + if (sta) +@@ -4692,7 +4692,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 +@@ -5218,7 +5218,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 33eb5d2001db91..453f516497a5b5 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 { +@@ -2084,6 +2084,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 { +@@ -2103,6 +2105,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 +@@ -4654,16 +4654,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 93% 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 b4a735f10fc0e6..5fc14bf1d44f37 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/245-compilation_fix.patch +++ b/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch @@ -77,7 +77,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran /* 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 +@@ -4676,19 +4676,21 @@ static void ieee80211_8023_xmit(struct i ieee80211_aggr_check(sdata, sta, skb); @@ -111,7 +111,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 +@@ -4745,7 +4747,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 +120,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 +@@ -4763,9 +4765,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 goto out; } @@ -137,7 +137,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 +@@ -4776,6 +4782,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,9 +145,8 @@ 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_ +@@ -6282,13 +6289,7 @@ start_xmit: + mutex_lock(&local->mtx); if (pubsta) { sta = container_of(pubsta, struct sta_info, sta); 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 96% 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 d3e6b9850b620f..5e0a156312fe4e 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,18 +66,18 @@ 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; +@@ -792,6 +801,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 { * @ack_hwtstamp: Hardware timestamp of the received ack in nanoseconds * Only needed for Timing measurement and Fine timing measurement action @@ -112,7 +112,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran }; -@@ -2765,6 +2785,7 @@ enum ieee80211_hw_flags { +@@ -2768,6 +2788,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 { +@@ -4268,6 +4289,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 { +@@ -4651,6 +4674,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 +@@ -7509,4 +7538,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( +@@ -2521,6 +2521,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( +@@ -2537,8 +2538,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( +@@ -2552,8 +2556,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( +@@ -2588,8 +2596,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( +@@ -2631,6 +2643,7 @@ static int ieee80211_update_mesh_config( conf->dot11MeshConnectedToAuthServer = nconf->dot11MeshConnectedToAuthServer; ieee80211_mbss_info_change_notify(sdata, BSS_CHANGED_BEACON); @@ -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 +@@ -572,3 +572,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); @@ -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 +@@ -2609,7 +2609,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); + +@@ -2621,6 +2621,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 +@@ -2691,6 +2694,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 +@@ -2954,10 +2964,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 +@@ -4272,6 +4282,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 +@@ -4348,9 +4359,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 94% 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 6a37ba0e1aa730..b488e431c6cd3c 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 { +@@ -2728,6 +2728,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 { +@@ -2787,6 +2789,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_MLO_MCAST_MULTI_LINK_TX, IEEE80211_HW_SUPPORTS_NSS_OFFLOAD, IEEE80211_HW_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 d859d038003196..0a3e71bee9716f 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: +@@ -4759,6 +4759,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 +@@ -4798,6 +4859,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 95% 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 d29a05f13943bf..eb6c51c8ba0cad 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 @@ -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 +@@ -4876,6 +4881,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 +@@ -4925,6 +4934,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 +@@ -4962,9 +5002,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 e4890a3654c3b3..0be0c6106bf788 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 +@@ -4711,7 +4711,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) { +@@ -4762,7 +4762,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 00000000000000..5fd21ba6a4d42b --- /dev/null +++ b/package/kernel/mac80211/patches/nss/subsys/345-mac80211-fix-mixed-declaration.patch @@ -0,0 +1,57 @@ +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(-) + +diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c +index 76747bf..7ddfb96 100644 +--- a/net/mac80211/spectmgmt.c ++++ b/net/mac80211/spectmgmt.c +@@ -33,7 +33,10 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, + 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 ieee80211_sub_if_data *sdata, + } + + 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 +-- +2.7.4 + 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 00000000000000..82e44b83600984 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/subsys/346-mac80211-fix-bw-change-to-40Mhz-during-channel-switc.patch @@ -0,0 +1,39 @@ +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(+) + +diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c +index 7ddfb96..15c7ac3 100644 +--- a/net/mac80211/spectmgmt.c ++++ b/net/mac80211/spectmgmt.c +@@ -136,6 +136,10 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, + } + + 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; +-- +2.7.4 + 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 d128824140ecb6..ba80b62d0ac732 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 14fd82cbeaa853..eaec491461b6cc 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 +@@ -1427,8 +1427,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 { +@@ -1500,22 +1498,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 +@@ -517,18 +517,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 70e2603c8cc02b..e0415032bb8ae7 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 +@@ -2061,6 +2061,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 +@@ -4667,7 +4668,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; +@@ -4723,6 +4725,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 && +@@ -4743,11 +4746,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) { +@@ -4770,7 +4774,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 +@@ -4779,6 +4784,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 +@@ -4790,11 +4798,13 @@ void ieee80211_8023_xmit_ap(struct ieee8 info = IEEE80211_SKB_CB(skb); memset(info, 0, sizeof(*info)); @@ -165,7 +133,7 @@ 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 +@@ -4831,14 +4841,23 @@ void ieee80211_8023_xmit_ap(struct ieee8 if (sta) atomic_inc(&sta->tx_drv_pkts); } @@ -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 +@@ -4854,14 +4873,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 +@@ -4872,13 +4892,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: +@@ -6384,7 +6404,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 6614d8d496b354..61421d7d766950 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_ +@@ -2373,7 +2373,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 +@@ -510,7 +510,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 +@@ -571,7 +571,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/ath11k_nss/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch b/package/kernel/mac80211/patches/nss/subsys/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch similarity index 94% rename from package/kernel/mac80211/patches/ath11k_nss/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch rename to package/kernel/mac80211/patches/nss/subsys/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch index 31db236d5fd4ef..e3c2db4cc8a713 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch +++ b/package/kernel/mac80211/patches/nss/subsys/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch @@ -19,7 +19,7 @@ Signed-off-by: Ramanathan Choodamani --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4567,6 +4567,7 @@ netdev_tx_t ieee80211_subif_start_xmit(s +@@ -4572,6 +4572,7 @@ netdev_tx_t ieee80211_subif_start_xmit(s #ifdef CPTCFG_MAC80211_NSS_SUPPORT ieee80211_xmit_nss_fixup(skb, dev); #endif @@ -27,7 +27,7 @@ Signed-off-by: Ramanathan Choodamani if (likely(!is_multicast_ether_addr(eth->h_dest))) goto normal; -@@ -4838,7 +4839,43 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4844,7 +4845,43 @@ void ieee80211_8023_xmit_ap(struct ieee8 netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, struct net_device *dev) { 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 89% 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 e5b4d7d9e7ef4e..a2a9879f25285b 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 +@@ -3631,7 +3633,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 +@@ -3649,7 +3651,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 +@@ -3795,7 +3797,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,7 +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 +@@ -4572,7 +4574,6 @@ netdev_tx_t ieee80211_subif_start_xmit(s #ifdef CPTCFG_MAC80211_NSS_SUPPORT ieee80211_xmit_nss_fixup(skb, dev); #endif @@ -75,7 +75,7 @@ Signed-off-by: Tamizh Chelvam Raja if (likely(!is_multicast_ether_addr(eth->h_dest))) goto normal; -@@ -4714,7 +4715,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4719,7 +4720,7 @@ static void ieee80211_8023_xmit(struct i } } @@ -84,7 +84,7 @@ Signed-off-by: Tamizh Chelvam Raja if (!skb) return; -@@ -4839,6 +4840,7 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4845,6 +4846,7 @@ void ieee80211_8023_xmit_ap(struct ieee8 netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, struct net_device *dev) { @@ -92,7 +92,7 @@ Signed-off-by: Tamizh Chelvam Raja 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: +@@ -4879,9 +4881,10 @@ out: } return NETDEV_TX_OK; @@ -107,7 +107,7 @@ Signed-off-by: Tamizh Chelvam Raja 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 00000000000000..e25220a1b01c99 --- /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 +@@ -2727,6 +2727,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 { +@@ -2787,6 +2790,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 +@@ -499,6 +499,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 +@@ -1602,6 +1602,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; +@@ -1649,6 +1652,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; + +@@ -1665,7 +1671,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) +@@ -4326,7 +4333,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) { +@@ -4678,8 +4686,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); + +@@ -6414,9 +6424,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 +@@ -4516,6 +4516,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 +@@ -841,7 +841,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++) { +@@ -427,7 +429,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); +@@ -529,8 +533,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); +@@ -604,18 +606,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)) +@@ -689,7 +695,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 +@@ -1684,11 +1691,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); +@@ -2103,6 +2112,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)) || +@@ -2519,7 +2531,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(); + +@@ -2847,6 +2859,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 7043ecb079061a..c19d97a818ba17 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_ +@@ -4649,16 +4649,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 +@@ -4881,10 +4879,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 +@@ -4934,37 +4929,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 +@@ -5002,30 +4966,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 100% 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 From e83d1891e6f5af7a941438046a9c61b70e52c764 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 18 Feb 2024 01:41:24 -0500 Subject: [PATCH 206/225] feeds: Switch to fork that requires nss qdisc Without it, NSS based SQM doesn't work. --- feeds.conf.default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feeds.conf.default b/feeds.conf.default index 741b14a875d234..4527c3215a827e 100644 --- a/feeds.conf.default +++ b/feeds.conf.default @@ -3,7 +3,7 @@ src-git luci https://git.openwrt.org/project/luci.git src-git routing https://git.openwrt.org/feed/routing.git src-git telephony https://git.openwrt.org/feed/telephony.git src-git nss_packages https://github.com/qosmio/nss-packages.git;NSS-12.4-K6.1 -src-git sqm_scripts_nss https://github.com/rickkdotnet/sqm-scripts-nss.git +src-git sqm_scripts_nss https://github.com/qosmio/sqm-scripts-nss.git #src-git video https://github.com/openwrt/video.git #src-git targets https://github.com/openwrt/targets.git #src-git oldpackages http://git.openwrt.org/packages.git From ab34b14afba5e9812c8fa439da347ec07cd74f97 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Tue, 27 Feb 2024 00:44:25 -0500 Subject: [PATCH 207/225] ath11k_nss: add missing support to enable/disable bss color collision detection --- ...ort-to-enable-disable-bss-color-coll.patch | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 package/kernel/mac80211/patches/nss/subsys/649-nl80211-Add-support-to-enable-disable-bss-color-coll.patch diff --git a/package/kernel/mac80211/patches/nss/subsys/649-nl80211-Add-support-to-enable-disable-bss-color-coll.patch b/package/kernel/mac80211/patches/nss/subsys/649-nl80211-Add-support-to-enable-disable-bss-color-coll.patch new file mode 100644 index 00000000000000..058d983c8a15f6 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/subsys/649-nl80211-Add-support-to-enable-disable-bss-color-coll.patch @@ -0,0 +1,78 @@ +From e4439779d28949a61228b359a27f399df9b42b1a Mon Sep 17 00:00:00 2001 +From: Rameshkumar Sundaram +Date: Mon, 25 Oct 2021 19:06:04 +0530 +Subject: [PATCH 1/2] nl80211: add support to enable/disable bss color + collision detection + +As per 802.11ax-2021, STAs shall process BSS Color Change Announcement +(BCCA) from AP and switch to new color, but some STAs aren't processing +BCCA from AP and not doing color switch, causing them to drop data +frames from AP post color change. + +Provide an option to disable color collision detection and therefore +not to do BCCA to mitigate the same from AP. If it's required in case +where STA supports BCCA handling, then it can enabled in AP using this +option. + +Signed-off-by: Rameshkumar Sundaram +Signed-off-by: Dinesh Karthikeyan +--- + include/net/cfg80211.h | 2 ++ + include/uapi/linux/nl80211.h | 3 +++ + net/wireless/nl80211.c | 3 +++ + 3 files changed, 8 insertions(+) + +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -312,11 +312,13 @@ struct ieee80211_he_obss_pd { + * @color: the current color. + * @enabled: HE BSS color is used + * @partial: define the AID equation. ++ * @collision_detection_enabled: HE BSS color collision detection is enabled. + */ + struct cfg80211_he_bss_color { + u8 color; + bool enabled; + bool partial; ++ bool collision_detection_enabled; + }; + + /** +--- a/include/uapi/linux/nl80211.h ++++ b/include/uapi/linux/nl80211.h +@@ -7566,6 +7566,8 @@ enum nl80211_obss_pd_attributes { + * @NL80211_HE_BSS_COLOR_ATTR_COLOR: the current BSS Color. + * @NL80211_HE_BSS_COLOR_ATTR_DISABLED: is BSS coloring disabled. + * @NL80211_HE_BSS_COLOR_ATTR_PARTIAL: the AID equation to be used.. ++ * @NL80211_HE_BSS_COLOR_ATTR_COLLISION_DETECTION_DISABLED: is BSS ++ * color collision detection disabled. + * + * @__NL80211_HE_BSS_COLOR_ATTR_LAST: Internal + * @NL80211_HE_BSS_COLOR_ATTR_MAX: highest BSS Color attribute. +@@ -7576,6 +7578,7 @@ enum nl80211_bss_color_attributes { + NL80211_HE_BSS_COLOR_ATTR_COLOR, + NL80211_HE_BSS_COLOR_ATTR_DISABLED, + NL80211_HE_BSS_COLOR_ATTR_PARTIAL, ++ NL80211_HE_BSS_COLOR_ATTR_COLLISION_DETECTION_DISABLED, + + /* keep last */ + __NL80211_HE_BSS_COLOR_ATTR_LAST, +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -378,6 +378,7 @@ he_bss_color_policy[NL80211_HE_BSS_COLOR + [NL80211_HE_BSS_COLOR_ATTR_COLOR] = NLA_POLICY_RANGE(NLA_U8, 1, 63), + [NL80211_HE_BSS_COLOR_ATTR_DISABLED] = { .type = NLA_FLAG }, + [NL80211_HE_BSS_COLOR_ATTR_PARTIAL] = { .type = NLA_FLAG }, ++ [NL80211_HE_BSS_COLOR_ATTR_COLLISION_DETECTION_DISABLED] = { .type = NLA_FLAG }, + }; + + static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = { +@@ -5495,6 +5496,8 @@ static int nl80211_parse_he_bss_color(st + !nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_DISABLED]); + he_bss_color->partial = + nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_PARTIAL]); ++ he_bss_color->collision_detection_enabled = ++ !nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_COLLISION_DETECTION_DISABLED]); + + return 0; + } From fba12dde8c5120958d4417cfad82e59de3eb21ae Mon Sep 17 00:00:00 2001 From: Qosmio Date: Tue, 27 Feb 2024 00:45:32 -0500 Subject: [PATCH 208/225] ath11k_nss: 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. --- ...03-mac80211-ath11k-fw-dynamic-muedca.patch | 162 ++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/203-mac80211-ath11k-fw-dynamic-muedca.patch 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 00000000000000..a91d4aa97cbbca --- /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 From 6ba2171d7b5d6ea21a5b4c52ff2ebec1c5691c22 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Tue, 27 Feb 2024 00:46:09 -0500 Subject: [PATCH 209/225] ath11k_nss: refresh patches + cleanup Makefile --- package/kernel/mac80211/Makefile | 9 +++- .../init.d/qca-nss-pbuf => qca-nss-pbuf.init} | 0 .../068-ath11k-add-rx-histogram-stats.patch | 10 ++-- ...080-ath11k-ethernet-rx-decap-offload.patch | 6 +-- ...dma-counter-always-zero-in-peer-stat.patch | 6 +-- ...dma-counter-increamenting-improperly.patch | 6 +-- ...ul-ofdma-ru-allocation-in-peer-stats.patch | 14 +++--- .../113-ath11k-add-8023-undecap-support.patch | 4 +- ...-adding-support-for-mgmt-frame-stats.patch | 20 ++++---- .../188-ath11k-m3-ssr-dump-collection.patch | 2 +- ...91-ath11k-add-mgmt-and-data-ack-rssi.patch | 2 +- ...-ath11k_nss-add-nss-driver-interface.patch | 6 +-- .../199-003-ath11k-add-nss-support.patch | 40 ++++++++-------- ...-ath11k-Add-support-for-dynamic-vlan.patch | 4 +- ...207-ath11k-Enable-256_512MB-profiles.patch | 4 +- ...load-changes-to-NSS-driver-interface.patch | 22 ++++----- ...-support-on-NSS-offload-for-STA-mode.patch | 22 ++++----- ...14-ath11k-qos-null-frame-tx-over-wmi.patch | 46 +++++++++--------- ...pport-for-WDS-offload-in-NSS-offload.patch | 34 ++++++------- ...dev-in-NSS-for-dynamic-VLAN-handling.patch | 12 ++--- ...-dynamic-VLAN-support-in-NSS-offload.patch | 48 +++++++++---------- ...ow-fast-rx-by-bypassing-stats-update.patch | 7 ++- ...ow-fast-rx-by-bypassing-stats-update.patch | 26 +++++----- .../nss/ath11k/244-ath11k-dp-tx-perf.patch | 12 ++--- .../patches/nss/ath11k/270-iphone-issue.patch | 2 +- .../300-ath11k-nss-mesh-offload-support.patch | 18 +++---- .../301-ath11k-nss-mcbc-exception.patch | 32 ++++++------- ...lookup-failure-in-mgmt-tx-completion.patch | 12 ++--- ...e-free-of-peer-rx_tid-during-reo-cmd.patch | 2 +- ...30-ath11k-sync-wds_ast_entry-updates.patch | 10 ++-- ...TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch | 2 +- ...ing-rx-stats-with-monitor-vif-enable.patch | 8 ++-- ...1k-skip-status-ring-entry-processing.patch | 8 ++-- ...rt-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch | 2 +- ...356-ath11k-invalid-desc-sanity-check.patch | 4 +- ...-fix-clear-peer-keys-during-disassoc.patch | 4 +- ...-fix-tkip-encryption-traffic-failure.patch | 2 +- ...ct-ast-index-assignment-for-wds-peer.patch | 12 ++--- ...Fix-ppdu_id-from-firmware-PPDU-stats.patch | 8 ++-- ...Add-retry-mechanism-for-update_rx_qu.patch | 30 ++++++------ ...treaming-not-working-for-wan-to-wlan.patch | 9 +--- ...-event-handler-support-for-link-desc.patch | 8 ++-- ...th11k-Advertise-TX_QUEUE-mac-hw-flag.patch | 7 +-- ...oid-memset-of-ppdu-info-for-next-skb.patch | 12 ++--- ...support-to-send-the-QoS-Null-Data-fr.patch | 2 +- ...11k-remove-invalid-peer-create-logic.patch | 4 +- ...th11k-rename-ath11k_start_vdev_delay.patch | 4 +- ...ation-of-ath11k_mac_start_vdev_delay.patch | 6 +-- ...ailure-due-to-unexpected-peer-delete.patch | 20 ++++---- ...k-make-debugfs-sta-htt-stats-modular.patch | 8 ++-- .../subsys/007-fix_compilation_issue.patch | 20 ++++---- ...-when-using-encapsulation-offloading.patch | 2 +- .../199-001-mac80211-add-nss-support.patch | 38 +++++++-------- ...t-callback-when-hwencap-enable-in-st.patch | 2 +- ...03-mac80211-ath11k-fw-dynamic-muedca.patch | 20 ++++---- ...-ath11k-Add-support-for-dynamic-vlan.patch | 4 +- ...07-mac80211-add-nss-redirect-support.patch | 10 ++-- ...N-iftype-support-on-NSS-offload-case.patch | 12 ++--- ...-dynamic-VLAN-support-on-NSS-offload.patch | 6 +-- .../nss/subsys/245-compilation_fix.patch | 10 ++-- .../300-ath11k-nss-mesh-offload-support.patch | 40 ++++++++-------- ...TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch | 6 +-- ...-0005-mac80211-simple-tx-for-AP-mode.patch | 4 +- .../336-mac80211-Mesh-Fast-rx-support.patch | 10 ++-- ...mac80211-fix-unconditional-sta-usage.patch | 4 +- .../345-mac80211-fix-mixed-declaration.patch | 9 +--- ...change-to-40Mhz-during-channel-switc.patch | 7 +-- ...unused-RX_FLAGS-from-mac80211_rx_fla.patch | 6 +-- ...ncapsulation-of-EAPOL-frames-if-OFFL.patch | 30 ++++++------ ...fix-RCU-stall-in-mesh-fast-xmit-path.patch | 6 +-- ...-the-frame-to-driver-tx-ops-directly.patch | 4 +- ...se-HW-checksum-offload-only-for-ethm.patch | 16 +++---- ...1-Add-mac-hw-flag-to-avoid-queue-skb.patch | 38 +++++++-------- .../829-mac80211-fix-mesh-ping-issue.patch | 8 ++-- ...x-memory-corruption-during-mesh-beac.patch | 6 +-- 75 files changed, 450 insertions(+), 466 deletions(-) rename package/kernel/mac80211/files/{etc/init.d/qca-nss-pbuf => qca-nss-pbuf.init} (100%) diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 080e07a43c8042..6b36819f75cc4d 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -309,8 +309,6 @@ ifdef CONFIG_ATH11K_NSS_SUPPORT IREMAP_CFLAGS+=-I$(STAGING_DIR)/usr/include/qca-nss-drv -I$(STAGING_DIR)/usr/include/qca-nss-clients endif -NSS_PATCHES:= subsys ath10k ath11k - config-$(CONFIG_PACKAGE_MAC80211_NSS_SUPPORT) += MAC80211_NSS_SUPPORT MAKE_OPTS:= \ @@ -433,6 +431,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/files/etc/init.d/qca-nss-pbuf b/package/kernel/mac80211/files/qca-nss-pbuf.init similarity index 100% rename from package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf rename to package/kernel/mac80211/files/qca-nss-pbuf.init diff --git a/package/kernel/mac80211/patches/nss/ath11k/068-ath11k-add-rx-histogram-stats.patch b/package/kernel/mac80211/patches/nss/ath11k/068-ath11k-add-rx-histogram-stats.patch index c4b6d2339deea1..e4ac1ee17b0b2e 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/068-ath11k-add-rx-histogram-stats.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/068-ath11k-add-rx-histogram-stats.patch @@ -269,7 +269,7 @@ Signed-off-by: Manikanta Pubbisetty &fops_htt_peer_stats); --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -2756,10 +2756,43 @@ exit: +@@ -2762,10 +2762,43 @@ exit: return total_msdu_reaped; } @@ -313,7 +313,7 @@ Signed-off-by: Manikanta Pubbisetty u32 num_msdu; int i; -@@ -2769,6 +2802,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); @@ -322,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; -@@ -2785,18 +2820,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; } @@ -341,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; -@@ -2825,8 +2848,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; @@ -350,7 +350,7 @@ Signed-off-by: Manikanta Pubbisetty BUILD_BUG_ON(ARRAY_SIZE(arsta->chain_signal) > ARRAY_SIZE(ppdu_info->rssi_chain_pri20)); -@@ -2835,6 +2856,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; 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 index d5e6ec621fcbb3..3334ef52f8ec78 100644 --- 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 @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c -@@ -26,10 +26,10 @@ module_param_named(crypto_mode, ath11k_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 */ @@ -11,5 +11,5 @@ - "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)"); + "Datapath frame mode (0: raw, 1: native wifi, 2: ethernet(default))"); - struct ath11k_base *ath11k_soc[MAX_SOCS]; - + 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 index 6a96689002eedb..b46a32c09210ea 100644 --- 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 @@ -31,7 +31,7 @@ Signed-off-by: Miles Hu 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 -@@ -1480,6 +1480,7 @@ ath11k_hal_rx_parse_mon_status_tlv(struc +@@ -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; @@ -39,7 +39,7 @@ Signed-off-by: Miles Hu /* TODO: Please note that the combined rssi will not be accurate * in MU case. Rssi in MU needs to be retrieved from -@@ -1489,6 +1490,22 @@ ath11k_hal_rx_parse_mon_status_tlv(struc +@@ -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)); @@ -64,7 +64,7 @@ Signed-off-by: Miles Hu ppdu_info->rssi_chain_pri20[i] = --- a/drivers/net/wireless/ath/ath11k/hal_rx.h +++ b/drivers/net/wireless/ath/ath11k/hal_rx.h -@@ -408,6 +408,15 @@ struct hal_rx_he_sig_b2_ofdma_info { +@@ -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) diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 1365bff54c1bbe..52e2509b796c3d 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -5376,8 +5376,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/nss/ath11k/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 index c9dc6912d0d185..18477cd5234f1b 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -15,7 +15,7 @@ --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -2893,11 +2893,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; -@@ -2919,10 +2920,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; -@@ -2980,7 +2984,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)); -@@ -2998,10 +3001,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 && -@@ -3034,7 +3037,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 @@ } -@@ -5372,6 +5488,55 @@ static void ath11k_dp_rx_mon_dest_proces +@@ -5380,6 +5496,55 @@ static void ath11k_dp_rx_mon_dest_proces } } @@ -247,7 +247,7 @@ int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id, struct napi_struct *napi, int budget) { -@@ -5445,8 +5610,13 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -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)) { diff --git a/package/kernel/mac80211/patches/nss/ath11k/113-ath11k-add-8023-undecap-support.patch b/package/kernel/mac80211/patches/nss/ath11k/113-ath11k-add-8023-undecap-support.patch index 0dfdd6a297a7a1..2ba2411c3ef54b 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -2297,6 +2297,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, -@@ -2338,7 +2374,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/nss/ath11k/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 index 9b74a712452d8b..c069cc8ff9f58a 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -312,6 +312,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; -@@ -370,6 +380,8 @@ struct ath11k_vif { +@@ -372,6 +382,8 @@ struct ath11k_vif { #ifdef CPTCFG_ATH11K_DEBUGFS struct dentry *debugfs_twt; #endif /* CPTCFG_ATH11K_DEBUGFS */ @@ -128,7 +128,7 @@ debugfs_create_file("dfs_simulate_radar", 0200, --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6151,9 +6151,9 @@ static int ath11k_mac_mgmt_tx(struct ath +@@ -6148,9 +6148,9 @@ static int ath11k_mac_mgmt_tx(struct ath */ if (is_prb_rsp && atomic_read(&ar->num_pending_mgmt_tx) > ATH11K_PRB_RSP_DROP_THRESHOLD) { @@ -140,7 +140,7 @@ } if (skb_queue_len_lockless(q) >= ATH11K_TX_MGMT_NUM_PENDING_MAX) { -@@ -6179,9 +6179,11 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6176,9 +6176,11 @@ static void ath11k_mac_op_tx(struct ieee struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_key_conf *key = info->control.hw_key; @@ -152,7 +152,7 @@ int ret; memset(skb_cb, 0, sizeof(*skb_cb)); -@@ -6195,12 +6197,21 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6192,12 +6194,21 @@ static void ath11k_mac_op_tx(struct ieee if (info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { skb_cb->flags |= ATH11K_SKB_HW_80211_ENCAP; } else if (ieee80211_is_mgmt(hdr->frame_control)) { @@ -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; @@ -198,7 +198,7 @@ int peer_id; --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -5825,6 +5825,12 @@ static int wmi_process_mgmt_tx_comp(stru +@@ -5823,6 +5823,12 @@ static int wmi_process_mgmt_tx_comp(stru struct sk_buff *msdu; struct ieee80211_tx_info *info; struct ath11k_skb_cb *skb_cb; @@ -211,7 +211,7 @@ int num_mgmt; spin_lock_bh(&ar->txmgmt_idr_lock); -@@ -5852,6 +5858,31 @@ static int wmi_process_mgmt_tx_comp(stru +@@ -5850,6 +5856,31 @@ static int wmi_process_mgmt_tx_comp(stru info->status.ack_signal = tx_compl_param->ack_rssi; } @@ -243,7 +243,7 @@ ieee80211_tx_status_irqsafe(ar->hw, msdu); num_mgmt = atomic_dec_if_positive(&ar->num_pending_mgmt_tx); -@@ -7521,6 +7552,11 @@ static void ath11k_mgmt_rx_event(struct +@@ -7519,6 +7550,11 @@ static void ath11k_mgmt_rx_event(struct struct ieee80211_hdr *hdr; u16 fc; struct ieee80211_supported_band *sband; @@ -255,7 +255,7 @@ if (ath11k_pull_mgmt_rx_params_tlv(ab, skb, &rx_ev) != 0) { ath11k_warn(ab, "failed to extract mgmt rx event"); -@@ -7586,7 +7622,34 @@ static void ath11k_mgmt_rx_event(struct +@@ -7584,7 +7620,34 @@ static void ath11k_mgmt_rx_event(struct hdr = (struct ieee80211_hdr *)skb->data; fc = le16_to_cpu(hdr->frame_control); diff --git a/package/kernel/mac80211/patches/nss/ath11k/188-ath11k-m3-ssr-dump-collection.patch b/package/kernel/mac80211/patches/nss/ath11k/188-ath11k-m3-ssr-dump-collection.patch index 47b29fd19e19bb..1fe5317105c137 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/188-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/nss/ath11k/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 index 55701c68d08760..22cdb4dccb4d5d 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 +@@ -9579,6 +9579,8 @@ static int __ath11k_mac_register(struct wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index c39580e79e1a43..851e4ed0225a95 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -2803,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, @@ -2845,7 +2845,7 @@ Signed-off-by: Sriram R enum hal_pn_type pn_type) --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -1166,6 +1166,44 @@ int ath11k_wmi_send_pdev_set_regdomain(s +@@ -1164,6 +1164,44 @@ int ath11k_wmi_send_pdev_set_regdomain(s return ret; } @@ -2995,7 +2995,7 @@ Signed-off-by: Sriram R int ath11k_dp_pdev_reo_setup(struct ath11k_base *ab); --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6370,6 +6370,16 @@ static int ath11k_mac_op_start(struct ie +@@ -6367,6 +6367,16 @@ static int ath11k_mac_op_start(struct ie goto err; } diff --git a/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch b/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch index 2f043fd65c86b9..2234cb6bc4cc1d 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch @@ -357,7 +357,7 @@ Signed-off-by: Sriram R if (ar->ab->hw_params.rxdma1_enable) { rx_ring = &dp->rxdma_mon_buf_ring; -@@ -2029,7 +2032,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; } @@ -366,7 +366,7 @@ Signed-off-by: Sriram R enum hal_encrypt_type enctype) { switch (enctype) { -@@ -2056,7 +2059,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; } @@ -375,7 +375,7 @@ Signed-off-by: Sriram R enum hal_encrypt_type enctype) { switch (enctype) { -@@ -2084,7 +2087,7 @@ static int ath11k_dp_rx_crypto_param_len +@@ -2090,7 +2093,7 @@ static int ath11k_dp_rx_crypto_param_len return 0; } @@ -384,7 +384,7 @@ Signed-off-by: Sriram R enum hal_encrypt_type enctype) { switch (enctype) { -@@ -2820,6 +2823,22 @@ static void ath11k_dp_rx_process_receive +@@ -2826,6 +2829,22 @@ static void ath11k_dp_rx_process_receive } } @@ -407,7 +407,7 @@ Signed-off-by: Sriram R int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id, struct napi_struct *napi, int budget) { -@@ -3127,6 +3146,13 @@ static void ath11k_dp_rx_update_user_sta +@@ -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; @@ -421,7 +421,7 @@ Signed-off-by: Sriram R if (!rx_stats) return; -@@ -3203,8 +3229,10 @@ static void ath11k_dp_rx_update_peer_mu_ +@@ -3209,8 +3235,10 @@ static void ath11k_dp_rx_update_peer_mu_ { u32 num_users, i; @@ -433,7 +433,7 @@ Signed-off-by: Sriram R num_users = ppdu_info->num_users; if (num_users > HAL_MAX_UL_MU_USERS) -@@ -5607,7 +5635,7 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -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; @@ -442,7 +442,7 @@ Signed-off-by: Sriram R int num_buffs_reaped = 0; u32 rx_buf_sz; u16 log_type; -@@ -5675,6 +5703,7 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -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); @@ -623,7 +623,7 @@ Signed-off-by: Sriram R exit: mutex_unlock(&ar->conf_mutex); return ret; -@@ -6219,10 +6282,14 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6216,10 +6279,14 @@ static void ath11k_mac_op_tx(struct ieee if (control->sta) arsta = ath11k_sta_to_arsta(control->sta); @@ -639,7 +639,7 @@ Signed-off-by: Sriram R } } -@@ -6244,6 +6311,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; @@ -648,7 +648,7 @@ Signed-off-by: Sriram R if (ath11k_debugfs_rx_filter(ar)) tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar); } -@@ -6542,7 +6611,7 @@ static int ath11k_mac_setup_vdev_create_ +@@ -6539,7 +6608,7 @@ static int ath11k_mac_setup_vdev_create_ return 0; } @@ -657,7 +657,7 @@ Signed-off-by: Sriram R struct ieee80211_vif *vif) { struct ath11k *ar = hw->priv; -@@ -6588,6 +6657,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; } @@ -666,7 +666,7 @@ Signed-off-by: Sriram R } static bool ath11k_mac_vif_ap_active_any(struct ath11k_base *ab) -@@ -6718,6 +6789,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); @@ -675,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", -@@ -6858,7 +6931,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); @@ -711,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, -@@ -6982,6 +7082,7 @@ err_peer_del: +@@ -6979,6 +7079,7 @@ err_peer_del: } err_vdev_del: @@ -719,7 +719,7 @@ Signed-off-by: Sriram R ath11k_mac_vdev_delete(ar, arvif); spin_lock_bh(&ar->data_lock); list_del(&arvif->list); -@@ -7492,6 +7593,10 @@ ath11k_mac_update_vif_chan(struct ath11k +@@ -7489,6 +7590,10 @@ ath11k_mac_update_vif_chan(struct ath11k arvif->vdev_id, ret); continue; } @@ -730,7 +730,7 @@ Signed-off-by: Sriram R } /* Restart the internal monitor vdev on new channel */ -@@ -8720,6 +8825,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); @@ -739,7 +739,7 @@ Signed-off-by: Sriram R } #if IS_ENABLED(CONFIG_IPV6) -@@ -9139,6 +9246,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, @@ -747,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, -@@ -9524,7 +9632,8 @@ static int __ath11k_mac_register(struct +@@ -9529,7 +9637,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); @@ -757,7 +757,7 @@ Signed-off-by: Sriram R } ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; -@@ -9637,6 +9746,9 @@ static int __ath11k_mac_register(struct +@@ -9644,6 +9753,9 @@ static int __ath11k_mac_register(struct ab->hw_params.bios_sar_capa) ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa; diff --git a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Add-support-for-dynamic-vlan.patch b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Add-support-for-dynamic-vlan.patch index d90c39c77c9a4f..54a6d1528422db 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -117,6 +117,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 -@@ -9763,6 +9763,9 @@ static int __ath11k_mac_register(struct +@@ -9770,6 +9770,9 @@ static int __ath11k_mac_register(struct */ ar->hw->wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MONITOR); diff --git a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch index d18b213cf27607..d89b500015fc33 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch @@ -246,8 +246,8 @@ Signed-off-by: Ramya Gnanasekar { .hw_rev = ATH11K_HW_IPQ6018_HW10, @@ -177,7 +180,7 @@ static struct ath11k_hw_params ath11k_hw - .coldboot_cal_mm = true, - .coldboot_cal_ftm = true, + .coldboot_cal_mm = false, + .coldboot_cal_ftm = false, .cbcal_restart_fw = true, - .fw_mem_mode = 0, + .fw_mem_mode = ATH11K_QMI_TARGET_MEM_MODE, diff --git a/package/kernel/mac80211/patches/nss/ath11k/211-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 index 0d2de0ae895d6f..a470ba934507f1 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/211-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,7 +13,7 @@ Signed-off-by: Sathishkumar Muruganandam --- a/drivers/net/wireless/ath/ath11k/nss.c +++ b/drivers/net/wireless/ath/ath11k/nss.c -@@ -306,6 +306,22 @@ void ath11k_nss_wifili_event_receive(str +@@ -307,6 +307,22 @@ void ath11k_nss_wifili_event_receive(str case NSS_WIFILI_TID_REOQ_SETUP_MSG: /* TODO setup tidq */ break; @@ -36,7 +36,7 @@ Signed-off-by: Sathishkumar Muruganandam default: ath11k_dbg(ab, ATH11K_DBG_NSS, "unhandled event %d\n", msg_type); break; -@@ -416,13 +432,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) -@@ -546,11 +555,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; -@@ -590,28 +827,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; } -@@ -1320,7 +1545,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; -@@ -1334,9 +1559,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; } -@@ -1409,8 +1635,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; -@@ -1467,17 +1694,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; -@@ -1496,6 +1729,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) -@@ -1886,7 +2312,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; } -@@ -1940,7 +2366,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) { diff --git a/package/kernel/mac80211/patches/nss/ath11k/211-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 index 016ace4edd7501..8ad2cc71f8981d 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/211-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 @@ -34,7 +34,7 @@ Signed-off-by: Sathishkumar Muruganandam #endif struct ath11k_pdev_dp dp; u8 mac_addr[ETH_ALEN]; -@@ -1042,6 +1043,9 @@ struct ath11k_base { +@@ -1047,6 +1048,9 @@ struct ath11k_base { } testmode; #endif @@ -67,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 -@@ -1849,6 +1849,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; @@ -76,7 +76,7 @@ Signed-off-by: Sathishkumar Muruganandam ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "dp_htt rx msg type :0x%0x\n", type); -@@ -1884,15 +1886,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); @@ -776,7 +776,7 @@ Signed-off-by: Sathishkumar Muruganandam #endif /* _PEER_H_ */ --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -154,6 +154,8 @@ static const struct wmi_tlv_policy wmi_t +@@ -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) }, @@ -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) { -@@ -6362,6 +6409,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) { -@@ -7277,6 +7354,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: -@@ -8717,6 +8795,22 @@ static void ath11k_wmi_gtk_offload_statu +@@ -8797,6 +8875,22 @@ exit: kfree(tb); } @@ -905,7 +905,7 @@ 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; -@@ -8844,6 +8938,9 @@ static void ath11k_wmi_tlv_op_rx(struct +@@ -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; @@ -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 -@@ -3009,6 +3009,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; -@@ -4611,6 +4626,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 */ -@@ -6400,6 +6430,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/nss/ath11k/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 index 59816b1883be1d..5f31f4ded2358c 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -22,7 +22,7 @@ Signed-off-by: Sowmiya Sree Elavalagan --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6132,6 +6132,16 @@ static int ath11k_mac_mgmt_tx_wmi(struct +@@ -6129,6 +6129,16 @@ static int ath11k_mac_mgmt_tx_wmi(struct ATH11K_SKB_CB(skb)->paddr = paddr; @@ -39,7 +39,7 @@ Signed-off-by: Sowmiya Sree Elavalagan ret = ath11k_wmi_mgmt_send(ar, arvif->vdev_id, buf_id, skb); if (ret) { ath11k_warn(ar->ab, "failed to send mgmt frame: %d\n", ret); -@@ -6199,8 +6209,8 @@ static void ath11k_mgmt_over_wmi_tx_work +@@ -6196,8 +6206,8 @@ static void ath11k_mgmt_over_wmi_tx_work } } @@ -50,7 +50,7 @@ Signed-off-by: Sowmiya Sree Elavalagan { struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue; -@@ -6262,7 +6272,7 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6259,7 +6269,7 @@ static void ath11k_mac_op_tx(struct ieee } else if (ieee80211_is_mgmt(hdr->frame_control)) { frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, hdr->frame_control); is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control); @@ -59,7 +59,7 @@ Signed-off-by: Sowmiya Sree Elavalagan if (ret) { if (ret != -EBUSY) ath11k_warn(ar->ab, "failed to queue management frame %d\n", -@@ -6277,6 +6287,20 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6274,6 +6284,20 @@ static void ath11k_mac_op_tx(struct ieee spin_unlock_bh(&ar->data_lock); } return; @@ -91,7 +91,7 @@ Signed-off-by: Sowmiya Sree Elavalagan [WMI_TAG_SCAN_EVENT] = { .min_len = sizeof(struct wmi_scan_event) }, [WMI_TAG_PEER_STA_KICKOUT_EVENT] -@@ -699,6 +699,55 @@ int ath11k_wmi_mgmt_send(struct ath11k * +@@ -701,6 +701,55 @@ int ath11k_wmi_mgmt_send(struct ath11k * return ret; } @@ -147,7 +147,7 @@ Signed-off-by: Sowmiya Sree Elavalagan int ath11k_wmi_vdev_create(struct ath11k *ar, u8 *macaddr, struct vdev_create_params *param) { -@@ -5857,8 +5906,8 @@ static int ath11k_pull_mgmt_rx_params_tl +@@ -5905,8 +5954,8 @@ static int ath11k_pull_mgmt_rx_params_tl return 0; } @@ -158,7 +158,7 @@ Signed-off-by: Sowmiya Sree Elavalagan { struct sk_buff *msdu; struct ieee80211_tx_info *info; -@@ -5896,6 +5945,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; } @@ -170,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); -@@ -5914,10 +5968,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; @@ -188,7 +188,7 @@ Signed-off-by: Sowmiya Sree Elavalagan spin_unlock_bh(&ar->data_lock); skip_mgmt_stats: -@@ -5939,12 +5996,13 @@ skip_mgmt_stats: +@@ -5987,12 +6044,13 @@ skip_mgmt_stats: return 0; } @@ -206,7 +206,7 @@ Signed-off-by: Sowmiya Sree Elavalagan int ret; tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); -@@ -5954,7 +6012,7 @@ static int ath11k_pull_mgmt_tx_compl_par +@@ -6002,7 +6060,7 @@ static int ath11k_pull_mgmt_tx_compl_par return ret; } @@ -215,7 +215,7 @@ Signed-off-by: Sowmiya Sree Elavalagan if (!ev) { ath11k_warn(ab, "failed to fetch mgmt tx compl ev"); kfree(tb); -@@ -7731,10 +7789,11 @@ exit: +@@ -7810,10 +7868,11 @@ exit: static void ath11k_mgmt_tx_compl_event(struct ath11k_base *ab, struct sk_buff *skb) { @@ -229,7 +229,7 @@ Signed-off-by: Sowmiya Sree Elavalagan ath11k_warn(ab, "failed to extract mgmt tx compl event"); return; } -@@ -7747,7 +7806,7 @@ static void ath11k_mgmt_tx_compl_event(s +@@ -7826,7 +7885,7 @@ static void ath11k_mgmt_tx_compl_event(s goto exit; } @@ -238,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", -@@ -7758,6 +7817,36 @@ exit: +@@ -7837,6 +7896,36 @@ exit: rcu_read_unlock(); } @@ -275,9 +275,9 @@ 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) -@@ -8844,6 +8933,10 @@ 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); @@ -305,7 +305,7 @@ Signed-off-by: Sowmiya Sree Elavalagan WMI_TX_DELBA_COMPLETE_EVENTID = WMI_TLV_CMD(WMI_GRP_BA_NEG), WMI_TX_ADDBA_COMPLETE_EVENTID, WMI_BA_RSP_SSN_EVENTID, -@@ -1878,6 +1881,9 @@ enum wmi_tlv_tag { +@@ -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, @@ -315,7 +315,7 @@ Signed-off-by: Sowmiya Sree Elavalagan 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, @@ -333,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 @@ -341,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) @@ -354,7 +354,7 @@ Signed-off-by: Sowmiya Sree Elavalagan u32 tlv_header; u32 tx_params_dword0; u32 tx_params_dword1; -@@ -4917,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]; }; @@ -363,7 +363,7 @@ Signed-off-by: Sowmiya Sree Elavalagan u32 desc_id; u32 status; u32 pdev_id; -@@ -5748,6 +5766,17 @@ struct wmi_debug_log_config_cmd_fixed_pa +@@ -5790,6 +5808,17 @@ struct wmi_debug_log_config_cmd_fixed_pa u32 value; } __packed; @@ -381,7 +381,7 @@ Signed-off-by: Sowmiya Sree Elavalagan #define WMI_MAX_MEM_REQS 32 #define MAX_RADIOS 3 -@@ -6358,6 +6387,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/nss/ath11k/235-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 index 429b781199f132..729ee80199b9a2 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/235-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 @@ -43,7 +43,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 -@@ -4748,6 +4748,11 @@ static void ath11k_sta_rc_update_wk(stru +@@ -4744,6 +4744,11 @@ static void ath11k_sta_rc_update_wk(stru arvif = arsta->arvif; ar = arvif->ar; @@ -55,7 +55,7 @@ Signed-off-by: Sathishkumar Muruganandam if (WARN_ON(ath11k_mac_vif_chan(arvif->vif, &def))) return; -@@ -4919,17 +4924,28 @@ err_rc_bw_changed: +@@ -4915,17 +4920,28 @@ err_rc_bw_changed: static void ath11k_sta_set_4addr_wk(struct work_struct *wk) { struct ath11k *ar; @@ -86,7 +86,7 @@ Signed-off-by: Sathishkumar Muruganandam "setting USE_4ADDR for peer %pM\n", sta->addr); ret = ath11k_wmi_set_peer_param(ar, sta->addr, -@@ -4937,8 +4953,93 @@ static void ath11k_sta_set_4addr_wk(stru +@@ -4933,8 +4949,93 @@ static void ath11k_sta_set_4addr_wk(stru WMI_PEER_USE_4ADDR, 1); if (ret) @@ -181,7 +181,7 @@ Signed-off-by: Sathishkumar Muruganandam } static int ath11k_mac_inc_num_stations(struct ath11k_vif *arvif, -@@ -5268,9 +5369,32 @@ static void ath11k_mac_op_sta_set_4addr( +@@ -5264,9 +5365,32 @@ static void ath11k_mac_op_sta_set_4addr( struct ieee80211_sta *sta, bool enabled) { struct ath11k *ar = hw->priv; @@ -214,7 +214,7 @@ Signed-off-by: Sathishkumar Muruganandam ieee80211_queue_work(ar->hw, &arsta->set_4addr_wk); arsta->use_4addr_set = true; } -@@ -6654,6 +6778,9 @@ static int ath11k_mac_op_update_vif_offl +@@ -6646,6 +6770,9 @@ static int ath11k_mac_op_update_vif_offl u32 param_id, param_value; int ret; @@ -224,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 && -@@ -6874,7 +7001,8 @@ static int ath11k_mac_op_add_interface(s +@@ -6866,7 +6993,8 @@ static int ath11k_mac_op_add_interface(s goto err; } @@ -234,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; -@@ -6894,6 +7022,28 @@ static int ath11k_mac_op_add_interface(s +@@ -6886,6 +7014,28 @@ static int ath11k_mac_op_add_interface(s arvif->vif = vif; INIT_LIST_HEAD(&arvif->list); @@ -263,7 +263,7 @@ Signed-off-by: Sathishkumar Muruganandam INIT_DELAYED_WORK(&arvif->connection_loss_work, ath11k_mac_vif_sta_connection_loss_work); -@@ -6923,6 +7073,7 @@ static int ath11k_mac_op_add_interface(s +@@ -6915,6 +7065,7 @@ static int ath11k_mac_op_add_interface(s fallthrough; case NL80211_IFTYPE_AP: arvif->vdev_type = WMI_VDEV_TYPE_AP; @@ -271,7 +271,7 @@ Signed-off-by: Sathishkumar Muruganandam break; case NL80211_IFTYPE_MONITOR: arvif->vdev_type = WMI_VDEV_TYPE_MONITOR; -@@ -7145,13 +7296,30 @@ static void ath11k_mac_op_remove_interfa +@@ -7137,13 +7288,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; @@ -304,7 +304,7 @@ Signed-off-by: Sathishkumar Muruganandam ath11k_dbg(ab, ATH11K_DBG_MAC, "remove interface (vdev %d)\n", arvif->vdev_id); -@@ -7168,6 +7336,14 @@ static void ath11k_mac_op_remove_interfa +@@ -7160,6 +7328,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); @@ -319,7 +319,7 @@ Signed-off-by: Sathishkumar Muruganandam } ret = ath11k_mac_vdev_delete(ar, arvif); -@@ -7211,8 +7387,7 @@ err_vdev_del: +@@ -7203,8 +7379,7 @@ err_vdev_del: ath11k_debugfs_remove_interface(arvif); @@ -329,7 +329,7 @@ Signed-off-by: Sathishkumar Muruganandam mutex_unlock(&ar->conf_mutex); } -@@ -7272,16 +7447,17 @@ static int ath11k_mac_op_ampdu_action(st +@@ -7264,16 +7439,17 @@ static int ath11k_mac_op_ampdu_action(st struct ieee80211_ampdu_params *params) { struct ath11k *ar = hw->priv; @@ -349,7 +349,7 @@ Signed-off-by: Sathishkumar Muruganandam break; case IEEE80211_AMPDU_TX_START: case IEEE80211_AMPDU_TX_STOP_CONT: -@@ -8804,6 +8980,7 @@ static void ath11k_mac_op_sta_statistics +@@ -8796,6 +8972,7 @@ static void ath11k_mac_op_sta_statistics { struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); struct ath11k *ar = arsta->arvif->ar; @@ -357,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); -@@ -8860,7 +9037,8 @@ static void ath11k_mac_op_sta_statistics +@@ -8852,7 +9029,8 @@ static void ath11k_mac_op_sta_statistics ATH11K_DEFAULT_NOISE_FLOOR; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); @@ -369,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 -@@ -5070,6 +5070,8 @@ enum wmi_vdev_subtype { +@@ -5082,6 +5082,8 @@ enum wmi_vdev_subtype { WMI_VDEV_SUBTYPE_MESH_11S, }; @@ -380,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 -@@ -1156,12 +1156,13 @@ err_mem_free: +@@ -1121,12 +1121,13 @@ err_mem_free: return ret; } @@ -396,7 +396,7 @@ Signed-off-by: Sathishkumar Muruganandam int ret; ret = ath11k_peer_rx_tid_setup(ar, params->sta->addr, vdev_id, -@@ -1173,13 +1174,13 @@ int ath11k_dp_rx_ampdu_start(struct ath1 +@@ -1138,13 +1139,13 @@ int ath11k_dp_rx_ampdu_start(struct ath1 return ret; } diff --git a/package/kernel/mac80211/patches/nss/ath11k/236-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 index bad782747c57a1..cb1e39f149e409 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/236-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 -@@ -1526,14 +1526,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, -@@ -1561,7 +1558,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); -@@ -1570,14 +1568,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"); -@@ -1586,8 +1589,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; } -@@ -1616,7 +1619,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; -@@ -1729,6 +1732,86 @@ free: +@@ -1730,6 +1733,86 @@ free: return ret; } diff --git a/package/kernel/mac80211/patches/nss/ath11k/236-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 index 3687af833b5082..80b8a5fc67d7ea 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/236-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 -@@ -97,6 +97,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 : -@@ -324,6 +329,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,7 +69,7 @@ Signed-off-by: Sathishkumar Muruganandam struct ath11k_vif { u32 vdev_id; enum wmi_vdev_type vdev_type; -@@ -388,6 +407,11 @@ struct ath11k_vif { +@@ -390,6 +409,11 @@ struct ath11k_vif { struct arvif_nss nss; #endif struct list_head ap_vlan_arvifs; @@ -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 -@@ -346,6 +346,10 @@ enum nl80211_he_gi ath11k_mac_he_gi_to_n +@@ -351,6 +351,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; -@@ -718,6 +722,33 @@ u8 ath11k_mac_get_target_pdev_id(struct +@@ -723,6 +727,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; -@@ -4167,6 +4198,9 @@ static int ath11k_install_key(struct ath +@@ -4172,6 +4203,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; -@@ -4256,15 +4290,40 @@ static int ath11k_clear_peer_keys(struct +@@ -4261,15 +4295,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; -@@ -4282,17 +4341,38 @@ static int ath11k_mac_op_set_key(struct +@@ -4287,17 +4346,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. */ -@@ -4337,6 +4417,74 @@ static int ath11k_mac_op_set_key(struct +@@ -4342,6 +4422,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); -@@ -4359,6 +4507,27 @@ static int ath11k_mac_op_set_key(struct +@@ -4364,6 +4512,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) { -@@ -4368,18 +4537,23 @@ static int ath11k_mac_op_set_key(struct +@@ -4373,18 +4542,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); } @@ -354,7 +354,7 @@ Signed-off-by: Sathishkumar Muruganandam switch (key->cipher) { case WLAN_CIPHER_SUITE_TKIP: -@@ -5186,6 +5360,33 @@ static u32 ath11k_mac_ieee80211_sta_bw_t +@@ -5191,6 +5365,33 @@ static u32 ath11k_mac_ieee80211_sta_bw_t return bw; } @@ -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, -@@ -5295,6 +5496,34 @@ static int ath11k_mac_op_sta_state(struc +@@ -5300,6 +5501,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) { -@@ -7027,7 +7256,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7018,7 +7247,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; -@@ -7040,6 +7269,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7031,6 +7260,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; } -@@ -7064,6 +7294,20 @@ static int ath11k_mac_op_add_interface(s +@@ -7055,6 +7285,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: -@@ -7104,7 +7348,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7095,7 +7339,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++; -@@ -7263,7 +7507,7 @@ err_peer_del: +@@ -7254,7 +7498,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 } } -@@ -7274,6 +7518,8 @@ err_vdev_del: +@@ -7265,6 +7509,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); -@@ -7371,6 +7617,7 @@ err_vdev_del: +@@ -7362,6 +7608,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, -@@ -9959,8 +10206,11 @@ static int __ath11k_mac_register(struct +@@ -9960,8 +10207,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 -@@ -1939,6 +1939,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; @@ -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; -@@ -5774,6 +5775,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 index ee1e977310c046..bbf4f20ac2326c 100644 --- 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 @@ -1,8 +1,8 @@ --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -1048,6 +1049,7 @@ struct ath11k_base { - } testmode; - #endif +@@ -1076,6 +1076,7 @@ struct ath11k_base { + u32 max_ast_index; + u32 num_ast_entries; + bool stats_disable; /* must be last */ @@ -99,4 +99,3 @@ ret = 0; - diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 8034b6186ee671..61077309338ffb 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -55,7 +55,7 @@ Signed-off-by: P Praneesh tlv_tag, ptr - begin, len, tlv_len); return -EINVAL; } -@@ -2448,10 +2454,60 @@ ath11k_dp_rx_h_find_peer(struct ath11k_b +@@ -2454,10 +2460,60 @@ ath11k_dp_rx_h_find_peer(struct ath11k_b return peer; } @@ -117,7 +117,7 @@ Signed-off-by: P Praneesh { bool fill_crypto_hdr; enum hal_encrypt_type enctype; -@@ -2462,9 +2518,13 @@ 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; @@ -132,7 +132,7 @@ Signed-off-by: P Praneesh rxcb->is_mcbc = fill_crypto_hdr; if (rxcb->is_mcbc) { -@@ -2475,6 +2535,26 @@ static void ath11k_dp_rx_h_mpdu(struct a +@@ -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) { @@ -159,7 +159,7 @@ Signed-off-by: P Praneesh if (rxcb->is_mcbc) enctype = peer->sec_type_grp; else -@@ -2484,6 +2564,8 @@ static void ath11k_dp_rx_h_mpdu(struct a +@@ -2490,6 +2570,8 @@ static void ath11k_dp_rx_h_mpdu(struct a } spin_unlock_bh(&ar->ab->base_lock); @@ -168,7 +168,7 @@ Signed-off-by: P Praneesh 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) -@@ -2725,7 +2807,8 @@ static void ath11k_dp_rx_deliver_msdu(st +@@ -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, @@ -178,7 +178,7 @@ Signed-off-by: P Praneesh { struct ath11k_base *ab = ar->ab; struct hal_rx_desc *rx_desc, *lrx_desc; -@@ -2792,8 +2875,13 @@ static int ath11k_dp_rx_process_msdu(str +@@ -2798,8 +2881,13 @@ static int ath11k_dp_rx_process_msdu(str } } @@ -193,7 +193,7 @@ Signed-off-by: P Praneesh rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; -@@ -2808,10 +2896,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) { @@ -206,7 +206,7 @@ Signed-off-by: P Praneesh if (skb_queue_empty(msdu_list)) return; -@@ -2828,7 +2918,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))) { @@ -220,7 +220,7 @@ Signed-off-by: P Praneesh if (unlikely(ret)) { ath11k_dbg(ab, ATH11K_DBG_DATA, "Unable to process msdu %d", ret); -@@ -2836,7 +2931,10 @@ static void ath11k_dp_rx_process_receive +@@ -2842,7 +2937,10 @@ static void ath11k_dp_rx_process_receive continue; } @@ -232,7 +232,7 @@ Signed-off-by: P Praneesh } } -@@ -2845,11 +2943,12 @@ void ath11k_dp_rx_from_nss(struct ath11k +@@ -2851,11 +2949,12 @@ void ath11k_dp_rx_from_nss(struct ath11k { struct ieee80211_rx_status rx_status = {0}; struct ath11k_skb_rxcb *rxcb; @@ -246,7 +246,7 @@ Signed-off-by: P Praneesh rx_status.flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; -@@ -4316,6 +4415,7 @@ static int ath11k_dp_rx_h_null_q_desc(st +@@ -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) { @@ -254,7 +254,7 @@ Signed-off-by: P Praneesh u16 msdu_len; struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; struct rx_attention *rx_attention; -@@ -4365,7 +4465,8 @@ static int ath11k_dp_rx_h_null_q_desc(st +@@ -4371,7 +4471,8 @@ static int ath11k_dp_rx_h_null_q_desc(st } ath11k_dp_rx_h_ppdu(ar, desc, status); @@ -328,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 -@@ -5536,6 +5536,14 @@ static int ath11k_mac_op_sta_state(struc +@@ -5532,6 +5532,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/nss/ath11k/244-ath11k-dp-tx-perf.patch b/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch index 3c4d324161644c..7535883c4763d0 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch @@ -430,7 +430,7 @@ Signed-off-by: P Praneesh --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6643,12 +6643,22 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6669,12 +6669,22 @@ static void ath11k_mac_op_tx(struct ieee if (control->sta) arsta = ath11k_sta_to_arsta(control->sta); @@ -454,7 +454,7 @@ Signed-off-by: P Praneesh ieee80211_free_txskb(ar->hw, skb); return; } -@@ -7596,7 +7606,7 @@ err_vdev_del: +@@ -7622,7 +7632,7 @@ err_vdev_del: idr_for_each(&ar->txmgmt_idr, ath11k_mac_vif_txmgmt_idr_remove, vif); @@ -490,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 -@@ -186,7 +186,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, @@ -498,7 +498,7 @@ Signed-off-by: P Praneesh .hal_params = &ath11k_hw_hal_params_ipq8074, .supports_dynamic_smps_6ghz = false, .alloc_cacheable_memory = true, -@@ -212,6 +211,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, @@ -507,7 +507,7 @@ Signed-off-by: P Praneesh }, { .name = "qca6390 hw2.0", -@@ -381,6 +382,8 @@ static struct ath11k_hw_params ath11k_hw +@@ -380,6 +381,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, @@ -516,7 +516,7 @@ Signed-off-by: P Praneesh }, { .name = "wcn6855 hw2.0", -@@ -2146,6 +2149,9 @@ int ath11k_core_pre_init(struct ath11k_b +@@ -2143,6 +2146,9 @@ int ath11k_core_pre_init(struct ath11k_b if (nss_offload) ab->nss.stats_enabled = 1; diff --git a/package/kernel/mac80211/patches/nss/ath11k/270-iphone-issue.patch b/package/kernel/mac80211/patches/nss/ath11k/270-iphone-issue.patch index 5890fa6a784a08..4260d0e5337451 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/270-iphone-issue.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/270-iphone-issue.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -5898,6 +5898,8 @@ static int ath11k_mac_copy_he_cap(struct +@@ -6267,6 +6267,8 @@ static int ath11k_mac_copy_he_cap(struct memcpy(he_cap_elem->phy_cap_info, band_cap->he_cap_phy_info, sizeof(he_cap_elem->phy_cap_info)); 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 index f11c9d28710d53..b31809f689548b 100644 --- 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 @@ -1046,7 +1046,7 @@ Signed-off-by: Vasanthakumar Thiagarajan #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 -@@ -1403,6 +1403,71 @@ static int ath11k_htt_tlv_ppdu_stats_par +@@ -1409,6 +1409,71 @@ static int ath11k_htt_tlv_ppdu_stats_par return 0; } @@ -1118,7 +1118,7 @@ Signed-off-by: Vasanthakumar Thiagarajan static void ath11k_update_per_peer_tx_stats(struct ath11k *ar, struct htt_ppdu_stats *ppdu_stats, u8 user) -@@ -1426,6 +1491,9 @@ ath11k_update_per_peer_tx_stats(struct a +@@ -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; @@ -1128,7 +1128,7 @@ Signed-off-by: Vasanthakumar Thiagarajan 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); -@@ -1559,6 +1627,8 @@ ath11k_update_per_peer_tx_stats(struct a +@@ -1565,6 +1633,8 @@ ath11k_update_per_peer_tx_stats(struct a ath11k_debugfs_sta_add_tx_stats(arsta, peer_stats, rate_idx); } @@ -1137,7 +1137,7 @@ Signed-off-by: Vasanthakumar Thiagarajan spin_unlock_bh(&ab->base_lock); rcu_read_unlock(); } -@@ -1679,6 +1749,69 @@ int ath11k_dp_htt_tlv_iter(struct ath11k +@@ -1685,6 +1755,69 @@ int ath11k_dp_htt_tlv_iter(struct ath11k return 0; } @@ -1207,7 +1207,7 @@ Signed-off-by: Vasanthakumar Thiagarajan static int ath11k_htt_pull_ppdu_stats(struct ath11k_base *ab, struct sk_buff *skb) { -@@ -1697,6 +1830,15 @@ static int ath11k_htt_pull_ppdu_stats(st +@@ -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; @@ -1223,7 +1223,7 @@ Signed-off-by: Vasanthakumar Thiagarajan rcu_read_lock(); ar = ath11k_mac_get_ar_by_pdev_id(ab, pdev_id); if (!ar) { -@@ -1764,6 +1906,12 @@ static int ath11k_htt_pull_ppdu_stats(st +@@ -1770,6 +1912,12 @@ static int ath11k_htt_pull_ppdu_stats(st } } @@ -1257,7 +1257,7 @@ Signed-off-by: Vasanthakumar Thiagarajan mutex_unlock(&ar->conf_mutex); } -@@ -9700,6 +9712,28 @@ err_fallback: +@@ -9714,6 +9726,28 @@ err_fallback: return 0; } @@ -1286,7 +1286,7 @@ Signed-off-by: Vasanthakumar Thiagarajan static const struct ieee80211_ops ath11k_ops = { .tx = ath11k_mac_op_tx, .wake_tx_queue = ieee80211_handle_wake_tx_queue, -@@ -9757,6 +9791,9 @@ static const struct ieee80211_ops ath11k +@@ -9771,6 +9805,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, @@ -1296,7 +1296,7 @@ Signed-off-by: Vasanthakumar Thiagarajan }; static void ath11k_mac_update_ch_list(struct ath11k *ar, -@@ -10215,6 +10252,8 @@ static int __ath11k_mac_register(struct +@@ -10231,6 +10268,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); diff --git a/package/kernel/mac80211/patches/nss/ath11k/301-ath11k-nss-mcbc-exception.patch b/package/kernel/mac80211/patches/nss/ath11k/301-ath11k-nss-mcbc-exception.patch index 6f4793b5a0afd5..2fa70d0f395ab3 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -568,7 +568,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; -@@ -604,8 +604,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); -@@ -649,8 +647,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; -@@ -672,7 +669,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,8 +53,8 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 break; case NSS_WIFI_VDEV_WDS_TYPE_MEC: ath11k_nss_mec_handler(ar, (u8 *)(skb->data)); -@@ -739,10 +736,12 @@ ath11k_nss_vdev_special_data_receive(str - struct ieee80211_vif *vif; +@@ -775,10 +772,12 @@ ath11k_nss_vdev_special_data_receive(str + struct nss_wifi_vdev_wds_per_packet_metadata *wds_metadata = NULL; struct ath11k_vif *arvif; struct ath11k_base *ab; - bool drop = false; @@ -65,9 +65,9 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 + struct ath11k_skb_rxcb *rxcb; + struct ath11k_peer *ta_peer = NULL; - if (!dev) { - dev_kfree_skb_any(skb); -@@ -791,15 +790,50 @@ ath11k_nss_vdev_special_data_receive(str + arvif = ath11k_nss_get_arvif_from_dev(dev); + if (!arvif) { +@@ -810,15 +809,50 @@ ath11k_nss_vdev_special_data_receive(str return; } @@ -126,7 +126,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 } static void -@@ -1006,6 +1040,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; @@ -136,7 +136,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 default: return -EINVAL; } -@@ -1247,12 +1284,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) { @@ -167,9 +167,9 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 + goto unregister_vdev; + } break; - default: - ret = -ENOTSUPP; -@@ -1526,7 +1582,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; @@ -177,7 +177,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 u32 features = 0; if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN || arvif->nss.ctx) -@@ -1540,7 +1595,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", @@ -188,7 +188,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 --- a/drivers/net/wireless/ath/ath11k/nss.h +++ b/drivers/net/wireless/ath/ath11k/nss.h -@@ -109,8 +109,12 @@ 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, 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 index ed3cde7c8e00ec..cb4fba0a2ffdcd 100644 --- 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 @@ -23,7 +23,7 @@ Signed-off-by: Rameshkumar Sundaram --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -7640,8 +7640,10 @@ err_vdev_del: +@@ -7643,8 +7643,10 @@ err_vdev_del: kfree(arvif->vlan_keyid_map); ath11k_peer_cleanup(ar, arvif->vdev_id); @@ -36,7 +36,7 @@ Signed-off-by: Rameshkumar Sundaram 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 -@@ -6125,13 +6125,13 @@ static int wmi_process_tx_comp(struct at +@@ -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; @@ -51,7 +51,7 @@ Signed-off-by: Rameshkumar Sundaram spin_lock_bh(&ar->txmgmt_idr_lock); msdu = idr_find(&ar->txmgmt_idr, tx_compl_param->desc_id); -@@ -6139,6 +6139,7 @@ static int wmi_process_tx_comp(struct at +@@ -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); @@ -59,7 +59,7 @@ Signed-off-by: Rameshkumar Sundaram return -ENOENT; } -@@ -6147,6 +6148,28 @@ static int wmi_process_tx_comp(struct at +@@ -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); @@ -87,8 +87,8 @@ Signed-off-by: Rameshkumar Sundaram + spin_unlock_bh(&ar->data_lock); info = IEEE80211_SKB_CB(msdu); - if ((!(info->flags & IEEE80211_TX_CTL_NO_ACK)) && !tx_compl_param->status) -@@ -6161,34 +6184,6 @@ static int wmi_process_tx_comp(struct at + 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; diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 6bf1ba225e0bd5..d733219b38aa7f 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -1440,6 +1440,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/nss/ath11k/330-ath11k-sync-wds_ast_entry-updates.patch b/package/kernel/mac80211/patches/nss/ath11k/330-ath11k-sync-wds_ast_entry-updates.patch index 98fb7325850498..662e11697f4d9c 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -2235,6 +2235,7 @@ struct ath11k_base *ath11k_core_alloc(st +@@ -2212,6 +2212,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); -@@ -2248,6 +2249,8 @@ struct ath11k_base *ath11k_core_alloc(st +@@ -2225,6 +2226,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); @@ -159,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 -@@ -288,8 +288,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); @@ -170,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, -@@ -409,8 +409,8 @@ static inline int ath11k_nss_map_wds_pee +@@ -413,8 +413,8 @@ static inline int ath11k_nss_map_wds_pee return 0; } @@ -183,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); diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 3b118c3fb5093c..3c3e436c75ce41 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -58,7 +58,7 @@ Signed-off-by: Venkateswara Naralasetty 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 -@@ -10114,6 +10114,8 @@ static int __ath11k_mac_register(struct +@@ -10154,6 +10154,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 index 8cd0b134bdf77e..752218e9b8ec26 100644 --- 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 @@ -16,7 +16,7 @@ Signed-off-by: Anilkumar Kolli --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -6197,12 +6197,23 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -5953,12 +5953,23 @@ int ath11k_dp_rx_process_mon_status(stru pmon->mon_ppdu_status = DP_PPDU_STATUS_START; } @@ -43,7 +43,7 @@ Signed-off-by: Anilkumar Kolli rcu_read_lock(); spin_lock_bh(&ab->base_lock); peer = ath11k_peer_find_by_id(ab, ppdu_info->peer_id); -@@ -6524,6 +6535,13 @@ static int ath11k_dp_full_mon_process_rx +@@ -6282,6 +6293,13 @@ static int ath11k_dp_full_mon_process_rx spin_lock_bh(&pmon->mon_lock); @@ -57,7 +57,7 @@ Signed-off-by: Anilkumar Kolli sw_mon_entries = &pmon->sw_mon_entries; rx_mon_stats = &pmon->rx_mon_stats; -@@ -6563,7 +6581,6 @@ static int ath11k_dp_full_mon_process_rx +@@ -6321,7 +6339,6 @@ static int ath11k_dp_full_mon_process_rx } rx_mon_stats->dest_ppdu_done++; @@ -65,7 +65,7 @@ Signed-off-by: Anilkumar Kolli pmon->buf_state = DP_MON_STATUS_LAG; pmon->mon_status_paddr = sw_mon_entries->mon_status_paddr; pmon->hold_mon_dst_ring = true; -@@ -6594,16 +6611,10 @@ reap_status_ring: +@@ -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) { diff --git a/package/kernel/mac80211/patches/nss/ath11k/336-ath11k-skip-status-ring-entry-processing.patch b/package/kernel/mac80211/patches/nss/ath11k/336-ath11k-skip-status-ring-entry-processing.patch index f03b4e2d7e5df6..0adf26c808aec6 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -3464,6 +3464,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) { -@@ -3477,6 +3517,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; -@@ -3496,8 +3537,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; -@@ -3528,18 +3568,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) { diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index af64057faf823f..dbd8dd904c022d 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -1839,6 +1839,11 @@ static int ath11k_core_reconfigure_on_cr +@@ -1838,6 +1838,11 @@ static int ath11k_core_reconfigure_on_cr clear_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags); diff --git a/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch b/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch index e1d407e57d2e6f..f574597dceb969 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch @@ -57,7 +57,7 @@ Signed-off-by: Nagarajan Maran spin_unlock_bh(&rx_ring->idr_lock); if (buf_id <= 0) goto fail_dma_unmap; -@@ -3134,6 +3134,16 @@ try_again: +@@ -3141,6 +3141,16 @@ try_again: while (likely(desc = (struct hal_reo_dest_ring *)ath11k_hal_srng_dst_get_next_entry(ab, srng))) { @@ -74,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, -@@ -3164,8 +3174,6 @@ try_again: +@@ -3171,8 +3181,6 @@ try_again: num_buffs_reaped[mac_id]++; diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 3c765c9c2df46e..15a8afde61ef4f 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -4882,12 +4882,6 @@ static int ath11k_station_disassoc(struc +@@ -4899,12 +4899,6 @@ static int ath11k_station_disassoc(struc return ret; } @@ -30,7 +30,7 @@ Signed-off-by: Karthikeyan Kathirvel return 0; } -@@ -5478,6 +5472,17 @@ static int ath11k_mac_op_sta_state(struc +@@ -5495,6 +5489,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/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch b/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch index ec9d831abded55..f57faaa465ae76 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch @@ -13,7 +13,7 @@ Signed-off-by: Ramya Gnanasekar --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -2515,7 +2515,8 @@ static void ath11k_dp_rx_h_undecap(struc +@@ -2564,7 +2564,8 @@ static void ath11k_dp_rx_h_undecap(struc ehdr = (struct ethhdr *)msdu->data; /* mac80211 allows fast path only for authorized STA */ diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index b4e399144ac1ae..3786bd3de9647d 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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,7 +19,7 @@ Signed-off-by: Raj Kumar Bhagat --- a/drivers/net/wireless/ath/ath11k/nss.c +++ b/drivers/net/wireless/ath/ath11k/nss.c -@@ -2410,13 +2410,14 @@ msg_free: +@@ -3871,13 +3871,14 @@ msg_free: } int ath11k_nss_map_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, @@ -35,7 +35,7 @@ Signed-off-by: Raj Kumar Bhagat int ret = 0; wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); -@@ -2426,7 +2427,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; @@ -46,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; @@ -54,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, @@ -63,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, @@ -75,7 +75,7 @@ Signed-off-by: Raj Kumar Bhagat } --- a/drivers/net/wireless/ath/ath11k/peer.c +++ b/drivers/net/wireless/ath/ath11k/peer.c -@@ -359,8 +359,7 @@ void ath11k_peer_map_ast(struct ath11k * +@@ -373,8 +373,7 @@ void ath11k_peer_map_ast(struct ath11k * if ((ast_entry->type == ATH11K_AST_TYPE_WDS) || (ast_entry->type == ATH11K_AST_TYPE_MEC)) 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 index fd4f0938cdb83b..f909ba4a673f69 100644 --- 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 @@ -14,7 +14,7 @@ Signed-off-by: Ramya Gnanasekar --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h -@@ -1501,6 +1501,7 @@ struct htt_ppdu_stats_usr_cmpltn_cmn { +@@ -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 @@ -24,7 +24,7 @@ Signed-off-by: Ramya Gnanasekar u32 ppdu_id; --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -1323,7 +1323,7 @@ static int ath11k_htt_tlv_ppdu_stats_par +@@ -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; @@ -33,7 +33,7 @@ Signed-off-by: Ramya Gnanasekar ppdu_info = data; -@@ -1404,6 +1404,8 @@ static int ath11k_htt_tlv_ppdu_stats_par +@@ -1369,6 +1369,8 @@ static int ath11k_htt_tlv_ppdu_stats_par return -EINVAL; } @@ -42,7 +42,7 @@ Signed-off-by: Ramya Gnanasekar 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, -@@ -1415,6 +1417,7 @@ static int ath11k_htt_tlv_ppdu_stats_par +@@ -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)); diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 832a7d92b35a0a..8adb5448a1564c 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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,9 +41,9 @@ Signed-off-by: Tamizh Chelvam Raja --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -1176,6 +1176,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 reo_error_drop[HAL_REO_DEST_RING_ERROR_CODE_MAX]; u32 hal_reo_error[DP_REO_DST_RING_MAX]; + u32 hal_reo_cmd_drain; + u32 reo_cmd_cache_error; @@ -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 -@@ -1416,6 +1416,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 -@@ -1185,8 +1185,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); @@ -95,7 +95,7 @@ Signed-off-by: Tamizh Chelvam Raja u32 ba_win_sz; bool active; -@@ -53,6 +54,14 @@ struct dp_reo_cache_flush_elem { +@@ -51,6 +52,14 @@ struct dp_reo_cache_flush_elem { unsigned long ts; }; @@ -110,7 +110,7 @@ Signed-off-by: Tamizh Chelvam Raja struct dp_reo_cmd { struct list_head list; struct dp_rx_tid data; -@@ -298,6 +307,12 @@ struct ath11k_dp { +@@ -295,6 +304,12 @@ struct ath11k_dp { * - reo_cmd_cache_flush_count */ spinlock_t reo_cmd_lock; @@ -122,10 +122,10 @@ Signed-off-by: Tamizh Chelvam Raja + spinlock_t reo_cmd_update_queue_lock; struct ath11k_hp_update_timer reo_cmd_timer; struct ath11k_hp_update_timer tx_ring_timer[DP_TCL_NUM_RING_MAX]; - + }; --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -22,6 +22,9 @@ +@@ -21,6 +21,9 @@ #define ATH11K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ) @@ -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) { -@@ -729,13 +732,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); -@@ -781,14 +821,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) { -@@ -799,11 +843,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); -@@ -811,24 +861,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? */ -@@ -837,6 +884,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; -@@ -854,13 +924,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); -@@ -876,34 +953,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/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch b/package/kernel/mac80211/patches/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch index 144d5a9ca4d36c..020df707b6e6a4 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch @@ -21,11 +21,9 @@ Signed-off-by: Aaradhana Sahu drivers/net/wireless/ath/ath11k/dp_tx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) -diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.c b/drivers/net/wireless/ath/ath11k/dp_tx.c -index 3d8417d..5c034e6 100644 --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -@@ -347,7 +347,8 @@ tcl_ring_sel: +@@ -221,7 +221,8 @@ tcl_ring_sel: switch (ti.encap_type) { case HAL_TCL_ENCAP_TYPE_NATIVE_WIFI: @@ -35,7 +33,7 @@ index 3d8417d..5c034e6 100644 is_diff_encap = true; else ath11k_dp_tx_encap_nwifi(skb); -@@ -375,7 +376,7 @@ tcl_ring_sel: +@@ -247,7 +248,7 @@ tcl_ring_sel: if ((!test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) && !(info->control.flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && !info->control.hw_key && ieee80211_has_protected(hdr->frame_control)) || @@ -44,6 +42,3 @@ index 3d8417d..5c034e6 100644 /* HW requirement is that metadata should always point to a * 8-byte aligned address. So we add alignment pad to start of * buffer. HTT Metadata should be ensured to be multiple of 8-bytes --- -2.17.1 - diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 6b4433aafa4f41..df9fb62bcd17b4 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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; -@@ -333,6 +370,10 @@ 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); +@@ -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/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 index 2b7d9c50c0c776..510fbc2448cee7 100644 --- 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 @@ -11,11 +11,9 @@ Signed-off-by: Yuvasree Sivasankaran drivers/net/wireless/ath/ath11k/mac.c | 1 + 1 file changed, 1 insertion(+) -diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c -index 3e79e07..32ff5c9 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -13034,6 +13034,7 @@ static int __ath11k_mac_register(struct ath11k *ar) +@@ -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); @@ -23,6 +21,3 @@ index 3e79e07..32ff5c9 100644 if (ath11k_frame_mode == ATH11K_HW_TXRX_ETHERNET) { ieee80211_hw_set(ar->hw, SUPPORTS_TX_ENCAP_OFFLOAD); --- -2.34.1 - diff --git a/package/kernel/mac80211/patches/nss/ath11k/457-wifi-ath11k-Avoid-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 index de7f697c7ccb7c..c23b6cb3c858b4 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/457-wifi-ath11k-Avoid-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 -@@ -6292,7 +6292,9 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -6090,7 +6090,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))) { -@@ -6310,7 +6312,6 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -6108,7 +6110,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,14 +67,14 @@ Signed-off-by: Yuvasree Sivasankaran ppdu_info->peer_id = HAL_INVALID_PEERID; hal_status = ath11k_hal_rx_parse_mon_status(ab, ppdu_info, skb); -@@ -6326,6 +6327,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) { +@@ -6136,6 +6137,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 @@ -221,6 +221,7 @@ struct hal_rx_mon_ppdu_info { diff --git a/package/kernel/mac80211/patches/nss/ath11k/458-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 index 04d842e96a107b..6399718268b0b1 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/458-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,7 +18,7 @@ Signed-off-by: Karthikeyan Periyasamy --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -@@ -217,7 +217,8 @@ tcl_ring_sel: +@@ -222,7 +222,8 @@ tcl_ring_sel: switch (ti.encap_type) { case HAL_TCL_ENCAP_TYPE_NATIVE_WIFI: if ((arvif->vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) && 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 index f5301ca9e4890f..b471fb326a5b48 100644 --- 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 @@ -26,7 +26,7 @@ Acked-by: Jeff Johnson --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -8232,7 +8232,6 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -8221,7 +8221,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; @@ -34,7 +34,7 @@ Acked-by: Jeff Johnson mutex_lock(&ar->conf_mutex); -@@ -8255,21 +8254,6 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -8244,21 +8243,6 @@ ath11k_mac_op_assign_vif_chanctx(struct goto out; } 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 index 2490a8139d452a..2fb2cdfd429b11 100644 --- 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 @@ -30,7 +30,7 @@ Acked-by: Jeff Johnson enum nl80211_he_ru_alloc ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc(u16 ru_phy) { -@@ -5323,7 +5323,7 @@ static int ath11k_mac_station_add(struct +@@ -5319,7 +5319,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) { @@ -39,7 +39,7 @@ Acked-by: Jeff Johnson if (ret) { ath11k_warn(ab, "failed to delay vdev start: %d\n", ret); goto free_tx_stats; -@@ -8175,8 +8175,8 @@ unlock: +@@ -8164,8 +8164,8 @@ unlock: mutex_unlock(&ar->conf_mutex); } 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 index 3b6e24ae508bbe..4d83d0f0ed9029 100644 --- 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 @@ -28,7 +28,7 @@ Acked-by: Jeff Johnson enum nl80211_he_ru_alloc ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc(u16 ru_phy) { enum nl80211_he_ru_alloc ret; -@@ -5253,100 +5250,6 @@ static void ath11k_mac_dec_num_stations( +@@ -5249,100 +5246,6 @@ static void ath11k_mac_dec_num_stations( ar->num_stations--; } @@ -129,7 +129,7 @@ Acked-by: Jeff Johnson static u32 ath11k_mac_ieee80211_sta_bw_to_wmi(struct ath11k *ar, struct ieee80211_sta *sta) { -@@ -5402,187 +5305,6 @@ static int ath11k_mac_cfg_dyn_vlan(struc +@@ -5398,187 +5301,6 @@ static int ath11k_mac_cfg_dyn_vlan(struc return ret; } @@ -317,7 +317,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) -@@ -9735,6 +9457,281 @@ ath11k_mac_op_config_mesh_offload_path(s +@@ -9739,6 +9461,281 @@ ath11k_mac_op_config_mesh_offload_path(s } #endif 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 index e8e663431217c5..d1b462519c91e8 100644 --- 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 @@ -52,7 +52,7 @@ Acked-by: Jeff Johnson --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -7937,6 +7937,30 @@ static int ath11k_mac_start_vdev_delay(s +@@ -7933,6 +7933,30 @@ static int ath11k_mac_start_vdev_delay(s return 0; } @@ -83,7 +83,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -@@ -7981,15 +8005,17 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -7977,15 +8001,17 @@ ath11k_mac_op_assign_vif_chanctx(struct goto out; } @@ -109,7 +109,7 @@ Acked-by: Jeff Johnson if (arvif->vdev_type != WMI_VDEV_TYPE_MONITOR && test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags)) { -@@ -8029,8 +8055,6 @@ ath11k_mac_op_unassign_vif_chanctx(struc +@@ -8025,8 +8051,6 @@ ath11k_mac_op_unassign_vif_chanctx(struc "chanctx unassign ptr %p vdev_id %i\n", ctx, arvif->vdev_id); @@ -118,7 +118,7 @@ Acked-by: Jeff Johnson if (ab->hw_params.vdev_start_delay && arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { spin_lock_bh(&ab->base_lock); -@@ -8054,24 +8078,13 @@ ath11k_mac_op_unassign_vif_chanctx(struc +@@ -8050,24 +8074,13 @@ ath11k_mac_op_unassign_vif_chanctx(struc return; } @@ -149,7 +149,7 @@ Acked-by: Jeff Johnson } if (ab->hw_params.vdev_start_delay && -@@ -9551,6 +9564,46 @@ exit: +@@ -9555,6 +9568,46 @@ exit: return ret; } @@ -196,7 +196,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, -@@ -9586,31 +9639,15 @@ static int ath11k_mac_op_sta_state(struc +@@ -9590,31 +9643,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)) { @@ -233,7 +233,7 @@ Acked-by: Jeff Johnson 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); -@@ -9621,12 +9658,6 @@ static int ath11k_mac_op_sta_state(struc +@@ -9625,12 +9662,6 @@ static int ath11k_mac_op_sta_state(struc } spin_unlock_bh(&ar->ab->base_lock); mutex_unlock(&ar->ab->tbl_mtx_lock); @@ -246,9 +246,9 @@ Acked-by: Jeff Johnson } else if (old_state == IEEE80211_STA_AUTH && new_state == IEEE80211_STA_ASSOC && (vif->type == NL80211_IFTYPE_AP || -@@ -10195,6 +10226,8 @@ static int __ath11k_mac_register(struct - wiphy_ext_feature_set(ar->hw->wiphy, - NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); +@@ -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); + 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 index 3bcf93279c5a2f..2362820dc9e838 100644 --- 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 @@ -40,7 +40,7 @@ ath11k-$(CPTCFG_ATH11K_THERMAL) += thermal.o --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c -@@ -1919,7 +1919,9 @@ int ath11k_debugfs_register(struct ath11 +@@ -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); @@ -120,7 +120,7 @@ &fops_peer_ps_state); --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -1664,8 +1664,10 @@ ath11k_update_per_peer_tx_stats(struct a +@@ -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; @@ -131,7 +131,7 @@ } usr_stats->rate_stats_updated = true; -@@ -2105,7 +2107,9 @@ void ath11k_dp_htt_htc_t2h_msg_handler(s +@@ -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: @@ -176,7 +176,7 @@ spin_unlock_bh(&ab->base_lock); --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -9869,7 +9869,7 @@ static const struct ieee80211_ops ath11k +@@ -9812,7 +9812,7 @@ static const struct ieee80211_ops ath11k .set_wakeup = ath11k_wow_op_set_wakeup, #endif diff --git a/package/kernel/mac80211/patches/nss/subsys/007-fix_compilation_issue.patch b/package/kernel/mac80211/patches/nss/subsys/007-fix_compilation_issue.patch index 3b9f555b3bce51..d89cfbe51cb8ab 100644 --- a/package/kernel/mac80211/patches/nss/subsys/007-fix_compilation_issue.patch +++ b/package/kernel/mac80211/patches/nss/subsys/007-fix_compilation_issue.patch @@ -1,6 +1,6 @@ --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -9224,7 +9224,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 */ @@ -9,7 +9,7 @@ enum nl80211_commands cmd, u8 count, u64 color_bitmap); -@@ -9234,9 +9234,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, @@ -21,7 +21,7 @@ 0, color_bitmap); } -@@ -9250,7 +9250,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) { @@ -30,7 +30,7 @@ count, 0); } -@@ -9262,7 +9262,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) { @@ -39,7 +39,7 @@ 0, 0); } -@@ -9274,7 +9274,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) { @@ -50,7 +50,7 @@ } --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -4771,7 +4771,7 @@ void ieee80211_color_collision_detection +@@ -4780,7 +4780,7 @@ void ieee80211_color_collision_detection struct ieee80211_sub_if_data *sdata = link->sdata; sdata_lock(sdata); @@ -72,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 +@@ -1410,18 +1410,6 @@ static void __sta_info_destroy_part2(str WARN_ON_ONCE(ret); } @@ -93,7 +93,7 @@ --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -19406,7 +19406,7 @@ void cfg80211_ch_switch_started_notify(s +@@ -19472,7 +19472,7 @@ void cfg80211_ch_switch_started_notify(s } EXPORT_SYMBOL(cfg80211_ch_switch_started_notify); @@ -102,7 +102,7 @@ enum nl80211_commands cmd, u8 count, u64 color_bitmap) { -@@ -19420,7 +19420,7 @@ int cfg80211_bss_color_notify(struct net +@@ -19486,7 +19486,7 @@ int cfg80211_bss_color_notify(struct net trace_cfg80211_bss_color_notify(dev, cmd, count, color_bitmap); @@ -111,7 +111,7 @@ if (!msg) return -ENOMEM; -@@ -19443,7 +19443,7 @@ int cfg80211_bss_color_notify(struct net +@@ -19509,7 +19509,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/nss/subsys/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 index 82d8c4e05bb11f..a5da9e91eae835 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 +@@ -4688,8 +4688,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/nss/subsys/199-001-mac80211-add-nss-support.patch b/package/kernel/mac80211/patches/nss/subsys/199-001-mac80211-add-nss-support.patch index 1c508dc8884c96..2943f6b04bad5c 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 +@@ -1408,7 +1424,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 +@@ -1416,7 +1432,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 +@@ -1989,6 +2005,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 { +@@ -2680,6 +2706,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 { +@@ -2737,6 +2765,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 { +@@ -3749,6 +3778,10 @@ struct ieee80211_prep_tx_info { * non-MLO connections. * The callback can sleep. * @@ -116,7 +116,7 @@ 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 { +@@ -4300,7 +4333,9 @@ struct ieee80211_ops { struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, u64 changed); @@ -127,7 +127,7 @@ Signed-off-by: Sriram R 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 { +@@ -4605,7 +4640,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 -@@ -2368,6 +2368,9 @@ sta_get_last_rx_stats(struct sta_info *s +@@ -2370,6 +2370,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 +@@ -4641,13 +4655,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 +@@ -2679,7 +2679,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 +@@ -2729,6 +2729,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 +@@ -2757,6 +2759,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); diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index 87c2a52b676f21..fffe171334c9a4 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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: +@@ -6215,7 +6215,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 index db6550ab79c2cc..bd9c1c024b1e5d 100644 --- 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 @@ -31,7 +31,7 @@ Signed-off-by: Muna Sinada --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -9229,4 +9229,15 @@ bool cfg80211_valid_disable_subchannel_b +@@ -9327,4 +9327,15 @@ bool cfg80211_valid_disable_subchannel_b */ void cfg80211_links_removed(struct net_device *dev, u16 link_mask); @@ -49,7 +49,7 @@ Signed-off-by: Muna Sinada #endif /* __NET_CFG80211_H */ --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -7353,6 +7353,20 @@ u32 ieee80211_calc_rx_airtime(struct iee +@@ -7361,6 +7361,20 @@ u32 ieee80211_calc_rx_airtime(struct iee int len); /** @@ -91,18 +91,18 @@ Signed-off-by: Muna Sinada /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ -@@ -2818,6 +2823,8 @@ enum nl80211_commands { - * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce - * transmit power to stay within regulatory limits. u32, dBi. +@@ -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 -@@ -3358,6 +3365,8 @@ enum nl80211_attrs { +@@ -3353,6 +3360,8 @@ enum nl80211_attrs { - NL80211_ATTR_WIPHY_ANTENNA_GAIN, + NL80211_ATTR_MLO_LINK_DISABLED, + NL80211_ATTR_HE_MUEDCA_PARAMS, + @@ -111,7 +111,7 @@ Signed-off-by: Muna Sinada __NL80211_ATTR_AFTER_LAST, --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c -@@ -7910,3 +7910,15 @@ void ieee80211_disable_rssi_reports(stru +@@ -7954,3 +7954,15 @@ void ieee80211_disable_rssi_reports(stru _ieee80211_enable_rssi_reports(sdata, 0, 0); } EXPORT_SYMBOL(ieee80211_disable_rssi_reports); @@ -129,7 +129,7 @@ Signed-off-by: Muna Sinada +EXPORT_SYMBOL(ieee80211_update_muedca_params); --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h -@@ -3085,6 +3085,26 @@ TRACE_EVENT(stop_queue, +@@ -3092,6 +3092,26 @@ TRACE_EVENT(stop_queue, ) ); @@ -158,7 +158,7 @@ Signed-off-by: Muna Sinada #undef TRACE_INCLUDE_PATH --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -20170,6 +20170,42 @@ nla_put_failure: +@@ -20199,6 +20199,42 @@ nla_put_failure: } EXPORT_SYMBOL(cfg80211_update_owe_info_event); diff --git a/package/kernel/mac80211/patches/nss/subsys/207-ath11k-Add-support-for-dynamic-vlan.patch b/package/kernel/mac80211/patches/nss/subsys/207-ath11k-Add-support-for-dynamic-vlan.patch index af46c8f0bfa05e..15d796071fa077 100644 --- a/package/kernel/mac80211/patches/nss/subsys/207-ath11k-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 +@@ -4270,6 +4273,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 +@@ -4291,6 +4296,19 @@ void __ieee80211_subif_start_xmit(struct if (IS_ERR(sta)) sta = NULL; diff --git a/package/kernel/mac80211/patches/nss/subsys/207-mac80211-add-nss-redirect-support.patch b/package/kernel/mac80211/patches/nss/subsys/207-mac80211-add-nss-redirect-support.patch index c9a12d5f127cbe..a4895803b38ba0 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 +@@ -4503,6 +4503,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 +@@ -4516,6 +4545,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 +@@ -4702,6 +4735,9 @@ netdev_tx_t ieee80211_subif_start_xmit_8 struct ieee80211_key *key; struct sta_info *sta; diff --git a/package/kernel/mac80211/patches/nss/subsys/235-001-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 index cf3784afa29b2a..55e2fff1560fb8 100644 --- a/package/kernel/mac80211/patches/nss/subsys/235-001-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 -@@ -5095,6 +5095,17 @@ void ieee80211_sta_pspoll(struct ieee802 +@@ -5098,6 +5098,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 -@@ -2176,7 +2176,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); @@ -137,8 +137,8 @@ Signed-off-by: Sathishkumar Muruganandam { --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4298,8 +4298,13 @@ void __ieee80211_subif_start_xmit(struct - atomic_inc(&sta->tx_netif_pkts); +@@ -4297,8 +4297,13 @@ void __ieee80211_subif_start_xmit(struct + sta = NULL; if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { - ap_sdata = container_of(sdata->bss, @@ -153,7 +153,7 @@ Signed-off-by: Sathishkumar Muruganandam if (ap_sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED && !is_multicast_ether_addr(skb->data)) { if (sta) -@@ -4692,7 +4692,8 @@ static void ieee80211_8023_xmit(struct i +@@ -4688,7 +4693,8 @@ static void ieee80211_8023_xmit(struct i info->hw_queue = sdata->vif.hw_queue[queue]; @@ -197,7 +197,7 @@ Signed-off-by: Sathishkumar Muruganandam drv_remove_interface(local, sdata); --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c -@@ -5218,7 +5218,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/nss/subsys/236-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 index 453f516497a5b5..803ee900bfdcc1 100644 --- a/package/kernel/mac80211/patches/nss/subsys/236-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 -@@ -2084,6 +2084,8 @@ enum ieee80211_key_flags { +@@ -2086,6 +2086,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) -@@ -2103,6 +2105,7 @@ struct ieee80211_key_conf { +@@ -2105,6 +2107,7 @@ struct ieee80211_key_conf { u8 hw_key_idx; s8 keyidx; u16 flags; @@ -102,7 +102,7 @@ Signed-off-by: Sathishkumar Muruganandam key->conf.cipher = cipher; --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4654,16 +4654,25 @@ static void ieee80211_8023_xmit(struct i +@@ -4649,16 +4649,25 @@ static void ieee80211_8023_xmit(struct i struct ieee80211_key *key, struct sk_buff *skb) { struct ieee80211_tx_info *info; diff --git a/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch b/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch index 5fc14bf1d44f37..46b716419a7cd8 100644 --- a/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch +++ b/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch @@ -77,7 +77,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran /* then other type-dependent work */ --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4676,19 +4676,21 @@ static void ieee80211_8023_xmit(struct i +@@ -4678,19 +4678,21 @@ static void ieee80211_8023_xmit(struct i ieee80211_aggr_check(sdata, sta, skb); @@ -111,7 +111,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran } skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); -@@ -4745,7 +4747,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4747,7 +4749,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 +120,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran struct sta_info *sta; #ifdef CPTCFG_MAC80211_NSS_SUPPORT -@@ -4763,9 +4765,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4765,9 +4767,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 goto out; } @@ -137,7 +137,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran goto skip_offload; key = rcu_dereference(sta->ptk[sta->ptk_idx]); -@@ -4776,6 +4782,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4778,6 +4784,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,7 +145,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran ieee80211_8023_xmit(sdata, dev, sta, key, skb); goto out; -@@ -6282,13 +6289,7 @@ start_xmit: +@@ -6284,13 +6291,7 @@ start_xmit: mutex_lock(&local->mtx); if (pubsta) { diff --git a/package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch b/package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch index 5e0a156312fe4e..55ad36baf69aa4 100644 --- a/package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch +++ b/package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch @@ -66,7 +66,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran }; /* -@@ -792,6 +801,11 @@ struct ieee80211_bss_conf { +@@ -790,6 +799,11 @@ struct ieee80211_bss_conf { bool he_full_ul_mumimo; bool eht_su_beamformer; bool eht_su_beamformee; @@ -112,7 +112,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran }; -@@ -2768,6 +2788,7 @@ enum ieee80211_hw_flags { +@@ -2769,6 +2789,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 -@@ -4268,6 +4289,8 @@ struct ieee80211_prep_tx_info { +@@ -4269,6 +4290,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. -@@ -4651,6 +4674,12 @@ struct ieee80211_ops { +@@ -4652,6 +4675,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); -@@ -7509,4 +7538,100 @@ int ieee80211_set_active_links(struct ie +@@ -7510,4 +7539,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 -@@ -2521,6 +2521,7 @@ static int ieee80211_update_mesh_config( +@@ -2523,6 +2523,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; -@@ -2537,8 +2538,11 @@ static int ieee80211_update_mesh_config( +@@ -2539,8 +2540,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)) { -@@ -2552,8 +2556,12 @@ static int ieee80211_update_mesh_config( +@@ -2554,8 +2558,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)) -@@ -2588,8 +2596,12 @@ static int ieee80211_update_mesh_config( +@@ -2590,8 +2598,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. -@@ -2631,6 +2643,7 @@ static int ieee80211_update_mesh_config( +@@ -2633,6 +2645,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 -@@ -572,3 +572,23 @@ int drv_change_sta_links(struct ieee8021 +@@ -579,3 +579,23 @@ int drv_change_sta_links(struct ieee8021 return 0; } @@ -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 +@@ -315,6 +315,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 +@@ -356,6 +360,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,7 @@ 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 -@@ -2609,7 +2609,7 @@ 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; @@ -1182,7 +1182,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran int ret; u8 link_id = u32_get_bits(ctrl_flags, IEEE80211_TX_CTRL_MLO_LINK); -@@ -2621,6 +2621,9 @@ static struct sk_buff *ieee80211_build_h +@@ -2622,6 +2622,9 @@ static struct sk_buff *ieee80211_build_h info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; #endif @@ -1192,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]; -@@ -2691,6 +2694,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: @@ -1206,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; -@@ -2954,10 +2964,10 @@ static struct sk_buff *ieee80211_build_h +@@ -2955,10 +2965,10 @@ static struct sk_buff *ieee80211_build_h skb_reset_mac_header(skb); @@ -1221,7 +1221,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran info->ack_frame_id = info_id; info->band = band; -@@ -4272,6 +4282,7 @@ void __ieee80211_subif_start_xmit(struct +@@ -4274,6 +4284,7 @@ void __ieee80211_subif_start_xmit(struct struct sk_buff *next; int len = skb->len; struct ieee80211_key *key = NULL; @@ -1229,7 +1229,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran struct ieee80211_sub_if_data *ap_sdata; if (unlikely(!ieee80211_sdata_running(sdata) || skb->len < ETH_HLEN)) { -@@ -4348,9 +4359,15 @@ void __ieee80211_subif_start_xmit(struct +@@ -4350,9 +4361,15 @@ void __ieee80211_subif_start_xmit(struct goto out; } diff --git a/package/kernel/mac80211/patches/nss/subsys/335-0003-ath11k-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 index b488e431c6cd3c..f78d7ce6e09304 100644 --- a/package/kernel/mac80211/patches/nss/subsys/335-0003-ath11k-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 -@@ -2728,6 +2728,8 @@ struct ieee80211_txq { +@@ -2731,6 +2731,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 { -@@ -2787,6 +2789,7 @@ enum ieee80211_hw_flags { +@@ -2790,6 +2792,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/nss/subsys/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 index 0a3e71bee9716f..63373b7751f9eb 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -4759,6 +4759,67 @@ out_free: +@@ -4761,6 +4761,67 @@ out_free: kfree_skb(skb); } @@ -82,7 +82,7 @@ Signed-off-by: Aloka Dixit netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, struct net_device *dev) { -@@ -4798,6 +4859,11 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4800,6 +4861,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/nss/subsys/336-mac80211-Mesh-Fast-rx-support.patch b/package/kernel/mac80211/patches/nss/subsys/336-mac80211-Mesh-Fast-rx-support.patch index eb6c51c8ba0cad..0b89a11957bec4 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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); @@ -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; -@@ -4876,6 +4881,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 -@@ -4925,6 +4934,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))) -@@ -4962,9 +5002,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/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch b/package/kernel/mac80211/patches/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch index 0be0c6106bf788..0cb2a1e95244e3 100644 --- a/package/kernel/mac80211/patches/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch +++ b/package/kernel/mac80211/patches/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch @@ -33,7 +33,7 @@ Signed-off-by: Tamizh Chelvam --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4711,7 +4711,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4695,7 +4695,7 @@ static void ieee80211_8023_xmit(struct i ieee80211_aggr_check(sdata, sta, skb); @@ -42,7 +42,7 @@ Signed-off-by: Tamizh Chelvam tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); if (tid_tx) { -@@ -4762,7 +4762,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4746,7 +4746,7 @@ static void ieee80211_8023_xmit(struct i &info->flags, NULL); dev_sw_netstats_tx_add(dev, skbs, len); 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 index 5fd21ba6a4d42b..808f69e644ed61 100644 --- 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 @@ -10,11 +10,9 @@ Signed-off-by: Hari Chandrakanthan net/mac80211/spectmgmt.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) -diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c -index 76747bf..7ddfb96 100644 --- a/net/mac80211/spectmgmt.c +++ b/net/mac80211/spectmgmt.c -@@ -33,7 +33,10 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, +@@ -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; @@ -25,7 +23,7 @@ index 76747bf..7ddfb96 100644 memset(csa_ie, 0, sizeof(*csa_ie)); -@@ -133,20 +136,13 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, +@@ -133,20 +136,13 @@ int ieee80211_parse_ch_switch_ie(struct } if (wide_bw_chansw_ie) { @@ -52,6 +50,3 @@ index 76747bf..7ddfb96 100644 /* default, for the case of IEEE80211_VHT_CHANWIDTH_USE_HT, * to the previously parsed chandef --- -2.7.4 - 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 index 82e44b83600984..df2b3a9257b115 100644 --- 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 @@ -19,11 +19,9 @@ Signed-off-by: Hari Chandrakanthan net/mac80211/spectmgmt.c | 4 ++++ 1 file changed, 4 insertions(+) -diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c -index 7ddfb96..15c7ac3 100644 --- a/net/mac80211/spectmgmt.c +++ b/net/mac80211/spectmgmt.c -@@ -136,6 +136,10 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, +@@ -136,6 +136,10 @@ int ieee80211_parse_ch_switch_ie(struct } if (wide_bw_chansw_ie) { @@ -34,6 +32,3 @@ index 7ddfb96..15c7ac3 100644 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; --- -2.7.4 - diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index eaec491461b6cc..2cb2ebe6f58f76 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -1427,8 +1427,6 @@ ieee80211_tx_info_clear_status(struct ie +@@ -1405,8 +1405,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 -@@ -1500,22 +1498,21 @@ enum mac80211_rx_flags { +@@ -1478,22 +1476,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 -@@ -517,18 +517,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/nss/subsys/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 index e0415032bb8ae7..a947728fc661f1 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -2061,6 +2061,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); @@ -44,7 +44,7 @@ Signed-off-by: Aaradhana Sahu /* misc utils */ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, -@@ -4320,7 +4321,7 @@ void __ieee80211_subif_start_xmit(struct +@@ -4319,7 +4320,7 @@ void __ieee80211_subif_start_xmit(struct !is_multicast_ether_addr(skb->data)) { if (sta) key = rcu_dereference(sta->ptk[sta->ptk_idx]); @@ -53,7 +53,7 @@ Signed-off-by: Aaradhana Sahu rcu_read_unlock(); return; } -@@ -4366,7 +4367,7 @@ void __ieee80211_subif_start_xmit(struct +@@ -4365,7 +4366,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]); @@ -62,7 +62,7 @@ Signed-off-by: Aaradhana Sahu } else { dev_sw_netstats_tx_add(dev, 1, skb->len); ieee80211_xmit(sdata, sta, skb); -@@ -4667,7 +4668,8 @@ static bool ieee80211_tx_8023(struct iee +@@ -4663,7 +4664,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, @@ -72,7 +72,7 @@ Signed-off-by: Aaradhana Sahu { struct ieee80211_tx_info *info; struct ethhdr *ehdr = (struct ethhdr *)skb->data; -@@ -4723,6 +4725,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4719,6 +4721,7 @@ static void ieee80211_8023_xmit(struct i info = IEEE80211_SKB_CB(skb); memset(info, 0, sizeof(*info)); @@ -80,7 +80,7 @@ Signed-off-by: Aaradhana Sahu info->hw_queue = sdata->vif.hw_queue[queue]; if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && -@@ -4743,11 +4746,12 @@ static void ieee80211_8023_xmit(struct i +@@ -4739,11 +4742,12 @@ static void ieee80211_8023_xmit(struct i memcpy(IEEE80211_SKB_CB(seg), info, sizeof(*info)); } @@ -96,7 +96,7 @@ Signed-off-by: Aaradhana Sahu dev_sw_netstats_tx_add(dev, skbs, len); if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD) && sta) { -@@ -4770,7 +4774,8 @@ out_free: +@@ -4763,7 +4767,8 @@ out_free: void ieee80211_8023_xmit_ap(struct ieee80211_sub_if_data *sdata, struct net_device *dev, struct sta_info *sta, @@ -106,7 +106,7 @@ Signed-off-by: Aaradhana Sahu { struct ieee80211_tx_info *info; struct ieee80211_local *local = sdata->local; -@@ -4779,6 +4784,9 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4772,6 +4777,9 @@ void ieee80211_8023_xmit_ap(struct ieee8 unsigned long flags; int q; u16 q_map; @@ -116,7 +116,7 @@ Signed-off-by: Aaradhana Sahu /* * If the skb is shared we need to obtain our own copy. -@@ -4790,11 +4798,13 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4783,11 +4791,13 @@ void ieee80211_8023_xmit_ap(struct ieee8 info = IEEE80211_SKB_CB(skb); memset(info, 0, sizeof(*info)); @@ -133,9 +133,9 @@ Signed-off-by: Aaradhana Sahu info->flags |= IEEE80211_TX_CTL_HW_80211_ENCAP; info->control.vif = &sdata->vif; -@@ -4831,14 +4841,23 @@ void ieee80211_8023_xmit_ap(struct ieee8 - if (sta) - atomic_inc(&sta->tx_drv_pkts); +@@ -4821,14 +4831,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, @@ -158,7 +158,7 @@ Signed-off-by: Aaradhana Sahu #ifdef CPTCFG_MAC80211_NSS_SUPPORT ieee80211_xmit_nss_fixup(skb, dev); -@@ -4854,14 +4873,15 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4844,14 +4863,15 @@ netdev_tx_t ieee80211_subif_start_xmit_8 kfree_skb(skb); goto out; } @@ -176,7 +176,7 @@ Signed-off-by: Aaradhana Sahu goto skip_offload; key = rcu_dereference(sta->ptk[sta->ptk_idx]); -@@ -4872,13 +4892,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4862,13 +4882,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 goto skip_offload; if (sdata->vif.type == NL80211_IFTYPE_AP) { @@ -192,7 +192,7 @@ Signed-off-by: Aaradhana Sahu goto out; skip_offload: -@@ -6384,7 +6404,10 @@ start_xmit: +@@ -6374,7 +6394,10 @@ start_xmit: mutex_lock(&local->mtx); local_bh_disable(); diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index 61421d7d766950..7ffaf99158b90e 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -2373,7 +2373,7 @@ static void mpath_set_pinfo(struct mesh_ +@@ -2350,7 +2350,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,7 +94,7 @@ 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 -@@ -510,7 +510,7 @@ 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) { @@ -103,7 +103,7 @@ Signed-off-by: P Praneesh flush_mpath = true; } mesh_path_assign_nexthop(mpath, sta); -@@ -571,7 +571,7 @@ 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) { diff --git a/package/kernel/mac80211/patches/nss/subsys/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch b/package/kernel/mac80211/patches/nss/subsys/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch index e3c2db4cc8a713..8d8c3c68d58c91 100644 --- a/package/kernel/mac80211/patches/nss/subsys/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch +++ b/package/kernel/mac80211/patches/nss/subsys/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch @@ -19,7 +19,7 @@ Signed-off-by: Ramanathan Choodamani --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4572,6 +4572,7 @@ netdev_tx_t ieee80211_subif_start_xmit(s +@@ -4571,6 +4571,7 @@ netdev_tx_t ieee80211_subif_start_xmit(s #ifdef CPTCFG_MAC80211_NSS_SUPPORT ieee80211_xmit_nss_fixup(skb, dev); #endif @@ -27,7 +27,7 @@ Signed-off-by: Ramanathan Choodamani if (likely(!is_multicast_ether_addr(eth->h_dest))) goto normal; -@@ -4844,7 +4845,43 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4834,7 +4835,43 @@ void ieee80211_8023_xmit_ap(struct ieee8 netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, struct net_device *dev) { diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index a2a9879f25285b..6b5cf7f3e24660 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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, -@@ -3631,7 +3633,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; -@@ -3649,7 +3651,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) -@@ -3795,7 +3797,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; -@@ -4344,7 +4346,7 @@ void __ieee80211_subif_start_xmit(struct +@@ -4343,7 +4345,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,7 +67,7 @@ Signed-off-by: Tamizh Chelvam Raja if (!skb) { len = 0; goto out; -@@ -4572,7 +4574,6 @@ netdev_tx_t ieee80211_subif_start_xmit(s +@@ -4571,7 +4573,6 @@ netdev_tx_t ieee80211_subif_start_xmit(s #ifdef CPTCFG_MAC80211_NSS_SUPPORT ieee80211_xmit_nss_fixup(skb, dev); #endif @@ -75,7 +75,7 @@ Signed-off-by: Tamizh Chelvam Raja if (likely(!is_multicast_ether_addr(eth->h_dest))) goto normal; -@@ -4719,7 +4720,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4715,7 +4716,7 @@ static void ieee80211_8023_xmit(struct i } } @@ -84,7 +84,7 @@ Signed-off-by: Tamizh Chelvam Raja if (!skb) return; -@@ -4845,6 +4846,7 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4835,6 +4836,7 @@ void ieee80211_8023_xmit_ap(struct ieee8 netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, struct net_device *dev) { @@ -92,7 +92,7 @@ Signed-off-by: Tamizh Chelvam Raja 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 = {}; -@@ -4879,9 +4881,10 @@ out: +@@ -4869,9 +4871,10 @@ out: } return NETDEV_TX_OK; 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 index e25220a1b01c99..b76692a6f9500c 100644 --- 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 @@ -23,7 +23,7 @@ Signed-off-by: Yuvasree Sivasankaran --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -2727,6 +2727,9 @@ struct ieee80211_txq { +@@ -2730,6 +2730,9 @@ struct ieee80211_txq { * * @IEEE80211_HW_SUPPORTS_TID_CLASS_OFFLOAD: Hardware suports tid calssification offload. * @@ -33,7 +33,7 @@ Signed-off-by: Yuvasree Sivasankaran * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays */ enum ieee80211_hw_flags { -@@ -2787,6 +2790,7 @@ enum ieee80211_hw_flags { +@@ -2790,6 +2793,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_SUPPORTS_NSS_OFFLOAD, IEEE80211_HW_SUPPORTS_MESH_NSS_OFFLOAD, IEEE80211_HW_SUPPORTS_TID_CLASS_OFFLOAD, @@ -43,7 +43,7 @@ Signed-off-by: Yuvasree Sivasankaran NUM_IEEE80211_HW_FLAGS --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c -@@ -499,6 +499,7 @@ static const char *hw_flag_names[] = { +@@ -508,6 +508,7 @@ static const char *hw_flag_names[] = { FLAG(SUPPORTS_NSS_OFFLOAD), FLAG(SUPPORTS_MESH_NSS_OFFLOAD), FLAG(SUPPORTS_TID_CLASS_OFFLOAD), @@ -53,7 +53,7 @@ Signed-off-by: Yuvasree Sivasankaran --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -1602,6 +1602,9 @@ int ieee80211_txq_setup_flows(struct iee +@@ -1603,6 +1603,9 @@ int ieee80211_txq_setup_flows(struct iee bool supp_vht = false; enum nl80211_band band; @@ -63,7 +63,7 @@ Signed-off-by: Yuvasree Sivasankaran ret = fq_init(fq, 4096); if (ret) return ret; -@@ -1649,6 +1652,9 @@ void ieee80211_txq_teardown_flows(struct +@@ -1650,6 +1653,9 @@ void ieee80211_txq_teardown_flows(struct { struct fq *fq = &local->fq; @@ -73,7 +73,7 @@ Signed-off-by: Yuvasree Sivasankaran kfree(local->cvars); local->cvars = NULL; -@@ -1665,7 +1671,8 @@ static bool ieee80211_queue_skb(struct i +@@ -1666,7 +1672,8 @@ static bool ieee80211_queue_skb(struct i struct ieee80211_vif *vif; struct txq_info *txqi; @@ -83,7 +83,7 @@ Signed-off-by: Yuvasree Sivasankaran return false; if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) -@@ -4326,7 +4333,8 @@ void __ieee80211_subif_start_xmit(struct +@@ -4328,7 +4335,8 @@ void __ieee80211_subif_start_xmit(struct } } @@ -93,7 +93,7 @@ Signed-off-by: Yuvasree Sivasankaran ieee80211_aggr_check(sdata, sta, skb); if (sta) { -@@ -4678,8 +4686,10 @@ static void ieee80211_8023_xmit(struct i +@@ -4680,8 +4688,10 @@ static void ieee80211_8023_xmit(struct i bool multicast; u8 tid; @@ -106,7 +106,7 @@ Signed-off-by: Yuvasree Sivasankaran multicast = is_multicast_ether_addr(ra); -@@ -6414,9 +6424,12 @@ int ieee80211_tx_control_port(struct wip +@@ -6416,9 +6426,12 @@ int ieee80211_tx_control_port(struct wip } if (!IS_ERR(sta)) { @@ -123,7 +123,7 @@ Signed-off-by: Yuvasree Sivasankaran * for MLO STA, the SA should be the AP MLD address, but --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -4516,6 +4516,9 @@ static int ieee80211_get_txq_stats(struc +@@ -4525,6 +4525,9 @@ static int ieee80211_get_txq_stats(struc struct ieee80211_sub_if_data *sdata; int ret = 0; @@ -135,7 +135,7 @@ Signed-off-by: Yuvasree Sivasankaran --- a/net/mac80211/main.c +++ b/net/mac80211/main.c -@@ -841,7 +841,10 @@ struct ieee80211_hw *ieee80211_alloc_hw_ +@@ -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); @@ -185,7 +185,7 @@ Signed-off-by: Yuvasree Sivasankaran } for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { -@@ -427,7 +429,9 @@ void sta_info_free(struct ieee80211_loca +@@ -430,7 +432,9 @@ void sta_info_free(struct ieee80211_loca sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr); @@ -196,7 +196,7 @@ Signed-off-by: Yuvasree Sivasankaran kfree(rcu_dereference_raw(sta->sta.rates)); #ifdef CPTCFG_MAC80211_MESH kfree(sta->mesh); -@@ -529,8 +533,6 @@ __sta_info_alloc(struct ieee80211_sub_if +@@ -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; @@ -205,7 +205,7 @@ Signed-off-by: Yuvasree Sivasankaran int i; sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp); -@@ -604,18 +606,22 @@ __sta_info_alloc(struct ieee80211_sub_if +@@ -607,18 +609,22 @@ __sta_info_alloc(struct ieee80211_sub_if sta->last_connected = ktime_get_seconds(); @@ -237,7 +237,7 @@ Signed-off-by: Yuvasree Sivasankaran } if (sta_prepare_rate_control(local, sta, gfp)) -@@ -689,7 +695,8 @@ __sta_info_alloc(struct ieee80211_sub_if +@@ -692,7 +698,8 @@ __sta_info_alloc(struct ieee80211_sub_if return sta; free_txq: @@ -247,7 +247,7 @@ Signed-off-by: Yuvasree Sivasankaran free: sta_info_free_link(&sta->deflink); #ifdef CPTCFG_MAC80211_MESH -@@ -1684,11 +1691,13 @@ void ieee80211_sta_ps_deliver_wakeup(str +@@ -1687,11 +1694,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); @@ -265,7 +265,7 @@ Signed-off-by: Yuvasree Sivasankaran } skb_queue_head_init(&pending); -@@ -2103,6 +2112,9 @@ ieee80211_sta_ps_deliver_response(struct +@@ -2106,6 +2115,9 @@ ieee80211_sta_ps_deliver_response(struct * TIM recalculation. */ @@ -275,7 +275,7 @@ Signed-off-by: Yuvasree Sivasankaran for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) { if (!sta->sta.txq[tid] || !(driver_release_tids & BIT(tid)) || -@@ -2519,7 +2531,7 @@ static void sta_set_tidstats(struct sta_ +@@ -2521,7 +2533,7 @@ static void sta_set_tidstats(struct sta_ tidstats->tx_msdu_failed = sta->deflink.status_stats.msdu_failed[tid]; } @@ -284,7 +284,7 @@ Signed-off-by: Yuvasree Sivasankaran spin_lock_bh(&local->fq.lock); rcu_read_lock(); -@@ -2847,6 +2859,9 @@ unsigned long ieee80211_sta_last_active( +@@ -2849,6 +2861,9 @@ unsigned long ieee80211_sta_last_active( static void sta_update_codel_params(struct sta_info *sta, u32 thr) { diff --git a/package/kernel/mac80211/patches/nss/subsys/829-mac80211-fix-mesh-ping-issue.patch b/package/kernel/mac80211/patches/nss/subsys/829-mac80211-fix-mesh-ping-issue.patch index c19d97a818ba17..642901bed17459 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -4649,16 +4649,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; } -@@ -4881,10 +4879,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 -@@ -4934,37 +4929,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))) -@@ -5002,30 +4966,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/nss/subsys/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 index ea76cd96327e46..e3d8db5815fe88 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 @@ -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; From a82be37a4824e2f4658f100f1753642bfbc84258 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 9 Mar 2024 11:15:21 -0500 Subject: [PATCH 210/225] ath11k_nss: Set correct pbufs for 1GB profile --- package/kernel/mac80211/files/qca-nss-pbuf.init | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/kernel/mac80211/files/qca-nss-pbuf.init b/package/kernel/mac80211/files/qca-nss-pbuf.init index f4f45b9a4a4c60..c6d6b8b2238074 100755 --- a/package/kernel/mac80211/files/qca-nss-pbuf.init +++ b/package/kernel/mac80211/files/qca-nss-pbuf.init @@ -105,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 | \ @@ -115,12 +115,12 @@ 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 } From 318079e475a9a0447507b2e38722b6c09885b8a7 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 9 Mar 2024 11:17:51 -0500 Subject: [PATCH 211/225] qualcommax: remove uneeded btcoex dts not needed for NSS offload and helps save some memory --- .../patches-6.6/9999-add-btcoex-dts.patch | 30 ------------------- 1 file changed, 30 deletions(-) delete mode 100644 target/linux/qualcommax/patches-6.6/9999-add-btcoex-dts.patch diff --git a/target/linux/qualcommax/patches-6.6/9999-add-btcoex-dts.patch b/target/linux/qualcommax/patches-6.6/9999-add-btcoex-dts.patch deleted file mode 100644 index 83825b782c1b7f..00000000000000 --- a/target/linux/qualcommax/patches-6.6/9999-add-btcoex-dts.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- linux-6.1.71/arch/arm64/boot/dts/qcom/ipq8074.dtsi 2024-01-07 01:44:56.908138962 -0500 -+++ linux-6.1.71/arch/arm64/boot/dts/qcom/ipq8074.dtsi 2024-01-07 01:44:58.908138962 -0500 -@@ -1170,7 +1170,14 @@ - wifi: wifi@c0000000 { - compatible = "qcom,ipq8074-wifi"; - reg = <0xc000000 0x2000000>; -- -+ qcom,hw-mode-id = <1>; -+ #ifdef __IPQ_MEM_PROFILE_256_MB__ -+ qcom,tgt-mem-mode = <2>; -+ #elif __IPQ_MEM_PROFILE_512_MB__ -+ qcom,tgt-mem-mode = <1>; -+ #else -+ qcom,tgt-mem-mode = <0>; -+ #endif - interrupts = , - , - , -@@ -1276,6 +1283,12 @@ - "tcl2host-status-ring"; - qcom,rproc = <&q6v5_wcss>; - status = "disabled"; -+ qcom,pta-num = <0>; -+ qcom,coex-mode = <0x2>; -+ qcom,bt-active-time = <0x12>; -+ qcom,bt-priority-time = <0x0c>; -+ qcom,coex-algo = <0x2>; -+ qcom,pta-priority = <0x80800505>; - }; - }; From 1becd2cd0d25e806530be961cbe3bc0d4ed5f402 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 9 Mar 2024 11:31:54 -0500 Subject: [PATCH 212/225] ath11k_nss: Revert setting fw_mem_mode for IPQ807x Leave it set to '0', as it will kernel panic with 2K skb patch. This flag was incorrectly assumed to save memory on 1G platforms. ath11k_nss: remove leftover max_tx_ring it was not removed when applying patch to replace it with 'max_tx_ring = DP_TCL_NUM_RING_MAX +1' ath11k_nss: Import bugfix patches ath11k_nss: Experimental build for IPQ6018 This will require setting the correct `ATH11K_MEM_PROFILE_XXX` for your platform. Setting it to value lower/higher than physically available will cause NULL virtual address kernel panics. I believe this setting was not originally meant to reduce memory footprint of 1G+ platforms, but to account for platforms that were 512M or less. Will require tweaking to allow for the old behvaior on 1G+ IPQ807x, while still saving memory for platforms <= 512M. --- ...207-ath11k-Enable-256_512MB-profiles.patch | 41 +- ...11k-Disable-rx_header-tlv-for-2K-SKB.patch | 1016 +++++++++++++++++ ...pport-for-WDS-offload-in-NSS-offload.patch | 24 +- ...-dynamic-VLAN-support-in-NSS-offload.patch | 16 +- ...ow-fast-rx-by-bypassing-stats-update.patch | 4 +- ...ow-fast-rx-by-bypassing-stats-update.patch | 46 +- .../nss/ath11k/244-ath11k-dp-tx-perf.patch | 26 +- .../300-ath11k-nss-mesh-offload-support.patch | 20 +- ...lookup-failure-in-mgmt-tx-completion.patch | 2 +- ...e-free-of-peer-rx_tid-during-reo-cmd.patch | 2 +- ...TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch | 2 +- ...ing-rx-stats-with-monitor-vif-enable.patch | 8 +- ...1k-skip-status-ring-entry-processing.patch | 8 +- ...356-ath11k-invalid-desc-sanity-check.patch | 6 +- ...-fix-tkip-encryption-traffic-failure.patch | 2 +- ...Fix-ppdu_id-from-firmware-PPDU-stats.patch | 8 +- ...Add-retry-mechanism-for-update_rx_qu.patch | 18 +- ...ix-mutex-dead-lock-and-q6-dump-crash.patch | 59 + ...agement-frames-to-firmware-before-wa.patch | 43 + ...th11k-Advertise-TX_QUEUE-mac-hw-flag.patch | 2 +- ...oid-memset-of-ppdu-info-for-next-skb.patch | 6 +- ...a_map_single-to-virt_to_phys-in-rx-r.patch | 66 ++ ...11k-remove-invalid-peer-create-logic.patch | 4 +- ...th11k-rename-ath11k_start_vdev_delay.patch | 2 +- ...ation-of-ath11k_mac_start_vdev_delay.patch | 2 +- ...ailure-due-to-unexpected-peer-delete.patch | 16 +- ...k-make-debugfs-sta-htt-stats-modular.patch | 8 +- .../999-336-0002-ath11k-Use-idr_replace.patch | 264 +++++ 28 files changed, 1601 insertions(+), 120 deletions(-) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/401-ath11k-Fix-mutex-dead-lock-and-q6-dump-crash.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/453-ath11k-flush-management-frames-to-firmware-before-wa.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/669-ath11k-change-dma_map_single-to-virt_to_phys-in-rx-r.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/999-336-0002-ath11k-Use-idr_replace.patch diff --git a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch index d89b500015fc33..75e0bf1b79b844 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch @@ -228,15 +228,6 @@ Signed-off-by: Ramya Gnanasekar static struct ath11k_hw_params ath11k_hw_params[] = { { .hw_rev = ATH11K_HW_IPQ8074, -@@ -95,7 +97,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, @@ -127,6 +129,7 @@ static struct ath11k_hw_params ath11k_hw .tcl_ring_retry = true, .tx_ring_size = DP_TCL_DATA_RING_SIZE, @@ -254,7 +245,15 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = false, -@@ -259,7 +262,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -210,6 +213,7 @@ 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, + }, + { + .name = "qca6390 hw2.0", +@@ -259,7 +263,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -263,7 +262,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -426,7 +429,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -426,7 +430,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -272,7 +271,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -462,6 +465,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -462,6 +466,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, @@ -280,7 +279,7 @@ Signed-off-by: Ramya Gnanasekar }, { .name = "wcn6855 hw2.1", -@@ -509,7 +513,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -509,7 +514,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -289,7 +288,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -545,6 +549,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -545,6 +550,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, @@ -297,7 +296,7 @@ Signed-off-by: Ramya Gnanasekar }, { .name = "wcn6750 hw1.0", -@@ -593,7 +598,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -593,7 +599,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = true, .coldboot_cal_ftm = true, .cbcal_restart_fw = false, @@ -306,7 +305,15 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = false, -@@ -672,7 +677,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -626,6 +632,7 @@ static struct ath11k_hw_params ath11k_hw + .tx_ring_size = DP_TCL_DATA_RING_SIZE_WCN6750, + .smp2p_wow_exit = true, + .support_fw_mac_sequence = true, ++ .num_vdevs_peers = ath11k_vdevs_peers, + }, + { + .hw_rev = ATH11K_HW_IPQ5018_HW10, +@@ -672,7 +679,7 @@ static struct ath11k_hw_params ath11k_hw .supports_monitor = false, .supports_sta_ps = false, .supports_shadow_regs = false, @@ -315,7 +322,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_regdb = false, -@@ -707,6 +712,22 @@ static struct ath11k_hw_params ath11k_hw +@@ -707,6 +714,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, diff --git a/package/kernel/mac80211/patches/nss/ath11k/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch b/package/kernel/mac80211/patches/nss/ath11k/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch new file mode 100644 index 00000000000000..7b7673953bd4fe --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch @@ -0,0 +1,1016 @@ +From 30f54666ae15128f26fbad787a35253885a10513 Mon Sep 17 00:00:00 2001 +From: Ramya Gnanasekar +Date: Fri, 25 Dec 2020 16:11:06 +0530 +Subject: [PATCH] ath11k: Disable rx_header tlv for 2K SKB + +On low memory platform hdr_status in hal_rx_desc is not subscribed to +get a savings of 128bytes in skb. This is required to reduce the skb +size from 4K to 2K. Use HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG message +to unsubscribe rx_pkt_header tlv for rxdma ring. + +Signed-off-by: Ramya Gnanasekar + +--- a/drivers/net/wireless/ath/ath11k/debugfs.c ++++ b/drivers/net/wireless/ath/ath11k/debugfs.c +@@ -668,6 +668,7 @@ static ssize_t ath11k_write_extd_rx_stat + } + + ar->debug.rx_filter = tlv_filter.rx_filter; ++ tlv_filter.offset_valid = false; + + 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; +@@ -1129,6 +1130,7 @@ static ssize_t ath11k_write_pktlog_filte + } + + /* Clear rx filter set for monitor mode and rx status */ ++ tlv_filter.offset_valid = false; + 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, 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 { + #define DP_REO_CMD_RING_SIZE 256 + #define DP_REO_STATUS_RING_SIZE 2048 + #define DP_RXDMA_BUF_RING_SIZE 4096 +-#define DP_RXDMA_REFILL_RING_SIZE 2048 ++#define DP_RXDMA_REFILL_RING_SIZE ATH11K_DP_RXDMA_REFILL_RING_SIZE ++#define DP_RXDMA_NSS_REFILL_RING_SIZE ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE + #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 +@@ -648,7 +649,7 @@ enum htt_stats_internal_ppdu_frametype { + * + * |31 26|25|24|23 16|15 8|7 0| + * |-----------------+----------------+----------------+---------------| +- * | rsvd1 |PS|SS| ring_id | pdev_id | msg_type | ++ * | rsvd1|OV|PS|SS| ring_id | pdev_id | msg_type | + * |-------------------------------------------------------------------| + * | rsvd2 | ring_buffer_size | + * |-------------------------------------------------------------------| +@@ -662,6 +663,14 @@ enum htt_stats_internal_ppdu_frametype { + * |-------------------------------------------------------------------| + * | tlv_filter_in_flags | + * |-------------------------------------------------------------------| ++ * | rx_header_offset | rx_packet_offset | ++ * |-------------------------------------------------------------------| ++ * | rx_mpdu_start_offset | rx_mpdu_end_offset | ++ * |-------------------------------------------------------------------| ++ * | rx_msdu_start_offset | rx_msdu_end_offset | ++ * |-------------------------------------------------------------------| ++ * | rsvd3 | rx_attention_offset | ++ * |-------------------------------------------------------------------| + * Where: + * PS = pkt_swap + * SS = status_swap +@@ -675,7 +684,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'27:31 - rsvd1: reserved for future use + * dword1 - b'0:16 - ring_buffer_size: size of buffers referenced by rx ring, + * in byte units. + * Valid only for HW_TO_SW_RING and SW_TO_HW_RING +@@ -704,6 +716,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 ++ * dword7 - b'0:15 - rx_packet_offset: rx_packet_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_1 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * - b'16:31 - rx_header_offset: rx_header_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_1 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * dword8 - b'0:15 - rx_mpdu_end_offset: rx_mpdu_end_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_2 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * - b'16:31 - rx_mpdu_start_offset: rx_mpdu_start_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_2 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * dword9 - b'0:15 - rx_msdu_end_offset: rx_msdu_end_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_3 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * - b'16:31 - rx_msdu_start_offset: rx_msdu_start_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_3 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * dword10- b'0:15 - rx_attention_offset: rx_attention_offset in byte units ++ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING ++ * A value of 0 will be considered as ignore this config. ++ * Refer to BUF_RING_CFG_4 defs within HW .h files, ++ * e.g. wmac_top_reg_seq_hwioreg.h ++ * - b'16:31 - rsvd3 for future use + */ + + #define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) +@@ -711,8 +759,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) ++#define HTT_RX_RING_SELECTION_CFG_CMD_OFFSET_VALID BIT(26) + + #define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE GENMASK(15, 0) ++#define HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET GENMASK(15, 0) ++#define HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET GENMASK(31, 16) ++#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET GENMASK(15, 0) ++#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET GENMASK(31, 16) ++#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET GENMASK(15, 0) ++#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET GENMASK(31, 16) ++#define HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET GENMASK(15, 0) + + enum htt_rx_filter_tlv_flags { + HTT_RX_FILTER_TLV_FLAGS_MPDU_START = BIT(0), +@@ -1016,6 +1072,14 @@ enum htt_rx_data_pkt_filter_tlv_flasg3 { + HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER | \ + HTT_RX_FILTER_TLV_FLAGS_ATTENTION) + ++#define HTT_RX_RXDMA_FILTER_TLV_FLAGS_BUF_RING \ ++ (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ ++ HTT_RX_FILTER_TLV_FLAGS_MSDU_START | \ ++ HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \ ++ HTT_RX_FILTER_TLV_FLAGS_MSDU_END | \ ++ HTT_RX_FILTER_TLV_FLAGS_MPDU_END | \ ++ HTT_RX_FILTER_TLV_FLAGS_ATTENTION) ++ + struct htt_rx_ring_selection_cfg_cmd { + u32 info0; + u32 info1; +@@ -1024,6 +1088,10 @@ struct htt_rx_ring_selection_cfg_cmd { + u32 pkt_type_en_flags2; + u32 pkt_type_en_flags3; + u32 rx_filter_tlv; ++ u32 rx_packet_offset; ++ u32 rx_mpdu_offset; ++ u32 rx_msdu_offset; ++ u32 rx_attn_offset; + } __packed; + + struct htt_rx_ring_tlv_filter { +@@ -1032,6 +1100,14 @@ struct htt_rx_ring_tlv_filter { + u32 pkt_filter_flags1; /* MGMT */ + u32 pkt_filter_flags2; /* CTRL */ + u32 pkt_filter_flags3; /* DATA */ ++ bool offset_valid; ++ u16 rx_packet_offset; ++ u16 rx_header_offset; ++ u16 rx_mpdu_end_offset; ++ u16 rx_mpdu_start_offset; ++ u16 rx_msdu_end_offset; ++ u16 rx_msdu_start_offset; ++ u16 rx_attn_offset; + }; + + #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 + return ab->hw_params.hw_ops->rx_desc_get_mpdu_fc_valid(desc); + } + ++static u16 ath11k_dp_rxdesc_get_mpdu_frame_ctrl(struct ath11k_base *ab, ++ struct hal_rx_desc *desc) ++{ ++ return ab->hw_params.hw_ops->rx_desc_get_mpdu_frame_ctl(desc); ++} ++ + 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 + return ab->hw_params.hw_ops->rx_desc_mpdu_start_addr2(desc); + } + ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M ++static void ath11k_dp_get_rx_header_offset(struct ath11k_base *ab, ++ struct htt_rx_ring_tlv_filter *tlv_filter) ++{ ++ ab->hw_params.hw_ops->rx_desc_get_offset(tlv_filter); ++} ++#endif ++ ++static bool ath11k_dp_rx_desc_dot11_hdr_fields_valid(struct ath11k_base *ab, ++ struct hal_rx_desc *desc) ++{ ++ return ab->hw_params.hw_ops->rx_desc_dot11_hdr_fields_valid(desc); ++} ++ ++static void ath11k_dp_rx_desc_get_dot11_hdr(struct ath11k_base *ab, ++ struct hal_rx_desc *desc, ++ struct ieee80211_hdr *hdr) ++{ ++ ab->hw_params.hw_ops->rx_desc_get_dot11_hdr(desc, hdr); ++} ++ ++static void ath11k_dp_rx_desc_get_crypto_header(struct ath11k_base *ab, ++ struct hal_rx_desc *desc, ++ u8 *crypto_hdr, ++ enum hal_encrypt_type enctype) ++{ ++ ab->hw_params.hw_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); ++} ++ + static void ath11k_dp_service_mon_ring(struct timer_list *t) + { + struct ath11k_base *ab = from_timer(ab, t, mon_reap_timer); +@@ -2134,6 +2169,49 @@ int ath11k_dp_rx_crypto_icv_len(struct a + return 0; + } + ++static void ath11k_get_dot11_hdr_from_rx_desc(struct ath11k *ar, ++ struct sk_buff *msdu, ++ struct ath11k_skb_rxcb *rxcb, ++ struct ieee80211_rx_status *status, ++ enum hal_encrypt_type enctype) ++{ ++ struct hal_rx_desc *rx_desc = rxcb->rx_desc; ++ struct ath11k_base *ab = ar->ab; ++ size_t hdr_len, crypto_len; ++ struct ieee80211_hdr *hdr; ++ u16 fc, qos_ctl = 0; ++ u8 *crypto_hdr; ++ ++ if (!(status->flag & RX_FLAG_IV_STRIPPED)) { ++ crypto_len = ath11k_dp_rx_crypto_param_len(ar, enctype); ++ crypto_hdr = skb_push(msdu, crypto_len); ++ ath11k_dp_rx_desc_get_crypto_header(ab, rx_desc, crypto_hdr, enctype); ++ } ++ ++ fc = ath11k_dp_rxdesc_get_mpdu_frame_ctrl(ab, rx_desc); ++ hdr_len = ieee80211_hdrlen(fc); ++ skb_push(msdu, hdr_len); ++ hdr = (struct ieee80211_hdr *)msdu->data; ++ hdr->frame_control = fc; ++ ++ /* Get wifi header from rx_desc */ ++ ath11k_dp_rx_desc_get_dot11_hdr(ab, rx_desc, hdr); ++ ++ if (rxcb->is_mcbc) ++ status->flag &= ~RX_FLAG_PN_VALIDATED; ++ ++ /* Add QOS header */ ++ if (ieee80211_is_data_qos(hdr->frame_control)) { ++ qos_ctl = rxcb->tid; ++ if (ath11k_dp_rx_h_msdu_start_mesh_ctl_present(ab, rx_desc)) ++ qos_ctl |= IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT; ++ ++ /* TODO Add other QoS ctl fields when required */ ++ memcpy(msdu->data + (hdr_len - IEEE80211_QOS_CTL_LEN), ++ &qos_ctl, IEEE80211_QOS_CTL_LEN); ++ } ++} ++ + static void ath11k_dp_rx_h_undecap_nwifi(struct ath11k *ar, + struct sk_buff *msdu, + u8 *first_hdr, +@@ -2147,7 +2225,8 @@ static void ath11k_dp_rx_h_undecap_nwifi + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + u16 qos_ctl = 0; +- u8 *qos; ++ u8 *qos, *crypto_hdr; ++ bool add_qos_ctrl = false; + + /* copy SA & DA and pull decapped header */ + hdr = (struct ieee80211_hdr *)msdu->data; +@@ -2156,7 +2235,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)); + +- if (rxcb->is_first_msdu) { ++ if (rxcb->is_first_msdu && first_hdr) { + /* original 802.11 header is valid for the first msdu + * hence we can reuse the same header + */ +@@ -2186,16 +2265,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); ++ add_qos_ctrl = true; + } + + 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)); ++ if (first_hdr) { ++ memcpy(skb_push(msdu, ++ ath11k_dp_rx_crypto_param_len(ar, enctype)), ++ (void *)hdr + hdr_len, ++ ath11k_dp_rx_crypto_param_len(ar, enctype)); ++ } else { ++ crypto_hdr = skb_push(msdu, ath11k_dp_rx_crypto_param_len(ar, enctype)); ++ ath11k_dp_rx_desc_get_crypto_header(ar->ab, ++ rxcb->rx_desc, crypto_hdr, enctype); ++ } + } + +- if (!rxcb->is_first_msdu) { ++ if (!rxcb->is_first_msdu || add_qos_ctrl) { + memcpy(skb_push(msdu, + IEEE80211_QOS_CTL_LEN), &qos_ctl, + IEEE80211_QOS_CTL_LEN); +@@ -2311,6 +2397,20 @@ static void ath11k_dp_rx_h_undecap_eth(s + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + void *rfc1042; ++ struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); ++ struct ath11k_dp_rfc1042_hdr rfc = {0xaa, 0xaa, 0x03, {0x00, 0x00, 0x00}}; ++ ++ if (!first_hdr) { ++ eth = (struct ethhdr *)msdu->data; ++ ether_addr_copy(da, eth->h_dest); ++ ether_addr_copy(sa, eth->h_source); ++ rfc.snap_type = eth->h_proto; ++ skb_pull(msdu, sizeof(struct ethhdr)); ++ 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); ++ goto exit; ++ } + + rfc1042 = ath11k_dp_rx_h_find_rfc1042(ar, msdu, enctype); + if (WARN_ON_ONCE(!rfc1042)) +@@ -2339,6 +2439,7 @@ static void ath11k_dp_rx_h_undecap_eth(s + + memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); + ++exit: + /* original 802.11 header has a different DA and in + * case of 4addr it may also have different SA + */ +@@ -2357,6 +2458,7 @@ static void ath11k_dp_rx_h_undecap_snap( + size_t hdr_len; + u8 l3_pad_bytes; + struct hal_rx_desc *rx_desc; ++ struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); + + /* Delivered decapped frame: + * [amsdu header] <-- replaced with 802.11 hdr +@@ -2370,6 +2472,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); + ++ if (!first_hdr) { ++ ath11k_get_dot11_hdr_from_rx_desc(ar, msdu, rxcb, status, enctype); ++ return; ++ } ++ + hdr = (struct ieee80211_hdr *)first_hdr; + hdr_len = ieee80211_hdrlen(hdr->frame_control); + +@@ -2766,6 +2873,20 @@ static int ath11k_dp_rx_process_msdu(str + goto free_out; + } + ++ hdr_status = ath11k_dp_rx_h_80211_hdr(ab, rx_desc); ++ /* wifi hdr fields validation for 512M:: ++ * Mcast packets in ethernet frame mode ++ * will need wifi hdr in msdu to validate PN. ++ * Header will be added in undecap routine. ++ * Validation on wifi hdr fields from rx_desc. ++ */ ++ if (!hdr_status && ath11k_dp_rx_h_attn_is_mcbc(ab, rx_desc) && ++ !ath11k_dp_rx_desc_dot11_hdr_fields_valid(ab, rx_desc)) { ++ ath11k_warn(ab, "One or more invalid dot11 header fields\n"); ++ ret = -EIO; ++ goto free_out; ++ } ++ + rxcb = ATH11K_SKB_RXCB(msdu); + rxcb->rx_desc = rx_desc; + msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(ab, rx_desc); +@@ -2778,8 +2899,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); +- ath11k_dbg_dump(ab, ATH11K_DBG_DATA, NULL, "", hdr_status, +- sizeof(struct ieee80211_hdr)); ++ if (hdr_status) ++ ath11k_dbg_dump(ab, ATH11K_DBG_DATA, NULL, "", hdr_status, ++ sizeof(struct ieee80211_hdr)); + ath11k_dbg_dump(ab, ATH11K_DBG_DATA, NULL, "", rx_desc, + sizeof(struct hal_rx_desc)); + goto free_out; +@@ -3649,6 +3771,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); ++ + head_len = hdr_len + hal_rx_desc_sz + IEEE80211_TKIP_IV_LEN; + tail_len = IEEE80211_CCMP_MIC_LEN + IEEE80211_TKIP_ICV_LEN + FCS_LEN; + +@@ -3929,8 +4052,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) + { +- struct ieee80211_hdr *hdr; + u64 pn = 0; ++ struct ieee80211_hdr *hdr; + u8 *ehdr; + u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; + +@@ -4160,8 +4283,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); +- ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", hdr_status, +- sizeof(struct ieee80211_hdr)); ++ if (hdr_status) ++ ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", hdr_status, ++ sizeof(struct ieee80211_hdr)); + ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", rx_desc, + sizeof(struct hal_rx_desc)); + dev_kfree_skb_any(msdu); +@@ -4784,6 +4908,47 @@ void ath11k_dp_rx_pdev_free(struct ath11 + ath11k_dp_rxdma_pdev_buf_free(ar); + } + ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M ++static int ath11k_dp_rxdma_ring_sel_config(struct ath11k *ar) ++{ ++ struct ath11k_pdev_dp *dp = &ar->dp; ++ struct htt_rx_ring_tlv_filter tlv_filter = {0}; ++ u32 ring_id; ++ int ret; ++ u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; ++ ++ ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id; ++ ++ tlv_filter.rx_filter = HTT_RX_RXDMA_FILTER_TLV_FLAGS_BUF_RING; ++ tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR; ++ tlv_filter.pkt_filter_flags3 = HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST | ++ HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST; ++ tlv_filter.offset_valid = true; ++ tlv_filter.rx_packet_offset = hal_rx_desc_sz; ++ tlv_filter.rx_header_offset = 0; ++ ++ ath11k_dp_get_rx_header_offset(ar->ab, &tlv_filter); ++ ++ if (!ar->ab->nss.enabled) ++ ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, dp->mac_id, ++ HAL_RXDMA_BUF, ++ DP_RXDMA_REFILL_RING_SIZE, ++ &tlv_filter); ++ else ++ ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, dp->mac_id, ++ HAL_RXDMA_BUF, ++ DP_RXDMA_NSS_REFILL_RING_SIZE, ++ &tlv_filter); ++ ++ return ret; ++} ++#else ++static int ath11k_dp_rxdma_ring_sel_config(struct ath11k *ar) ++{ ++ return 0; ++} ++#endif ++ + int ath11k_dp_rx_pdev_alloc(struct ath11k_base *ab, int mac_id) + { + struct ath11k *ar = ab->pdevs[mac_id].ar; +@@ -4877,6 +5042,12 @@ config_refill_ring: + } + } + ++ ret = ath11k_dp_rxdma_ring_sel_config(ar); ++ if (ret) { ++ ath11k_warn(ab, "failed to setup rxdma ring selection config\n"); ++ return ret; ++ } ++ + return 0; + } + +--- a/drivers/net/wireless/ath/ath11k/dp_tx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_tx.c +@@ -1183,6 +1183,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)); ++ cmd->info0 |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_OFFSET_VALID, ++ tlv_filter->offset_valid); + + cmd->info1 = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE, + rx_buf_size); +@@ -1192,6 +1194,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; + ++ if (tlv_filter->offset_valid) { ++ cmd->rx_packet_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET, ++ tlv_filter->rx_packet_offset); ++ cmd->rx_packet_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET, ++ tlv_filter->rx_header_offset); ++ ++ cmd->rx_mpdu_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET, ++ tlv_filter->rx_mpdu_end_offset); ++ cmd->rx_mpdu_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET, ++ tlv_filter->rx_mpdu_start_offset); ++ ++ cmd->rx_msdu_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET, ++ tlv_filter->rx_msdu_end_offset); ++ cmd->rx_msdu_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET, ++ tlv_filter->rx_msdu_start_offset); ++ ++ cmd->rx_attn_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET, ++ tlv_filter->rx_attn_offset); ++ } ++ + ret = ath11k_htc_send(&ab->htc, ab->dp.eid, skb); + if (ret) + goto err_free; +@@ -1270,6 +1292,7 @@ int ath11k_dp_tx_htt_monitor_mode_ring_c + } + + ring_id = dp->rxdma_mon_buf_ring.refill_buf_ring.ring_id; ++ tlv_filter.offset_valid = false; + + if (!reset) { + tlv_filter.rx_filter = HTT_RX_MON_FILTER_TLV_FLAGS_MON_BUF_RING; +--- a/drivers/net/wireless/ath/ath11k/hw.c ++++ b/drivers/net/wireless/ath/ath11k/hw.c +@@ -260,7 +260,11 @@ static u8 ath11k_hw_ipq8074_rx_desc_get_ + + static u8 *ath11k_hw_ipq8074_rx_desc_get_hdr_status(struct hal_rx_desc *desc) + { ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + return desc->u.ipq8074.hdr_status; ++#else ++ return NULL; ++#endif + } + + 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 + desc->u.ipq8074.msdu_start.info1 = __cpu_to_le32(info); + } + ++static ++struct rx_attention *ath11k_hw_ipq8074_rx_desc_get_attention(struct hal_rx_desc *desc) ++{ ++ return &desc->u.ipq8074.attention; ++} ++ ++static u8 *ath11k_hw_ipq8074_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) ++{ ++ return &desc->u.ipq8074.msdu_payload[0]; ++} ++ ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M ++static void ath11k_hw_ipq8074_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_ipq8074, mpdu_end_tag)); ++ tlv_filter->rx_mpdu_start_offset = __le16_to_cpu(offsetof ++ (struct hal_rx_desc_ipq8074, mpdu_start_tag)); ++ tlv_filter->rx_msdu_end_offset = __le16_to_cpu(offsetof ++ (struct hal_rx_desc_ipq8074, msdu_end_tag)); ++ tlv_filter->rx_msdu_start_offset = __le16_to_cpu(offsetof ++ (struct hal_rx_desc_ipq8074, msdu_start_tag)); ++ tlv_filter->rx_attn_offset = __le16_to_cpu(offsetof ++ (struct hal_rx_desc_ipq8074, rx_attn_tag)); ++} ++#endif ++ ++static u16 ath11k_hw_ipq8074_rx_desc_get_mpdu_frame_ctl(struct hal_rx_desc *desc) ++{ ++ return __le16_to_cpu(desc->u.ipq8074.mpdu_start.frame_ctrl); ++} ++ + static bool ath11k_hw_ipq8074_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) + { + return __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & + RX_MPDU_START_INFO1_MAC_ADDR2_VALID; + } + +-static u8 *ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) ++static u8* ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) + { + return desc->u.ipq8074.mpdu_start.addr2; + } + +-static +-struct rx_attention *ath11k_hw_ipq8074_rx_desc_get_attention(struct hal_rx_desc *desc) ++static bool ath11k_hw_ipq8074_rx_desc_dot11_hdr_fields_valid(struct hal_rx_desc *desc) + { +- return &desc->u.ipq8074.attention; ++ if ((ath11k_hw_ipq8074_rx_desc_get_mpdu_seq_ctl_vld(desc) && ++ ath11k_hw_ipq8074_rx_desc_get_mpdu_fc_valid(desc) && ++ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & ++ RX_MPDU_START_INFO1_MAC_ADDR1_VALID && ++ ath11k_hw_ipq8074_rx_desc_mac_addr2_valid(desc) && ++ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & ++ RX_MPDU_START_INFO1_MAC_ADDR3_VALID && ++ FIELD_GET((RX_MPDU_START_INFO1_MPDU_DUR_VALID), ++ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1)))) { ++ return true; ++ } ++ return false; ++} ++ ++static void ath11k_hw_ipq8074_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, ++ struct ieee80211_hdr *hdr) ++{ ++ hdr->frame_control = __le16_to_cpu(desc->u.ipq8074.mpdu_start.frame_ctrl); ++ hdr->duration_id = __le16_to_cpu(desc->u.ipq8074.mpdu_start.duration); ++ ether_addr_copy(hdr->addr1, desc->u.ipq8074.mpdu_start.addr1); ++ ether_addr_copy(hdr->addr2, desc->u.ipq8074.mpdu_start.addr2); ++ ether_addr_copy(hdr->addr3, desc->u.ipq8074.mpdu_start.addr3); ++ if (__le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & ++ RX_MPDU_START_INFO1_MAC_ADDR4_VALID) { ++ ether_addr_copy(hdr->addr4, desc->u.ipq8074.mpdu_start.addr4); ++ } ++ hdr->seq_ctrl = __le16_to_cpu(desc->u.ipq8074.mpdu_start.seq_ctrl); ++} ++ ++static void ath11k_hw_ipq8074_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.ipq8074.mpdu_start.pn[0]); ++ crypto_hdr[1] = 0; ++ crypto_hdr[2] = ++ HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.ipq8074.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.ipq8074.mpdu_start.pn[0]); ++ crypto_hdr[1] = ++ HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.ipq8074.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_INFO5_KEY_ID, ++ __le32_to_cpu(desc->u.ipq8074.mpdu_start.info5)); ++ crypto_hdr[3] = 0x20 | (key_id << 6); ++ crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.ipq8074.mpdu_start.pn[0]); ++ crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.ipq8074.mpdu_start.pn[0]); ++ crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.ipq8074.mpdu_start.pn[1]); ++ crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.ipq8074.mpdu_start.pn[1]); + } + +-static u8 *ath11k_hw_ipq8074_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) ++static bool ath11k_hw_qcn9074_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) + { +- return &desc->u.ipq8074.msdu_payload[0]; ++ return __le32_to_cpu(desc->u.qcn9074.mpdu_start.info11) & ++ RX_MPDU_START_INFO11_MAC_ADDR2_VALID; ++} ++ ++static u8* ath11k_hw_qcn9074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) ++{ ++ return desc->u.qcn9074.mpdu_start.addr2; + } + + 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_ + + static u8 *ath11k_hw_qcn9074_rx_desc_get_hdr_status(struct hal_rx_desc *desc) + { ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + return desc->u.qcn9074.hdr_status; ++#else ++ return NULL; ++#endif + } + + 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_ + + static u8 *ath11k_hw_wcn6855_rx_desc_get_hdr_status(struct hal_rx_desc *desc) + { ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + return desc->u.wcn6855.hdr_status; ++#else ++ return NULL; ++#endif + } + + static bool ath11k_hw_wcn6855_rx_desc_encrypt_valid(struct hal_rx_desc *desc) +@@ -929,6 +1047,98 @@ static u32 ath11k_hw_qcn9074_rx_desc_get + return FIELD_GET(HAL_RX_MPDU_INFO_INFO1_MPDU_LEN, + __le32_to_cpu(mpdu_info->u.qcn9074.info1)); + } ++ ++#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]); ++} ++ + 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, +@@ -1009,6 +1219,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 = { +@@ -1050,6 +1267,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 = { +@@ -1132,6 +1356,13 @@ 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, ++#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 wcn6750_ops = { +@@ -1180,6 +1411,8 @@ const struct ath11k_hw_ops ipq5018_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, +@@ -1214,6 +1447,13 @@ const struct ath11k_hw_ops ipq5018_ops = + .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, ++#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, + }; + + #define ATH11K_TX_RING_MASK_0 BIT(0) +--- a/drivers/net/wireless/ath/ath11k/hw.h ++++ b/drivers/net/wireless/ath/ath11k/hw.h +@@ -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 + #else + /* Num VDEVS per radio */ + #define TARGET_NUM_VDEVS(ab) (ab->hw_params.num_vdevs_peers[ab->qmi.target_mem_mode].num_vdevs) +@@ -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 ++#define ATH11K_DP_RXDMA_REFILL_RING_SIZE 2048 ++#define ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE 2048 + #endif + + /* Num of peers for Single Radio mode */ +@@ -128,6 +135,8 @@ 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]; +@@ -285,7 +294,17 @@ 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); ++ 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 ++ u16 (*rx_desc_get_mpdu_frame_ctl)(struct hal_rx_desc *desc); ++ bool (*rx_desc_dot11_hdr_fields_valid)(struct hal_rx_desc *desc); ++ void (*rx_desc_get_dot11_hdr)(struct hal_rx_desc *desc, ++ struct ieee80211_hdr *hdr); ++ void (*rx_desc_get_crypto_header)(struct hal_rx_desc *desc, ++ u8 *crypto_hdr, ++ enum hal_encrypt_type enctype); + }; + + extern const struct ath11k_hw_ops ipq8074_ops; +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -6343,6 +6343,7 @@ static int ath11k_mac_config_mon_status_ + tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar); + } + ++ tlv_filter.offset_valid = false; + 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, +--- 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 { + __le32 mpdu_end_tag; + struct rx_mpdu_end mpdu_end; + u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES]; ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + __le32 hdr_status_tag; + __le32 phy_ppdu_id; + u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN]; ++#endif + u8 msdu_payload[]; + } __packed; + +@@ -1461,9 +1463,11 @@ struct hal_rx_desc_qcn9074 { + __le32 mpdu_end_tag; + struct rx_mpdu_end mpdu_end; + u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES]; ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + __le32 hdr_status_tag; + __le32 phy_ppdu_id; + u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN]; ++#endif + u8 msdu_payload[]; + } __packed; + +@@ -1480,9 +1484,11 @@ struct hal_rx_desc_wcn6855 { + __le32 mpdu_end_tag; + struct rx_mpdu_end mpdu_end; + u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES]; ++#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M + __le32 hdr_status_tag; + __le32 phy_ppdu_id; + u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN]; ++#endif + u8 msdu_payload[]; + } __packed; + +@@ -1507,4 +1513,17 @@ struct hal_rx_desc { + #define RU_484 18 + #define RU_996 37 + ++#define HAL_RX_MPDU_INFO_PN_GET_BYTE1(__val) \ ++ FIELD_GET(GENMASK(7, 0), __le32_to_cpu(__val)) ++ ++#define HAL_RX_MPDU_INFO_PN_GET_BYTE2(__val) \ ++ FIELD_GET(GENMASK(15, 8), __le32_to_cpu(__val)) ++ ++#define HAL_RX_MPDU_INFO_PN_GET_BYTE3(__val) \ ++ FIELD_GET(GENMASK(23, 16), __le32_to_cpu(__val)) ++ ++#define HAL_RX_MPDU_INFO_PN_GET_BYTE4(__val) \ ++ FIELD_GET(GENMASK(31, 24), __le32_to_cpu(__val)) ++ ++ + #endif /* ATH11K_RX_DESC_H */ +--- a/drivers/net/wireless/ath/ath11k/nss.c ++++ b/drivers/net/wireless/ath/ath11k/nss.c +@@ -2230,7 +2230,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; +- wim->wrip.rx_buf_len = DP_RX_BUFFER_SIZE; ++ wim->wrip.rx_buf_len = DP_RXDMA_NSS_REFILL_RING_SIZE; + + /* fill hal srng message */ + wim->hssm.dev_base_addr = (u32)ab->mem_pa; diff --git a/package/kernel/mac80211/patches/nss/ath11k/235-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 index 729ee80199b9a2..10e65157232edb 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/235-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 @@ -214,7 +214,7 @@ Signed-off-by: Sathishkumar Muruganandam ieee80211_queue_work(ar->hw, &arsta->set_4addr_wk); arsta->use_4addr_set = true; } -@@ -6646,6 +6770,9 @@ static int ath11k_mac_op_update_vif_offl +@@ -6647,6 +6771,9 @@ static int ath11k_mac_op_update_vif_offl u32 param_id, param_value; int ret; @@ -224,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 && -@@ -6866,7 +6993,8 @@ static int ath11k_mac_op_add_interface(s +@@ -6867,7 +6994,8 @@ static int ath11k_mac_op_add_interface(s goto err; } @@ -234,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; -@@ -6886,6 +7014,28 @@ static int ath11k_mac_op_add_interface(s +@@ -6887,6 +7015,28 @@ static int ath11k_mac_op_add_interface(s arvif->vif = vif; INIT_LIST_HEAD(&arvif->list); @@ -263,7 +263,7 @@ Signed-off-by: Sathishkumar Muruganandam INIT_DELAYED_WORK(&arvif->connection_loss_work, ath11k_mac_vif_sta_connection_loss_work); -@@ -6915,6 +7065,7 @@ static int ath11k_mac_op_add_interface(s +@@ -6916,6 +7066,7 @@ static int ath11k_mac_op_add_interface(s fallthrough; case NL80211_IFTYPE_AP: arvif->vdev_type = WMI_VDEV_TYPE_AP; @@ -271,7 +271,7 @@ Signed-off-by: Sathishkumar Muruganandam break; case NL80211_IFTYPE_MONITOR: arvif->vdev_type = WMI_VDEV_TYPE_MONITOR; -@@ -7137,13 +7288,30 @@ static void ath11k_mac_op_remove_interfa +@@ -7138,13 +7289,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; @@ -304,7 +304,7 @@ Signed-off-by: Sathishkumar Muruganandam ath11k_dbg(ab, ATH11K_DBG_MAC, "remove interface (vdev %d)\n", arvif->vdev_id); -@@ -7160,6 +7328,14 @@ static void ath11k_mac_op_remove_interfa +@@ -7161,6 +7329,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); @@ -319,7 +319,7 @@ Signed-off-by: Sathishkumar Muruganandam } ret = ath11k_mac_vdev_delete(ar, arvif); -@@ -7203,8 +7379,7 @@ err_vdev_del: +@@ -7204,8 +7380,7 @@ err_vdev_del: ath11k_debugfs_remove_interface(arvif); @@ -329,7 +329,7 @@ Signed-off-by: Sathishkumar Muruganandam mutex_unlock(&ar->conf_mutex); } -@@ -7264,16 +7439,17 @@ static int ath11k_mac_op_ampdu_action(st +@@ -7265,16 +7440,17 @@ static int ath11k_mac_op_ampdu_action(st struct ieee80211_ampdu_params *params) { struct ath11k *ar = hw->priv; @@ -349,7 +349,7 @@ Signed-off-by: Sathishkumar Muruganandam break; case IEEE80211_AMPDU_TX_START: case IEEE80211_AMPDU_TX_STOP_CONT: -@@ -8796,6 +8972,7 @@ static void ath11k_mac_op_sta_statistics +@@ -8797,6 +8973,7 @@ static void ath11k_mac_op_sta_statistics { struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); struct ath11k *ar = arsta->arvif->ar; @@ -357,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); -@@ -8852,7 +9029,8 @@ static void ath11k_mac_op_sta_statistics +@@ -8853,7 +9030,8 @@ static void ath11k_mac_op_sta_statistics ATH11K_DEFAULT_NOISE_FLOOR; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); @@ -380,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 -@@ -1121,12 +1121,13 @@ err_mem_free: +@@ -1156,12 +1156,13 @@ err_mem_free: return ret; } @@ -396,7 +396,7 @@ Signed-off-by: Sathishkumar Muruganandam int ret; ret = ath11k_peer_rx_tid_setup(ar, params->sta->addr, vdev_id, -@@ -1138,13 +1139,13 @@ int ath11k_dp_rx_ampdu_start(struct ath1 +@@ -1173,13 +1174,13 @@ int ath11k_dp_rx_ampdu_start(struct ath1 return ret; } diff --git a/package/kernel/mac80211/patches/nss/ath11k/236-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 index 80b8a5fc67d7ea..e7817f953ace6e 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/236-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 @@ -423,7 +423,7 @@ Signed-off-by: Sathishkumar Muruganandam } } else if (old_state == IEEE80211_STA_AUTHORIZED && new_state == IEEE80211_STA_ASSOC) { -@@ -7018,7 +7247,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7019,7 +7248,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; -@@ -7031,6 +7260,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7032,6 +7261,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; } -@@ -7055,6 +7285,20 @@ static int ath11k_mac_op_add_interface(s +@@ -7056,6 +7286,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: -@@ -7095,7 +7339,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7096,7 +7340,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++; -@@ -7254,7 +7498,7 @@ err_peer_del: +@@ -7255,7 +7499,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 } } -@@ -7265,6 +7509,8 @@ err_vdev_del: +@@ -7266,6 +7510,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); -@@ -7362,6 +7608,7 @@ err_vdev_del: +@@ -7363,6 +7609,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, -@@ -9960,8 +10207,11 @@ static int __ath11k_mac_register(struct +@@ -9961,8 +10208,11 @@ static int __ath11k_mac_register(struct ab->hw_params.bios_sar_capa) ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa; 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 index bbf4f20ac2326c..493ed32105629e 100644 --- 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 @@ -10,7 +10,7 @@ }; --- 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 +@@ -974,6 +974,79 @@ static const struct file_operations fops .llseek = default_llseek, }; @@ -90,7 +90,7 @@ 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 +@@ -1023,6 +1096,8 @@ int ath11k_debugfs_soc_create(struct ath ret = PTR_ERR(ab->debugfs_soc); goto out; } diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 61077309338ffb..c5cd8f20874996 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -33,7 +33,7 @@ Signed-off-by: P Praneesh enum ath11k_hw_rev { --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -340,6 +340,12 @@ static int ath11k_dp_purge_mon_ring(stru +@@ -375,6 +375,12 @@ static int ath11k_dp_purge_mon_ring(stru return -ETIMEDOUT; } @@ -46,7 +46,7 @@ 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, -@@ -1664,7 +1670,7 @@ int ath11k_dp_htt_tlv_iter(struct ath11k +@@ -1699,7 +1705,7 @@ int ath11k_dp_htt_tlv_iter(struct ath11k len -= sizeof(*tlv); if (tlv_len > len) { @@ -55,7 +55,7 @@ Signed-off-by: P Praneesh tlv_tag, ptr - begin, len, tlv_len); return -EINVAL; } -@@ -2454,10 +2460,60 @@ ath11k_dp_rx_h_find_peer(struct ath11k_b +@@ -2561,10 +2567,60 @@ ath11k_dp_rx_h_find_peer(struct ath11k_b return peer; } @@ -117,7 +117,7 @@ Signed-off-by: P Praneesh { bool fill_crypto_hdr; enum hal_encrypt_type enctype; -@@ -2468,9 +2524,13 @@ static void ath11k_dp_rx_h_mpdu(struct a +@@ -2575,9 +2631,13 @@ static void ath11k_dp_rx_h_mpdu(struct a struct rx_attention *rx_attention; u32 err_bitmap; @@ -132,7 +132,7 @@ Signed-off-by: P Praneesh rxcb->is_mcbc = fill_crypto_hdr; if (rxcb->is_mcbc) { -@@ -2481,6 +2541,26 @@ static void ath11k_dp_rx_h_mpdu(struct a +@@ -2588,6 +2648,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) { @@ -159,7 +159,7 @@ Signed-off-by: P Praneesh if (rxcb->is_mcbc) enctype = peer->sec_type_grp; else -@@ -2490,6 +2570,8 @@ static void ath11k_dp_rx_h_mpdu(struct a +@@ -2597,6 +2677,8 @@ static void ath11k_dp_rx_h_mpdu(struct a } spin_unlock_bh(&ar->ab->base_lock); @@ -168,7 +168,7 @@ Signed-off-by: P Praneesh 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 +@@ -2838,7 +2920,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, @@ -178,7 +178,7 @@ Signed-off-by: P Praneesh { struct ath11k_base *ab = ar->ab; struct hal_rx_desc *rx_desc, *lrx_desc; -@@ -2798,8 +2881,13 @@ static int ath11k_dp_rx_process_msdu(str +@@ -2920,8 +3003,13 @@ static int ath11k_dp_rx_process_msdu(str } } @@ -193,7 +193,7 @@ Signed-off-by: P Praneesh rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; -@@ -2814,10 +2902,12 @@ static void ath11k_dp_rx_process_receive +@@ -2936,10 +3024,12 @@ static void ath11k_dp_rx_process_receive struct sk_buff_head *msdu_list, int mac_id) { @@ -206,7 +206,7 @@ Signed-off-by: P Praneesh if (skb_queue_empty(msdu_list)) return; -@@ -2834,7 +2924,12 @@ static void ath11k_dp_rx_process_receive +@@ -2956,7 +3046,12 @@ static void ath11k_dp_rx_process_receive } while ((msdu = __skb_dequeue(msdu_list))) { @@ -220,7 +220,7 @@ Signed-off-by: P Praneesh if (unlikely(ret)) { ath11k_dbg(ab, ATH11K_DBG_DATA, "Unable to process msdu %d", ret); -@@ -2842,7 +2937,10 @@ static void ath11k_dp_rx_process_receive +@@ -2964,7 +3059,10 @@ static void ath11k_dp_rx_process_receive continue; } @@ -232,7 +232,7 @@ Signed-off-by: P Praneesh } } -@@ -2851,11 +2949,12 @@ void ath11k_dp_rx_from_nss(struct ath11k +@@ -2973,11 +3071,12 @@ void ath11k_dp_rx_from_nss(struct ath11k { struct ieee80211_rx_status rx_status = {0}; struct ath11k_skb_rxcb *rxcb; @@ -246,7 +246,7 @@ Signed-off-by: P Praneesh 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 +@@ -4446,6 +4545,7 @@ static int ath11k_dp_rx_h_null_q_desc(st struct ieee80211_rx_status *status, struct sk_buff_head *msdu_list) { @@ -254,7 +254,7 @@ Signed-off-by: P Praneesh 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 +@@ -4495,7 +4595,8 @@ static int ath11k_dp_rx_h_null_q_desc(st } ath11k_dp_rx_h_ppdu(ar, desc, status); @@ -266,7 +266,7 @@ Signed-off-by: P Praneesh --- a/drivers/net/wireless/ath/ath11k/hw.c +++ b/drivers/net/wireless/ath/ath11k/hw.c -@@ -293,6 +293,16 @@ static bool ath11k_hw_ipq8074_rx_desc_ge +@@ -297,6 +297,16 @@ static bool ath11k_hw_ipq8074_rx_desc_ge __le32_to_cpu(desc->u.ipq8074.msdu_start.info2)); } @@ -283,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, -@@ -470,6 +480,16 @@ static bool ath11k_hw_qcn9074_rx_desc_ge +@@ -584,6 +594,16 @@ static bool ath11k_hw_qcn9074_rx_desc_ge __le32_to_cpu(desc->u.qcn9074.msdu_start.info2)); } @@ -300,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, -@@ -1025,6 +1045,7 @@ const struct ath11k_hw_ops qca6390_ops = +@@ -1194,6 +1214,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, @@ -308,7 +308,15 @@ 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, -@@ -1189,6 +1210,7 @@ const struct ath11k_hw_ops ipq5018_ops = +@@ -1242,6 +1263,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, ++ .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, +@@ -1379,6 +1401,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, @@ -318,7 +326,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 -@@ -260,6 +260,7 @@ struct ath11k_hw_ops { +@@ -269,6 +269,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); diff --git a/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch b/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch index 7535883c4763d0..f514843b447f1a 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch @@ -454,7 +454,7 @@ Signed-off-by: P Praneesh ieee80211_free_txskb(ar->hw, skb); return; } -@@ -7622,7 +7632,7 @@ err_vdev_del: +@@ -7623,7 +7633,7 @@ err_vdev_del: idr_for_each(&ar->txmgmt_idr, ath11k_mac_vif_txmgmt_idr_remove, vif); @@ -465,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 -@@ -832,10 +832,22 @@ static ssize_t ath11k_debugfs_dump_soc_d +@@ -833,10 +833,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]); @@ -490,6 +490,15 @@ Signed-off-by: P Praneesh if (len > size) --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -105,7 +105,7 @@ static struct ath11k_hw_params ath11k_hw + .supports_regdb = false, + .fix_l1ss = true, + .credit_flow = false, +- .max_tx_ring = DP_TCL_NUM_RING_MAX, ++ .max_tx_ring = DP_TCL_NUM_RING_MAX + 1, + .hal_params = &ath11k_hw_hal_params_ipq8074, + .supports_dynamic_smps_6ghz = false, + .alloc_cacheable_memory = true, @@ -188,7 +188,6 @@ static struct ath11k_hw_params ath11k_hw .supports_regdb = false, .fix_l1ss = true, @@ -504,10 +513,19 @@ Signed-off-by: P Praneesh .support_fw_mac_sequence = 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, }, { .name = "qca6390 hw2.0", -@@ -380,6 +381,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, @@ -516,7 +534,7 @@ Signed-off-by: P Praneesh }, { .name = "wcn6855 hw2.0", -@@ -2143,6 +2146,9 @@ int ath11k_core_pre_init(struct ath11k_b +@@ -2143,6 +2145,9 @@ int ath11k_core_pre_init(struct ath11k_b if (nss_offload) ab->nss.stats_enabled = 1; 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 index b31809f689548b..1fa2d32aaa33cb 100644 --- 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 @@ -1014,7 +1014,7 @@ Signed-off-by: Vasanthakumar Thiagarajan +#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 { +@@ -1529,15 +1529,29 @@ struct htt_ppdu_stats_usr_cmn_array { struct htt_tx_ppdu_stats_info tx_ppdu_info[]; } __packed; @@ -1046,7 +1046,7 @@ Signed-off-by: Vasanthakumar Thiagarajan #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 +@@ -1444,6 +1444,71 @@ static int ath11k_htt_tlv_ppdu_stats_par return 0; } @@ -1118,7 +1118,7 @@ Signed-off-by: Vasanthakumar Thiagarajan 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 +@@ -1467,6 +1532,9 @@ ath11k_update_per_peer_tx_stats(struct a if (!(usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_RATE))) return; @@ -1128,7 +1128,7 @@ Signed-off-by: Vasanthakumar Thiagarajan 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 +@@ -1600,6 +1668,8 @@ ath11k_update_per_peer_tx_stats(struct a ath11k_debugfs_sta_add_tx_stats(arsta, peer_stats, rate_idx); } @@ -1137,7 +1137,7 @@ Signed-off-by: Vasanthakumar Thiagarajan spin_unlock_bh(&ab->base_lock); rcu_read_unlock(); } -@@ -1685,6 +1755,69 @@ int ath11k_dp_htt_tlv_iter(struct ath11k +@@ -1720,6 +1790,69 @@ int ath11k_dp_htt_tlv_iter(struct ath11k return 0; } @@ -1207,7 +1207,7 @@ Signed-off-by: Vasanthakumar Thiagarajan 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 +@@ -1738,6 +1871,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; @@ -1223,7 +1223,7 @@ Signed-off-by: Vasanthakumar Thiagarajan 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 +@@ -1805,6 +1947,12 @@ static int ath11k_htt_pull_ppdu_stats(st } } @@ -1257,7 +1257,7 @@ Signed-off-by: Vasanthakumar Thiagarajan mutex_unlock(&ar->conf_mutex); } -@@ -9714,6 +9726,28 @@ err_fallback: +@@ -9715,6 +9727,28 @@ err_fallback: return 0; } @@ -1286,7 +1286,7 @@ Signed-off-by: Vasanthakumar Thiagarajan static const struct ieee80211_ops ath11k_ops = { .tx = ath11k_mac_op_tx, .wake_tx_queue = ieee80211_handle_wake_tx_queue, -@@ -9771,6 +9805,9 @@ static const struct ieee80211_ops ath11k +@@ -9772,6 +9806,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, @@ -1296,7 +1296,7 @@ Signed-off-by: Vasanthakumar Thiagarajan }; static void ath11k_mac_update_ch_list(struct ath11k *ar, -@@ -10231,6 +10268,8 @@ static int __ath11k_mac_register(struct +@@ -10232,6 +10269,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); 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 index cb4fba0a2ffdcd..1d7cf5b0e7c585 100644 --- 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 @@ -23,7 +23,7 @@ Signed-off-by: Rameshkumar Sundaram --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -7643,8 +7643,10 @@ err_vdev_del: +@@ -7644,8 +7644,10 @@ err_vdev_del: kfree(arvif->vlan_keyid_map); ath11k_peer_cleanup(ar, arvif->vdev_id); diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index d733219b38aa7f..798ec1973c3fe3 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -1332,6 +1332,7 @@ const struct ath11k_hw_ring_mask ath11k_ +@@ -1573,6 +1573,7 @@ const struct ath11k_hw_ring_mask ath11k_ ATH11K_RX_WBM_REL_RING_MASK_0, }, .reo_status = { diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 3c3e436c75ce41..67781ea0ad2b6b 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -58,7 +58,7 @@ Signed-off-by: Venkateswara Naralasetty 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 -@@ -10154,6 +10154,8 @@ static int __ath11k_mac_register(struct +@@ -10155,6 +10155,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 index 752218e9b8ec26..90adde1baf67db 100644 --- 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 @@ -16,7 +16,7 @@ Signed-off-by: Anilkumar Kolli --- 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 +@@ -6124,12 +6124,23 @@ int ath11k_dp_rx_process_mon_status(stru pmon->mon_ppdu_status = DP_PPDU_STATUS_START; } @@ -43,7 +43,7 @@ Signed-off-by: Anilkumar Kolli 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 +@@ -6453,6 +6464,13 @@ static int ath11k_dp_full_mon_process_rx spin_lock_bh(&pmon->mon_lock); @@ -57,7 +57,7 @@ Signed-off-by: Anilkumar Kolli 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 +@@ -6492,7 +6510,6 @@ static int ath11k_dp_full_mon_process_rx } rx_mon_stats->dest_ppdu_done++; @@ -65,7 +65,7 @@ Signed-off-by: Anilkumar Kolli 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: +@@ -6523,16 +6540,10 @@ reap_status_ring: int ath11k_dp_rx_process_mon_rings(struct ath11k_base *ab, int mac_id, struct napi_struct *napi, int budget) { diff --git a/package/kernel/mac80211/patches/nss/ath11k/336-ath11k-skip-status-ring-entry-processing.patch b/package/kernel/mac80211/patches/nss/ath11k/336-ath11k-skip-status-ring-entry-processing.patch index 0adf26c808aec6..8950e960467e67 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -3660,6 +3660,46 @@ ath11k_dp_rx_mon_update_status_buf_state +@@ -3782,6 +3782,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) { -@@ -3673,6 +3713,7 @@ static int ath11k_dp_rx_reap_mon_status_ +@@ -3795,6 +3835,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; -@@ -3692,8 +3733,7 @@ static int ath11k_dp_rx_reap_mon_status_ +@@ -3814,8 +3855,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; -@@ -3724,18 +3764,43 @@ static int ath11k_dp_rx_reap_mon_status_ +@@ -3846,18 +3886,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) { diff --git a/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch b/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch index f574597dceb969..8e23cd99e747c6 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch @@ -46,7 +46,7 @@ Signed-off-by: Nagarajan Maran --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -396,8 +396,8 @@ int ath11k_dp_rxbufs_replenish(struct at +@@ -431,8 +431,8 @@ int ath11k_dp_rxbufs_replenish(struct at goto fail_free_skb; spin_lock_bh(&rx_ring->idr_lock); @@ -57,7 +57,7 @@ Signed-off-by: Nagarajan Maran spin_unlock_bh(&rx_ring->idr_lock); if (buf_id <= 0) goto fail_dma_unmap; -@@ -3141,6 +3141,16 @@ try_again: +@@ -3263,6 +3263,16 @@ try_again: while (likely(desc = (struct hal_reo_dest_ring *)ath11k_hal_srng_dst_get_next_entry(ab, srng))) { @@ -74,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, -@@ -3171,8 +3181,6 @@ try_again: +@@ -3293,8 +3303,6 @@ try_again: num_buffs_reaped[mac_id]++; diff --git a/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch b/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch index f57faaa465ae76..fe231db61355ea 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch @@ -13,7 +13,7 @@ Signed-off-by: Ramya Gnanasekar --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -2564,7 +2564,8 @@ static void ath11k_dp_rx_h_undecap(struc +@@ -2671,7 +2671,8 @@ static void ath11k_dp_rx_h_undecap(struc ehdr = (struct ethhdr *)msdu->data; /* mac80211 allows fast path only for authorized STA */ 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 index f909ba4a673f69..fd4f0938cdb83b 100644 --- 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 @@ -14,7 +14,7 @@ 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 { +@@ -1501,6 +1501,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 @@ -24,7 +24,7 @@ Signed-off-by: Ramya Gnanasekar 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 +@@ -1323,7 +1323,7 @@ static int ath11k_htt_tlv_ppdu_stats_par struct htt_ppdu_user_stats *user_stats = NULL; int cur_user; u16 peer_id; @@ -33,7 +33,7 @@ Signed-off-by: Ramya Gnanasekar ppdu_info = data; -@@ -1369,6 +1369,8 @@ static int ath11k_htt_tlv_ppdu_stats_par +@@ -1404,6 +1404,8 @@ static int ath11k_htt_tlv_ppdu_stats_par return -EINVAL; } @@ -42,7 +42,7 @@ Signed-off-by: Ramya Gnanasekar 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 +@@ -1415,6 +1417,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)); diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 8adb5448a1564c..fd78090aebc0f0 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -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 -@@ -848,6 +848,18 @@ static ssize_t ath11k_debugfs_dump_soc_d +@@ -849,6 +849,18 @@ static ssize_t ath11k_debugfs_dump_soc_d "\nNSS Transmit Failures: %d\n", atomic_read(&soc_stats->tx_err.nss_tx_fail)); @@ -110,7 +110,7 @@ Signed-off-by: Tamizh Chelvam Raja struct dp_reo_cmd { struct list_head list; struct dp_rx_tid data; -@@ -295,6 +304,12 @@ struct ath11k_dp { +@@ -296,6 +305,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) { -@@ -672,13 +675,50 @@ static int ath11k_dp_rx_pdev_srng_alloc( +@@ -707,13 +710,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); -@@ -724,14 +764,18 @@ static void ath11k_dp_reo_cmd_free(struc +@@ -759,14 +799,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) { -@@ -742,11 +786,17 @@ static void ath11k_dp_reo_cache_flush(st +@@ -777,11 +821,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); -@@ -754,24 +804,21 @@ static void ath11k_dp_reo_cache_flush(st +@@ -789,24 +839,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? */ -@@ -780,6 +827,29 @@ static void ath11k_dp_rx_tid_del_func(st +@@ -815,6 +862,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; -@@ -797,13 +867,20 @@ static void ath11k_dp_rx_tid_del_func(st +@@ -832,13 +902,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); -@@ -819,34 +896,48 @@ free_desc: +@@ -854,34 +931,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/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 00000000000000..1f66f72a4a4851 --- /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 +@@ -8001,7 +8001,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 +@@ -2960,6 +2960,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 00000000000000..7d413afec97b3d --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/453-ath11k-flush-management-frames-to-firmware-before-wa.patch @@ -0,0 +1,43 @@ +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(+) + +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index 28c9908ef816..dbdb7aa5c498 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -10266,6 +10266,8 @@ static int ath11k_mac_flush_tx_complete(struct ath11k *ar) + 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); +-- +2.7.4 + 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 index 510fbc2448cee7..1f81a8ef722598 100644 --- 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 @@ -13,7 +13,7 @@ Signed-off-by: Yuvasree Sivasankaran --- 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 +@@ -10142,6 +10142,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); diff --git a/package/kernel/mac80211/patches/nss/ath11k/457-wifi-ath11k-Avoid-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 index c23b6cb3c858b4..55d8063a2403ca 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/457-wifi-ath11k-Avoid-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 -@@ -6090,7 +6090,9 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -6261,7 +6261,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))) { -@@ -6108,7 +6110,6 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -6279,7 +6281,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,7 +67,7 @@ Signed-off-by: Yuvasree Sivasankaran ppdu_info->peer_id = HAL_INVALID_PEERID; hal_status = ath11k_hal_rx_parse_mon_status(ab, ppdu_info, skb); -@@ -6136,6 +6137,7 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -6307,6 +6308,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); 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 00000000000000..fe767b6a33de2a --- /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 +@@ -427,9 +427,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; + +@@ -465,8 +465,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 index b471fb326a5b48..b2912777fad5d0 100644 --- 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 @@ -26,7 +26,7 @@ Acked-by: Jeff Johnson --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -8221,7 +8221,6 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -8222,7 +8222,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; @@ -34,7 +34,7 @@ Acked-by: Jeff Johnson mutex_lock(&ar->conf_mutex); -@@ -8244,21 +8243,6 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -8245,21 +8244,6 @@ ath11k_mac_op_assign_vif_chanctx(struct goto out; } 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 index 2fb2cdfd429b11..ea08ea8818155d 100644 --- 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 @@ -39,7 +39,7 @@ Acked-by: Jeff Johnson if (ret) { ath11k_warn(ab, "failed to delay vdev start: %d\n", ret); goto free_tx_stats; -@@ -8164,8 +8164,8 @@ unlock: +@@ -8165,8 +8165,8 @@ unlock: mutex_unlock(&ar->conf_mutex); } 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 index 4d83d0f0ed9029..a2ff42ad9d194d 100644 --- 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 @@ -317,7 +317,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) -@@ -9739,6 +9461,281 @@ ath11k_mac_op_config_mesh_offload_path(s +@@ -9740,6 +9462,281 @@ ath11k_mac_op_config_mesh_offload_path(s } #endif 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 index d1b462519c91e8..aeaf65aaa0e73b 100644 --- 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 @@ -52,7 +52,7 @@ Acked-by: Jeff Johnson --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -7933,6 +7933,30 @@ static int ath11k_mac_start_vdev_delay(s +@@ -7934,6 +7934,30 @@ static int ath11k_mac_start_vdev_delay(s return 0; } @@ -83,7 +83,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -@@ -7977,15 +8001,17 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -7978,15 +8002,17 @@ ath11k_mac_op_assign_vif_chanctx(struct goto out; } @@ -109,7 +109,7 @@ Acked-by: Jeff Johnson if (arvif->vdev_type != WMI_VDEV_TYPE_MONITOR && test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags)) { -@@ -8025,8 +8051,6 @@ ath11k_mac_op_unassign_vif_chanctx(struc +@@ -8026,8 +8052,6 @@ ath11k_mac_op_unassign_vif_chanctx(struc "chanctx unassign ptr %p vdev_id %i\n", ctx, arvif->vdev_id); @@ -118,7 +118,7 @@ Acked-by: Jeff Johnson if (ab->hw_params.vdev_start_delay && arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { spin_lock_bh(&ab->base_lock); -@@ -8050,24 +8074,13 @@ ath11k_mac_op_unassign_vif_chanctx(struc +@@ -8051,24 +8075,13 @@ ath11k_mac_op_unassign_vif_chanctx(struc return; } @@ -149,7 +149,7 @@ Acked-by: Jeff Johnson } if (ab->hw_params.vdev_start_delay && -@@ -9555,6 +9568,46 @@ exit: +@@ -9556,6 +9569,46 @@ exit: return ret; } @@ -196,7 +196,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, -@@ -9590,31 +9643,15 @@ static int ath11k_mac_op_sta_state(struc +@@ -9591,31 +9644,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)) { @@ -233,7 +233,7 @@ Acked-by: Jeff Johnson 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); -@@ -9625,12 +9662,6 @@ static int ath11k_mac_op_sta_state(struc +@@ -9626,12 +9663,6 @@ static int ath11k_mac_op_sta_state(struc } spin_unlock_bh(&ar->ab->base_lock); mutex_unlock(&ar->ab->tbl_mtx_lock); @@ -246,7 +246,7 @@ Acked-by: Jeff Johnson } 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 +@@ -10203,6 +10234,8 @@ static int __ath11k_mac_register(struct wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); 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 index 2362820dc9e838..06f5e62c7b103c 100644 --- 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 @@ -40,7 +40,7 @@ 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 +@@ -1877,7 +1877,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); @@ -120,7 +120,7 @@ &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 +@@ -1758,8 +1758,10 @@ ath11k_update_per_peer_tx_stats(struct a peer_stats->mu_pos = mu_pos; peer_stats->ru_tones = arsta->txrate.he_ru_alloc; @@ -131,7 +131,7 @@ } usr_stats->rate_stats_updated = true; -@@ -2170,7 +2172,9 @@ void ath11k_dp_htt_htc_t2h_msg_handler(s +@@ -2205,7 +2207,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: @@ -176,7 +176,7 @@ spin_unlock_bh(&ab->base_lock); --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -9812,7 +9812,7 @@ static const struct ieee80211_ops ath11k +@@ -9813,7 +9813,7 @@ static const struct ieee80211_ops ath11k .set_wakeup = ath11k_wow_op_set_wakeup, #endif 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 00000000000000..c2cc4f2f89f43e --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/999-336-0002-ath11k-Use-idr_replace.patch @@ -0,0 +1,264 @@ +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; + } + +@@ -3346,11 +3365,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]; + +@@ -3383,8 +3405,16 @@ 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_find(&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", + buf_id); +@@ -3464,9 +3494,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; + } + +@@ -4831,7 +4864,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; +@@ -5047,14 +5080,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]; + +@@ -5129,7 +5165,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(); +@@ -5151,6 +5187,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; + } + +@@ -5238,7 +5276,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; + } +@@ -6184,12 +6222,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); + } + } + +@@ -6701,7 +6739,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), From 6afa4bf85d8146e404835f3e88ca95a6639fb4b3 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sat, 9 Mar 2024 11:59:20 -0500 Subject: [PATCH 213/225] ath11k_nss: Introduce skbuff_recycle for performance QSDK NSS builds utilize skbuff recycling for better handling of memory. On a Dynalink DL-WRX36 (pbuf script should be set to 'auto') a significant drop in memory usage was observed as well consistent sustained RX/TX speeds. BEFORE: echo 3 >! /proc/sys/vm/drop_caches free -m total used free shared buff/cache available Mem: 867 338 547 90 101 528 Swap: 0 0 0 AFTER: total used free shared buff/cache available Mem: 867 242 594 1 81 624 Swap: 0 0 0 NOTE: For 512MB platforms, users need to test with the following scenarios, as the patch `999-233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch` is really only testable on platforms with 512M or less RAM. 1.) Explicitly setting 'ATH11K_MEM_PROFILE_512M' on and see if system crashes on boot. 2.) Explicitly setting 'ATH11K_MEM_PROFILE_1G' 3.) Remove patches 999-233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch 999-311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch And re-test with #1 and #2 It was incorrectly assumed that setting a 512M for 1G platforms would save memory, instead it needs to be explicitly set to know proper memory regions, otherwise it would cause fw crash. ath11k_nss: fix typo in 512M memory profile ath11k_nss: remove SFE patch 718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly It is not relevant to NSS builds and only meant for SFE. ath11k_nss: remove unecessary patches Color collision should be left on by default, as it's a primary feature of 802.11AX. ath11k_nss: fix spacing ath11k_nss: Remove unnecessary TKIP bloat Remove TKIP patches that are not being used as 99% of folks are running modern encryption (AES-CCMP,SAE,etc). ath11k_nss: parameterize DP_RXDMA_REFILL_RING_SIZE memory profile ath11k_nss: Remove SFE related code Cleanup SFE (shortcut fe) related code as we're not using it on NSS ath11k_nss: idr, ampdu, and skb headroom check optimizations ath11k_nss: get valid last_rate for rx_bitrate from cpu stats ath11k_nss: 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. ath11k_nss: Fix compile for TRACE feature --- package/kernel/mac80211/ath.mk | 1 - ...207-ath11k-Enable-256_512MB-profiles.patch | 32 +- ...rt-to-enable-disable-color-collision.patch | 46 -- ...pport-for-WDS-offload-in-NSS-offload.patch | 24 +- ...-dynamic-VLAN-support-in-NSS-offload.patch | 16 +- ...ow-fast-rx-by-bypassing-stats-update.patch | 6 +- ...ow-fast-rx-by-bypassing-stats-update.patch | 46 +- .../nss/ath11k/244-ath11k-dp-tx-perf.patch | 14 +- .../300-ath11k-nss-mesh-offload-support.patch | 20 +- ...lookup-failure-in-mgmt-tx-completion.patch | 2 +- ...e-free-of-peer-rx_tid-during-reo-cmd.patch | 2 +- ...30-ath11k-sync-wds_ast_entry-updates.patch | 2 +- ...TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch | 2 +- ...ing-rx-stats-with-monitor-vif-enable.patch | 8 +- ...1k-skip-status-ring-entry-processing.patch | 8 +- ...356-ath11k-invalid-desc-sanity-check.patch | 6 +- ...-fix-tkip-encryption-traffic-failure.patch | 25 - ...Fix-ppdu_id-from-firmware-PPDU-stats.patch | 8 +- ...Add-retry-mechanism-for-update_rx_qu.patch | 18 +- ...treaming-not-working-for-wan-to-wlan.patch | 44 -- ...th11k-Advertise-TX_QUEUE-mac-hw-flag.patch | 2 +- ...oid-memset-of-ppdu-info-for-next-skb.patch | 6 +- ...support-to-send-the-QoS-Null-Data-fr.patch | 10 +- ...11k-remove-invalid-peer-create-logic.patch | 4 +- ...th11k-rename-ath11k_start_vdev_delay.patch | 2 +- ...ation-of-ath11k_mac_start_vdev_delay.patch | 2 +- ...ailure-due-to-unexpected-peer-delete.patch | 16 +- ...k-make-debugfs-sta-htt-stats-modular.patch | 8 +- ...1k-Disable-rx_header-tlv-for-2K-SKB.patch} | 128 ++- ...-nss-thread-priority-during-pdev_ini.patch | 109 +++ ...d-ampdu-id-in-802.11-radiotap-header.patch | 279 +++++++ ...999-336-0001-ath11k-idr-optimization.patch | 132 ++++ .../999-336-0002-ath11k-Use-idr_replace.patch | 28 +- ...k-skb_headroom-before-using-skb_push.patch | 253 ++++++ ...wifi-ath11k-Fix-BCCA-counter-for-EMA.patch | 115 +++ .../199-001-mac80211-add-nss-support.patch | 2 +- ...ort-to-enable-disable-bss-color-coll.patch | 78 -- ...-the-frame-to-driver-tx-ops-directly.patch | 74 -- ...id-last_rate-for-rx_bitrate-from-cpu.patch | 68 ++ ...se-HW-checksum-offload-only-for-ethm.patch | 31 +- target/linux/qualcommax/config-6.6 | 5 + .../qualcommax/files/net/core/skbuff_debug.c | 332 ++++++++ .../qualcommax/files/net/core/skbuff_debug.h | 53 ++ .../files/net/core/skbuff_notifier.c | 42 + .../files/net/core/skbuff_notifier.h | 52 ++ .../files/net/core/skbuff_recycle.c | 729 ++++++++++++++++++ .../files/net/core/skbuff_recycle.h | 178 +++++ 47 files changed, 2547 insertions(+), 521 deletions(-) delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/218-ath11k-add-support-to-enable-disable-color-collision.patch delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch delete mode 100644 package/kernel/mac80211/patches/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch rename package/kernel/mac80211/patches/nss/ath11k/{233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch => 999-233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch} (90%) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/999-311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/999-312-ath11k-add-ampdu-id-in-802.11-radiotap-header.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/999-336-0001-ath11k-idr-optimization.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/999-374-ath11k-Check-skb_headroom-before-using-skb_push.patch create mode 100644 package/kernel/mac80211/patches/nss/ath11k/999-783-001-wifi-ath11k-Fix-BCCA-counter-for-EMA.patch delete mode 100644 package/kernel/mac80211/patches/nss/subsys/649-nl80211-Add-support-to-enable-disable-bss-color-coll.patch delete mode 100644 package/kernel/mac80211/patches/nss/subsys/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch create mode 100644 package/kernel/mac80211/patches/nss/subsys/751-mac80211-Get-valid-last_rate-for-rx_bitrate-from-cpu.patch create mode 100644 target/linux/qualcommax/files/net/core/skbuff_debug.c create mode 100644 target/linux/qualcommax/files/net/core/skbuff_debug.h create mode 100644 target/linux/qualcommax/files/net/core/skbuff_notifier.c create mode 100644 target/linux/qualcommax/files/net/core/skbuff_notifier.h create mode 100644 target/linux/qualcommax/files/net/core/skbuff_recycle.c create mode 100644 target/linux/qualcommax/files/net/core/skbuff_recycle.h diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk index 574a3e2424dc90..ba76c0125a910b 100644 --- a/package/kernel/mac80211/ath.mk +++ b/package/kernel/mac80211/ath.mk @@ -70,7 +70,6 @@ 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-$(CONFIG_ATH11K_NSS_MESH_SUPPORT) += ATH11K_NSS_MESH_SUPPORT config-$(call config_package,ath9k-htc) += ATH9K_HTC config-$(call config_package,ath10k,regular) += ATH10K ATH10K_PCI diff --git a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch index 75e0bf1b79b844..4d9c1537a8bb4b 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch @@ -245,15 +245,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = false, -@@ -210,6 +213,7 @@ 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, - }, - { - .name = "qca6390 hw2.0", -@@ -259,7 +263,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, @@ -262,7 +254,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -426,7 +430,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, @@ -271,7 +263,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -462,6 +466,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, @@ -279,7 +271,7 @@ Signed-off-by: Ramya Gnanasekar }, { .name = "wcn6855 hw2.1", -@@ -509,7 +514,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -509,7 +513,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -288,7 +280,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -545,6 +550,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, @@ -296,7 +288,7 @@ Signed-off-by: Ramya Gnanasekar }, { .name = "wcn6750 hw1.0", -@@ -593,7 +599,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -593,7 +598,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = true, .coldboot_cal_ftm = true, .cbcal_restart_fw = false, @@ -305,15 +297,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = false, -@@ -626,6 +632,7 @@ static struct ath11k_hw_params ath11k_hw - .tx_ring_size = DP_TCL_DATA_RING_SIZE_WCN6750, - .smp2p_wow_exit = true, - .support_fw_mac_sequence = true, -+ .num_vdevs_peers = ath11k_vdevs_peers, - }, - { - .hw_rev = ATH11K_HW_IPQ5018_HW10, -@@ -672,7 +679,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, @@ -322,7 +306,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_regdb = false, -@@ -707,6 +714,22 @@ static struct ath11k_hw_params ath11k_hw +@@ -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, diff --git a/package/kernel/mac80211/patches/nss/ath11k/218-ath11k-add-support-to-enable-disable-color-collision.patch b/package/kernel/mac80211/patches/nss/ath11k/218-ath11k-add-support-to-enable-disable-color-collision.patch deleted file mode 100644 index 24520cbeafbc7a..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/218-ath11k-add-support-to-enable-disable-color-collision.patch +++ /dev/null @@ -1,46 +0,0 @@ -From ee8c401bdfa08c6b98fb5b016841db5603ba4059 Mon Sep 17 00:00:00 2001 -From: Lavanya Suresh -Date: Wed, 23 Sep 2020 21:54:34 +0530 -Subject: [PATCH] ath11k: add support to enable/disable bss color collision - detection - -Added module param to enable or disable bss color collision detection. -By default, it is disabled. This config should be changed before VAP -bringup only. - - -Signed-off-by: Lavanya Suresh ---- - drivers/net/wireless/ath/ath11k/mac.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/ath/ath11k/mac.c -+++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -53,6 +54,10 @@ - .max_power = 30, \ - } - -+unsigned int color_collision_enable = 0; -+module_param_named(color_collision_detect, color_collision_enable, uint, 0644); -+MODULE_PARM_DESC(color_collision_detect, "BSS color collision detecion: 0-disable 1-enable"); -+ - static const struct ieee80211_channel ath11k_2ghz_channels[] = { - CHAN2G(1, 2412, 0), - CHAN2G(2, 2417, 0), -@@ -3723,7 +3728,7 @@ static void ath11k_mac_op_bss_info_chang - ret = ath11k_wmi_send_obss_color_collision_cfg_cmd( - ar, arvif->vdev_id, info->he_bss_color.color, - ATH11K_BSS_COLOR_COLLISION_DETECTION_AP_PERIOD_MS, -- info->he_bss_color.enabled); -+ (info->he_bss_color.enabled & color_collision_enable)); - if (ret) - ath11k_warn(ar->ab, "failed to set bss color collision on vdev %i: %d\n", - arvif->vdev_id, ret); diff --git a/package/kernel/mac80211/patches/nss/ath11k/235-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 index 10e65157232edb..729ee80199b9a2 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/235-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 @@ -214,7 +214,7 @@ Signed-off-by: Sathishkumar Muruganandam ieee80211_queue_work(ar->hw, &arsta->set_4addr_wk); arsta->use_4addr_set = true; } -@@ -6647,6 +6771,9 @@ static int ath11k_mac_op_update_vif_offl +@@ -6646,6 +6770,9 @@ static int ath11k_mac_op_update_vif_offl u32 param_id, param_value; int ret; @@ -224,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 && -@@ -6867,7 +6994,8 @@ static int ath11k_mac_op_add_interface(s +@@ -6866,7 +6993,8 @@ static int ath11k_mac_op_add_interface(s goto err; } @@ -234,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; -@@ -6887,6 +7015,28 @@ static int ath11k_mac_op_add_interface(s +@@ -6886,6 +7014,28 @@ static int ath11k_mac_op_add_interface(s arvif->vif = vif; INIT_LIST_HEAD(&arvif->list); @@ -263,7 +263,7 @@ Signed-off-by: Sathishkumar Muruganandam INIT_DELAYED_WORK(&arvif->connection_loss_work, ath11k_mac_vif_sta_connection_loss_work); -@@ -6916,6 +7066,7 @@ static int ath11k_mac_op_add_interface(s +@@ -6915,6 +7065,7 @@ static int ath11k_mac_op_add_interface(s fallthrough; case NL80211_IFTYPE_AP: arvif->vdev_type = WMI_VDEV_TYPE_AP; @@ -271,7 +271,7 @@ Signed-off-by: Sathishkumar Muruganandam break; case NL80211_IFTYPE_MONITOR: arvif->vdev_type = WMI_VDEV_TYPE_MONITOR; -@@ -7138,13 +7289,30 @@ static void ath11k_mac_op_remove_interfa +@@ -7137,13 +7288,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; @@ -304,7 +304,7 @@ Signed-off-by: Sathishkumar Muruganandam ath11k_dbg(ab, ATH11K_DBG_MAC, "remove interface (vdev %d)\n", arvif->vdev_id); -@@ -7161,6 +7329,14 @@ static void ath11k_mac_op_remove_interfa +@@ -7160,6 +7328,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); @@ -319,7 +319,7 @@ Signed-off-by: Sathishkumar Muruganandam } ret = ath11k_mac_vdev_delete(ar, arvif); -@@ -7204,8 +7380,7 @@ err_vdev_del: +@@ -7203,8 +7379,7 @@ err_vdev_del: ath11k_debugfs_remove_interface(arvif); @@ -329,7 +329,7 @@ Signed-off-by: Sathishkumar Muruganandam mutex_unlock(&ar->conf_mutex); } -@@ -7265,16 +7440,17 @@ static int ath11k_mac_op_ampdu_action(st +@@ -7264,16 +7439,17 @@ static int ath11k_mac_op_ampdu_action(st struct ieee80211_ampdu_params *params) { struct ath11k *ar = hw->priv; @@ -349,7 +349,7 @@ Signed-off-by: Sathishkumar Muruganandam break; case IEEE80211_AMPDU_TX_START: case IEEE80211_AMPDU_TX_STOP_CONT: -@@ -8797,6 +8973,7 @@ static void ath11k_mac_op_sta_statistics +@@ -8796,6 +8972,7 @@ static void ath11k_mac_op_sta_statistics { struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); struct ath11k *ar = arsta->arvif->ar; @@ -357,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); -@@ -8853,7 +9030,8 @@ static void ath11k_mac_op_sta_statistics +@@ -8852,7 +9029,8 @@ static void ath11k_mac_op_sta_statistics ATH11K_DEFAULT_NOISE_FLOOR; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); @@ -380,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 -@@ -1156,12 +1156,13 @@ err_mem_free: +@@ -1121,12 +1121,13 @@ err_mem_free: return ret; } @@ -396,7 +396,7 @@ Signed-off-by: Sathishkumar Muruganandam int ret; ret = ath11k_peer_rx_tid_setup(ar, params->sta->addr, vdev_id, -@@ -1173,13 +1174,13 @@ int ath11k_dp_rx_ampdu_start(struct ath1 +@@ -1138,13 +1139,13 @@ int ath11k_dp_rx_ampdu_start(struct ath1 return ret; } diff --git a/package/kernel/mac80211/patches/nss/ath11k/236-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 index e7817f953ace6e..80b8a5fc67d7ea 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/236-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 @@ -423,7 +423,7 @@ Signed-off-by: Sathishkumar Muruganandam } } else if (old_state == IEEE80211_STA_AUTHORIZED && new_state == IEEE80211_STA_ASSOC) { -@@ -7019,7 +7248,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7018,7 +7247,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; -@@ -7032,6 +7261,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7031,6 +7260,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; } -@@ -7056,6 +7286,20 @@ static int ath11k_mac_op_add_interface(s +@@ -7055,6 +7285,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: -@@ -7096,7 +7340,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7095,7 +7339,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++; -@@ -7255,7 +7499,7 @@ err_peer_del: +@@ -7254,7 +7498,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 } } -@@ -7266,6 +7510,8 @@ err_vdev_del: +@@ -7265,6 +7509,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); -@@ -7363,6 +7609,7 @@ err_vdev_del: +@@ -7362,6 +7608,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, -@@ -9961,8 +10208,11 @@ static int __ath11k_mac_register(struct +@@ -9960,8 +10207,11 @@ static int __ath11k_mac_register(struct ab->hw_params.bios_sar_capa) ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa; 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 index 493ed32105629e..0362ff8caa5d0e 100644 --- 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 @@ -4,13 +4,13 @@ u32 max_ast_index; u32 num_ast_entries; -+ bool stats_disable; ++ 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 -@@ -974,6 +974,79 @@ static const struct file_operations fops +@@ -973,6 +973,79 @@ static const struct file_operations fops .llseek = default_llseek, }; @@ -90,7 +90,7 @@ int ath11k_debugfs_pdev_create(struct ath11k_base *ab) { if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) -@@ -1023,6 +1096,8 @@ int ath11k_debugfs_soc_create(struct ath +@@ -1022,6 +1095,8 @@ int ath11k_debugfs_soc_create(struct ath ret = PTR_ERR(ab->debugfs_soc); goto out; } diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index c5cd8f20874996..61077309338ffb 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -33,7 +33,7 @@ Signed-off-by: P Praneesh enum ath11k_hw_rev { --- 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; } @@ -46,7 +46,7 @@ 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, -@@ -1699,7 +1705,7 @@ int ath11k_dp_htt_tlv_iter(struct ath11k +@@ -1664,7 +1670,7 @@ int ath11k_dp_htt_tlv_iter(struct ath11k len -= sizeof(*tlv); if (tlv_len > len) { @@ -55,7 +55,7 @@ Signed-off-by: P Praneesh tlv_tag, ptr - begin, len, tlv_len); return -EINVAL; } -@@ -2561,10 +2567,60 @@ ath11k_dp_rx_h_find_peer(struct ath11k_b +@@ -2454,10 +2460,60 @@ ath11k_dp_rx_h_find_peer(struct ath11k_b return peer; } @@ -117,7 +117,7 @@ Signed-off-by: P Praneesh { bool fill_crypto_hdr; enum hal_encrypt_type enctype; -@@ -2575,9 +2631,13 @@ 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; @@ -132,7 +132,7 @@ Signed-off-by: P Praneesh rxcb->is_mcbc = fill_crypto_hdr; if (rxcb->is_mcbc) { -@@ -2588,6 +2648,26 @@ static void ath11k_dp_rx_h_mpdu(struct a +@@ -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) { @@ -159,7 +159,7 @@ Signed-off-by: P Praneesh if (rxcb->is_mcbc) enctype = peer->sec_type_grp; else -@@ -2597,6 +2677,8 @@ static void ath11k_dp_rx_h_mpdu(struct a +@@ -2490,6 +2570,8 @@ static void ath11k_dp_rx_h_mpdu(struct a } spin_unlock_bh(&ar->ab->base_lock); @@ -168,7 +168,7 @@ Signed-off-by: P Praneesh 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) -@@ -2838,7 +2920,8 @@ static void ath11k_dp_rx_deliver_msdu(st +@@ -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, @@ -178,7 +178,7 @@ Signed-off-by: P Praneesh { struct ath11k_base *ab = ar->ab; struct hal_rx_desc *rx_desc, *lrx_desc; -@@ -2920,8 +3003,13 @@ static int ath11k_dp_rx_process_msdu(str +@@ -2798,8 +2881,13 @@ static int ath11k_dp_rx_process_msdu(str } } @@ -193,7 +193,7 @@ Signed-off-by: P Praneesh rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; -@@ -2936,10 +3024,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) { @@ -206,7 +206,7 @@ Signed-off-by: P Praneesh if (skb_queue_empty(msdu_list)) return; -@@ -2956,7 +3046,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))) { @@ -220,7 +220,7 @@ Signed-off-by: P Praneesh if (unlikely(ret)) { ath11k_dbg(ab, ATH11K_DBG_DATA, "Unable to process msdu %d", ret); -@@ -2964,7 +3059,10 @@ static void ath11k_dp_rx_process_receive +@@ -2842,7 +2937,10 @@ static void ath11k_dp_rx_process_receive continue; } @@ -232,7 +232,7 @@ Signed-off-by: P Praneesh } } -@@ -2973,11 +3071,12 @@ void ath11k_dp_rx_from_nss(struct ath11k +@@ -2851,11 +2949,12 @@ void ath11k_dp_rx_from_nss(struct ath11k { struct ieee80211_rx_status rx_status = {0}; struct ath11k_skb_rxcb *rxcb; @@ -246,7 +246,7 @@ Signed-off-by: P Praneesh rx_status.flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; -@@ -4446,6 +4545,7 @@ static int ath11k_dp_rx_h_null_q_desc(st +@@ -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) { @@ -254,7 +254,7 @@ Signed-off-by: P Praneesh u16 msdu_len; struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; struct rx_attention *rx_attention; -@@ -4495,7 +4595,8 @@ static int ath11k_dp_rx_h_null_q_desc(st +@@ -4371,7 +4471,8 @@ static int ath11k_dp_rx_h_null_q_desc(st } ath11k_dp_rx_h_ppdu(ar, desc, status); @@ -266,7 +266,7 @@ Signed-off-by: P Praneesh --- a/drivers/net/wireless/ath/ath11k/hw.c +++ b/drivers/net/wireless/ath/ath11k/hw.c -@@ -297,6 +297,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)); } @@ -283,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, -@@ -584,6 +594,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)); } @@ -300,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, -@@ -1194,6 +1214,7 @@ const struct ath11k_hw_ops ipq6018_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, @@ -308,15 +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, -@@ -1242,6 +1263,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, -+ .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, -@@ -1379,6 +1401,7 @@ const struct ath11k_hw_ops wcn6750_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, @@ -326,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 -@@ -269,6 +269,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); diff --git a/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch b/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch index f514843b447f1a..1c9a6ebd1d41ac 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch @@ -454,7 +454,7 @@ Signed-off-by: P Praneesh ieee80211_free_txskb(ar->hw, skb); return; } -@@ -7623,7 +7633,7 @@ err_vdev_del: +@@ -7622,7 +7632,7 @@ err_vdev_del: idr_for_each(&ar->txmgmt_idr, ath11k_mac_vif_txmgmt_idr_remove, vif); @@ -465,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]); @@ -490,15 +490,6 @@ Signed-off-by: P Praneesh if (len > size) --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c -@@ -105,7 +105,7 @@ static struct ath11k_hw_params ath11k_hw - .supports_regdb = false, - .fix_l1ss = true, - .credit_flow = false, -- .max_tx_ring = DP_TCL_NUM_RING_MAX, -+ .max_tx_ring = DP_TCL_NUM_RING_MAX + 1, - .hal_params = &ath11k_hw_hal_params_ipq8074, - .supports_dynamic_smps_6ghz = false, - .alloc_cacheable_memory = true, @@ -188,7 +188,6 @@ static struct ath11k_hw_params ath11k_hw .supports_regdb = false, .fix_l1ss = true, @@ -513,7 +504,6 @@ Signed-off-by: P Praneesh .support_fw_mac_sequence = 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, }, { .name = "qca6390 hw2.0", 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 index 1fa2d32aaa33cb..b31809f689548b 100644 --- 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 @@ -1014,7 +1014,7 @@ Signed-off-by: Vasanthakumar Thiagarajan +#endif --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h -@@ -1529,15 +1529,29 @@ struct htt_ppdu_stats_usr_cmn_array { +@@ -1453,15 +1453,29 @@ struct htt_ppdu_stats_usr_cmn_array { struct htt_tx_ppdu_stats_info tx_ppdu_info[]; } __packed; @@ -1046,7 +1046,7 @@ Signed-off-by: Vasanthakumar Thiagarajan #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 -@@ -1444,6 +1444,71 @@ static int ath11k_htt_tlv_ppdu_stats_par +@@ -1409,6 +1409,71 @@ static int ath11k_htt_tlv_ppdu_stats_par return 0; } @@ -1118,7 +1118,7 @@ Signed-off-by: Vasanthakumar Thiagarajan static void ath11k_update_per_peer_tx_stats(struct ath11k *ar, struct htt_ppdu_stats *ppdu_stats, u8 user) -@@ -1467,6 +1532,9 @@ ath11k_update_per_peer_tx_stats(struct a +@@ -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; @@ -1128,7 +1128,7 @@ Signed-off-by: Vasanthakumar Thiagarajan 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); -@@ -1600,6 +1668,8 @@ ath11k_update_per_peer_tx_stats(struct a +@@ -1565,6 +1633,8 @@ ath11k_update_per_peer_tx_stats(struct a ath11k_debugfs_sta_add_tx_stats(arsta, peer_stats, rate_idx); } @@ -1137,7 +1137,7 @@ Signed-off-by: Vasanthakumar Thiagarajan spin_unlock_bh(&ab->base_lock); rcu_read_unlock(); } -@@ -1720,6 +1790,69 @@ int ath11k_dp_htt_tlv_iter(struct ath11k +@@ -1685,6 +1755,69 @@ int ath11k_dp_htt_tlv_iter(struct ath11k return 0; } @@ -1207,7 +1207,7 @@ Signed-off-by: Vasanthakumar Thiagarajan static int ath11k_htt_pull_ppdu_stats(struct ath11k_base *ab, struct sk_buff *skb) { -@@ -1738,6 +1871,15 @@ static int ath11k_htt_pull_ppdu_stats(st +@@ -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; @@ -1223,7 +1223,7 @@ Signed-off-by: Vasanthakumar Thiagarajan rcu_read_lock(); ar = ath11k_mac_get_ar_by_pdev_id(ab, pdev_id); if (!ar) { -@@ -1805,6 +1947,12 @@ static int ath11k_htt_pull_ppdu_stats(st +@@ -1770,6 +1912,12 @@ static int ath11k_htt_pull_ppdu_stats(st } } @@ -1257,7 +1257,7 @@ Signed-off-by: Vasanthakumar Thiagarajan mutex_unlock(&ar->conf_mutex); } -@@ -9715,6 +9727,28 @@ err_fallback: +@@ -9714,6 +9726,28 @@ err_fallback: return 0; } @@ -1286,7 +1286,7 @@ Signed-off-by: Vasanthakumar Thiagarajan static const struct ieee80211_ops ath11k_ops = { .tx = ath11k_mac_op_tx, .wake_tx_queue = ieee80211_handle_wake_tx_queue, -@@ -9772,6 +9806,9 @@ static const struct ieee80211_ops ath11k +@@ -9771,6 +9805,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, @@ -1296,7 +1296,7 @@ Signed-off-by: Vasanthakumar Thiagarajan }; static void ath11k_mac_update_ch_list(struct ath11k *ar, -@@ -10232,6 +10269,8 @@ static int __ath11k_mac_register(struct +@@ -10231,6 +10268,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); 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 index 1d7cf5b0e7c585..cb4fba0a2ffdcd 100644 --- 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 @@ -23,7 +23,7 @@ Signed-off-by: Rameshkumar Sundaram --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -7644,8 +7644,10 @@ err_vdev_del: +@@ -7643,8 +7643,10 @@ err_vdev_del: kfree(arvif->vlan_keyid_map); ath11k_peer_cleanup(ar, arvif->vdev_id); diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 798ec1973c3fe3..d733219b38aa7f 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -1573,6 +1573,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/nss/ath11k/330-ath11k-sync-wds_ast_entry-updates.patch b/package/kernel/mac80211/patches/nss/ath11k/330-ath11k-sync-wds_ast_entry-updates.patch index 662e11697f4d9c..361c9064148acd 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/330-ath11k-sync-wds_ast_entry-updates.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/330-ath11k-sync-wds_ast_entry-updates.patch @@ -91,7 +91,7 @@ Signed-off-by: Rameshkumar Sundaram + struct work_struct wmi_ast_work; + struct list_head wmi_ast_list; - bool stats_disable; + bool stats_disable; /* must be last */ --- a/drivers/net/wireless/ath/ath11k/nss.c +++ b/drivers/net/wireless/ath/ath11k/nss.c diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 67781ea0ad2b6b..3c3e436c75ce41 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -58,7 +58,7 @@ Signed-off-by: Venkateswara Naralasetty 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 -@@ -10155,6 +10155,8 @@ static int __ath11k_mac_register(struct +@@ -10154,6 +10154,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 index 90adde1baf67db..752218e9b8ec26 100644 --- 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 @@ -16,7 +16,7 @@ Signed-off-by: Anilkumar Kolli --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -6124,12 +6124,23 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -5953,12 +5953,23 @@ int ath11k_dp_rx_process_mon_status(stru pmon->mon_ppdu_status = DP_PPDU_STATUS_START; } @@ -43,7 +43,7 @@ Signed-off-by: Anilkumar Kolli rcu_read_lock(); spin_lock_bh(&ab->base_lock); peer = ath11k_peer_find_by_id(ab, ppdu_info->peer_id); -@@ -6453,6 +6464,13 @@ static int ath11k_dp_full_mon_process_rx +@@ -6282,6 +6293,13 @@ static int ath11k_dp_full_mon_process_rx spin_lock_bh(&pmon->mon_lock); @@ -57,7 +57,7 @@ Signed-off-by: Anilkumar Kolli sw_mon_entries = &pmon->sw_mon_entries; rx_mon_stats = &pmon->rx_mon_stats; -@@ -6492,7 +6510,6 @@ static int ath11k_dp_full_mon_process_rx +@@ -6321,7 +6339,6 @@ static int ath11k_dp_full_mon_process_rx } rx_mon_stats->dest_ppdu_done++; @@ -65,7 +65,7 @@ Signed-off-by: Anilkumar Kolli pmon->buf_state = DP_MON_STATUS_LAG; pmon->mon_status_paddr = sw_mon_entries->mon_status_paddr; pmon->hold_mon_dst_ring = true; -@@ -6523,16 +6540,10 @@ reap_status_ring: +@@ -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) { diff --git a/package/kernel/mac80211/patches/nss/ath11k/336-ath11k-skip-status-ring-entry-processing.patch b/package/kernel/mac80211/patches/nss/ath11k/336-ath11k-skip-status-ring-entry-processing.patch index 8950e960467e67..0adf26c808aec6 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -3782,6 +3782,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) { -@@ -3795,6 +3835,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; -@@ -3814,8 +3855,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; -@@ -3846,18 +3886,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) { diff --git a/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch b/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch index 8e23cd99e747c6..f574597dceb969 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch @@ -46,7 +46,7 @@ Signed-off-by: Nagarajan Maran --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -431,8 +431,8 @@ int ath11k_dp_rxbufs_replenish(struct at +@@ -396,8 +396,8 @@ int ath11k_dp_rxbufs_replenish(struct at goto fail_free_skb; spin_lock_bh(&rx_ring->idr_lock); @@ -57,7 +57,7 @@ Signed-off-by: Nagarajan Maran spin_unlock_bh(&rx_ring->idr_lock); if (buf_id <= 0) goto fail_dma_unmap; -@@ -3263,6 +3263,16 @@ try_again: +@@ -3141,6 +3141,16 @@ try_again: while (likely(desc = (struct hal_reo_dest_ring *)ath11k_hal_srng_dst_get_next_entry(ab, srng))) { @@ -74,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, -@@ -3293,8 +3303,6 @@ try_again: +@@ -3171,8 +3181,6 @@ try_again: num_buffs_reaped[mac_id]++; diff --git a/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch b/package/kernel/mac80211/patches/nss/ath11k/359-ath11k-fix-tkip-encryption-traffic-failure.patch deleted file mode 100644 index fe231db61355ea..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -2671,7 +2671,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/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 index fd4f0938cdb83b..f909ba4a673f69 100644 --- 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 @@ -14,7 +14,7 @@ Signed-off-by: Ramya Gnanasekar --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h -@@ -1501,6 +1501,7 @@ struct htt_ppdu_stats_usr_cmpltn_cmn { +@@ -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 @@ -24,7 +24,7 @@ Signed-off-by: Ramya Gnanasekar u32 ppdu_id; --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -1323,7 +1323,7 @@ static int ath11k_htt_tlv_ppdu_stats_par +@@ -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; @@ -33,7 +33,7 @@ Signed-off-by: Ramya Gnanasekar ppdu_info = data; -@@ -1404,6 +1404,8 @@ static int ath11k_htt_tlv_ppdu_stats_par +@@ -1369,6 +1369,8 @@ static int ath11k_htt_tlv_ppdu_stats_par return -EINVAL; } @@ -42,7 +42,7 @@ Signed-off-by: Ramya Gnanasekar 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, -@@ -1415,6 +1417,7 @@ static int ath11k_htt_tlv_ppdu_stats_par +@@ -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)); diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index fd78090aebc0f0..8adb5448a1564c 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -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 -@@ -849,6 +849,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)); @@ -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/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch b/package/kernel/mac80211/patches/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch deleted file mode 100644 index 020df707b6e6a4..00000000000000 --- a/package/kernel/mac80211/patches/nss/ath11k/374-ath11k-fix-VLC-streaming-not-working-for-wan-to-wlan.patch +++ /dev/null @@ -1,44 +0,0 @@ -From c9bcb26f30a1b2e3434d851aea19200a6d757cca Mon Sep 17 00:00:00 2001 -From: Aaradhana Sahu -Date: Sat, 3 Jun 2023 18:33:54 +0530 -Subject: [PATCH] ath11k: fix VLC streaming not working for wan to wlan when - multicast to unicast flag enable - -Currently, additional two bytes after 802.11 header are seen on the air. -When per-packet encap mode is native wifi and vdev level encap mode is -eth mode, native wifi encap functionality is skipped. - -This leaves QoS header unremoved in the 802.11 header of the packet. When -sending the packet HW will also add (one more) QoS header. The additional -two bytes before LLC/SNAP header confuses the receiver and those packets -will get dropped at receiver. - -Fix this issue by removing QoS header (native wifi encap functionality) -for all the packets which will be enqueued to hw in native wifi mode. - -Signed-off-by: Aaradhana Sahu ---- - drivers/net/wireless/ath/ath11k/dp_tx.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/ath/ath11k/dp_tx.c -+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -@@ -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)) - is_diff_encap = true; - else - ath11k_dp_tx_encap_nwifi(skb); -@@ -247,7 +248,7 @@ tcl_ring_sel: - if ((!test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) && - !(info->control.flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && - !info->control.hw_key && ieee80211_has_protected(hdr->frame_control)) || -- (skb->protocol == cpu_to_be16(ETH_P_PAE) && is_diff_encap)) { -+ is_diff_encap) { - /* HW requirement is that metadata should always point to a - * 8-byte aligned address. So we add alignment pad to start of - * buffer. HTT Metadata should be ensured to be multiple of 8-bytes 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 index 1f81a8ef722598..510fbc2448cee7 100644 --- 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 @@ -13,7 +13,7 @@ Signed-off-by: Yuvasree Sivasankaran --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -10142,6 +10142,7 @@ static int __ath11k_mac_register(struct +@@ -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); diff --git a/package/kernel/mac80211/patches/nss/ath11k/457-wifi-ath11k-Avoid-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 index 55d8063a2403ca..c23b6cb3c858b4 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/457-wifi-ath11k-Avoid-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 -@@ -6261,7 +6261,9 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -6090,7 +6090,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))) { -@@ -6279,7 +6281,6 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -6108,7 +6110,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,7 +67,7 @@ Signed-off-by: Yuvasree Sivasankaran ppdu_info->peer_id = HAL_INVALID_PEERID; hal_status = ath11k_hal_rx_parse_mon_status(ab, ppdu_info, skb); -@@ -6307,6 +6308,7 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -6136,6 +6137,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); diff --git a/package/kernel/mac80211/patches/nss/ath11k/458-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 index 6399718268b0b1..88903faddfdbf6 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/458-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,13 +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 -@@ -222,7 +222,8 @@ 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) && -- skb->protocol == cpu_to_be16(ETH_P_PAE)) -+ (skb->protocol == cpu_to_be16(ETH_P_PAE) || -+ ieee80211_is_qos_nullfunc(hdr->frame_control))) +- if (arvif->vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) ++ if ((arvif->vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) && ++ 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/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 index b2912777fad5d0..b471fb326a5b48 100644 --- 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 @@ -26,7 +26,7 @@ Acked-by: Jeff Johnson --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -8222,7 +8222,6 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -8221,7 +8221,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; @@ -34,7 +34,7 @@ Acked-by: Jeff Johnson mutex_lock(&ar->conf_mutex); -@@ -8245,21 +8244,6 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -8244,21 +8243,6 @@ ath11k_mac_op_assign_vif_chanctx(struct goto out; } 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 index ea08ea8818155d..2fb2cdfd429b11 100644 --- 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 @@ -39,7 +39,7 @@ Acked-by: Jeff Johnson if (ret) { ath11k_warn(ab, "failed to delay vdev start: %d\n", ret); goto free_tx_stats; -@@ -8165,8 +8165,8 @@ unlock: +@@ -8164,8 +8164,8 @@ unlock: mutex_unlock(&ar->conf_mutex); } 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 index a2ff42ad9d194d..4d83d0f0ed9029 100644 --- 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 @@ -317,7 +317,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) -@@ -9740,6 +9462,281 @@ ath11k_mac_op_config_mesh_offload_path(s +@@ -9739,6 +9461,281 @@ ath11k_mac_op_config_mesh_offload_path(s } #endif 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 index aeaf65aaa0e73b..d1b462519c91e8 100644 --- 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 @@ -52,7 +52,7 @@ Acked-by: Jeff Johnson --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -7934,6 +7934,30 @@ static int ath11k_mac_start_vdev_delay(s +@@ -7933,6 +7933,30 @@ static int ath11k_mac_start_vdev_delay(s return 0; } @@ -83,7 +83,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -@@ -7978,15 +8002,17 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -7977,15 +8001,17 @@ ath11k_mac_op_assign_vif_chanctx(struct goto out; } @@ -109,7 +109,7 @@ Acked-by: Jeff Johnson if (arvif->vdev_type != WMI_VDEV_TYPE_MONITOR && test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags)) { -@@ -8026,8 +8052,6 @@ ath11k_mac_op_unassign_vif_chanctx(struc +@@ -8025,8 +8051,6 @@ ath11k_mac_op_unassign_vif_chanctx(struc "chanctx unassign ptr %p vdev_id %i\n", ctx, arvif->vdev_id); @@ -118,7 +118,7 @@ Acked-by: Jeff Johnson if (ab->hw_params.vdev_start_delay && arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { spin_lock_bh(&ab->base_lock); -@@ -8051,24 +8075,13 @@ ath11k_mac_op_unassign_vif_chanctx(struc +@@ -8050,24 +8074,13 @@ ath11k_mac_op_unassign_vif_chanctx(struc return; } @@ -149,7 +149,7 @@ Acked-by: Jeff Johnson } if (ab->hw_params.vdev_start_delay && -@@ -9556,6 +9569,46 @@ exit: +@@ -9555,6 +9568,46 @@ exit: return ret; } @@ -196,7 +196,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, -@@ -9591,31 +9644,15 @@ static int ath11k_mac_op_sta_state(struc +@@ -9590,31 +9643,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)) { @@ -233,7 +233,7 @@ Acked-by: Jeff Johnson 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); -@@ -9626,12 +9663,6 @@ static int ath11k_mac_op_sta_state(struc +@@ -9625,12 +9662,6 @@ static int ath11k_mac_op_sta_state(struc } spin_unlock_bh(&ar->ab->base_lock); mutex_unlock(&ar->ab->tbl_mtx_lock); @@ -246,7 +246,7 @@ Acked-by: Jeff Johnson } else if (old_state == IEEE80211_STA_AUTH && new_state == IEEE80211_STA_ASSOC && (vif->type == NL80211_IFTYPE_AP || -@@ -10203,6 +10234,8 @@ static int __ath11k_mac_register(struct +@@ -10202,6 +10233,8 @@ static int __ath11k_mac_register(struct wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); 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 index 06f5e62c7b103c..2362820dc9e838 100644 --- 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 @@ -40,7 +40,7 @@ ath11k-$(CPTCFG_ATH11K_THERMAL) += thermal.o --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c -@@ -1877,7 +1877,9 @@ int ath11k_debugfs_register(struct ath11 +@@ -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); @@ -120,7 +120,7 @@ &fops_peer_ps_state); --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -1758,8 +1758,10 @@ ath11k_update_per_peer_tx_stats(struct a +@@ -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; @@ -131,7 +131,7 @@ } usr_stats->rate_stats_updated = true; -@@ -2205,7 +2207,9 @@ void ath11k_dp_htt_htc_t2h_msg_handler(s +@@ -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: @@ -176,7 +176,7 @@ spin_unlock_bh(&ab->base_lock); --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -9813,7 +9813,7 @@ static const struct ieee80211_ops ath11k +@@ -9812,7 +9812,7 @@ static const struct ieee80211_ops ath11k .set_wakeup = ath11k_wow_op_set_wakeup, #endif diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 90% rename from package/kernel/mac80211/patches/nss/ath11k/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 7b7673953bd4fe..85562dc463a211 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -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; -@@ -1129,6 +1130,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 -@@ -648,7 +649,7 @@ enum htt_stats_internal_ppdu_frametype { +@@ -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 | * |-------------------------------------------------------------------| -@@ -662,6 +663,14 @@ enum htt_stats_internal_ppdu_frametype { +@@ -686,6 +691,14 @@ enum htt_stats_internal_ppdu_frametype { * |-------------------------------------------------------------------| * | tlv_filter_in_flags | * |-------------------------------------------------------------------| @@ -64,7 +64,7 @@ Signed-off-by: Ramya Gnanasekar * Where: * PS = pkt_swap * SS = status_swap -@@ -675,7 +684,10 @@ enum htt_stats_internal_ppdu_frametype { +@@ -699,7 +712,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 @@ -76,7 +76,7 @@ Signed-off-by: Ramya Gnanasekar * dword1 - b'0:16 - ring_buffer_size: size of buffers referenced by rx ring, * in byte units. * Valid only for HW_TO_SW_RING and SW_TO_HW_RING -@@ -704,6 +716,42 @@ enum htt_stats_internal_ppdu_frametype { +@@ -728,6 +744,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 @@ -119,7 +119,7 @@ Signed-off-by: Ramya Gnanasekar */ #define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) -@@ -711,8 +759,16 @@ enum htt_stats_internal_ppdu_frametype { +@@ -735,8 +787,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) @@ -136,7 +136,7 @@ Signed-off-by: Ramya Gnanasekar enum htt_rx_filter_tlv_flags { HTT_RX_FILTER_TLV_FLAGS_MPDU_START = BIT(0), -@@ -1016,6 +1072,14 @@ enum htt_rx_data_pkt_filter_tlv_flasg3 { +@@ -1040,6 +1100,14 @@ enum htt_rx_data_pkt_filter_tlv_flasg3 { HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER | \ HTT_RX_FILTER_TLV_FLAGS_ATTENTION) @@ -151,7 +151,7 @@ Signed-off-by: Ramya Gnanasekar struct htt_rx_ring_selection_cfg_cmd { u32 info0; u32 info1; -@@ -1024,6 +1088,10 @@ struct htt_rx_ring_selection_cfg_cmd { +@@ -1048,6 +1116,10 @@ struct htt_rx_ring_selection_cfg_cmd { u32 pkt_type_en_flags2; u32 pkt_type_en_flags3; u32 rx_filter_tlv; @@ -162,7 +162,7 @@ Signed-off-by: Ramya Gnanasekar } __packed; struct htt_rx_ring_tlv_filter { -@@ -1032,6 +1100,14 @@ struct htt_rx_ring_tlv_filter { +@@ -1056,6 +1128,14 @@ struct htt_rx_ring_tlv_filter { u32 pkt_filter_flags1; /* MGMT */ u32 pkt_filter_flags2; /* CTRL */ u32 pkt_filter_flags3; /* DATA */ @@ -179,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); } @@ -192,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); } @@ -228,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); -@@ -2134,6 +2169,49 @@ int ath11k_dp_rx_crypto_icv_len(struct a +@@ -2387,6 +2422,49 @@ int ath11k_dp_rx_crypto_icv_len(struct a return 0; } @@ -278,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, -@@ -2147,7 +2225,8 @@ static void ath11k_dp_rx_h_undecap_nwifi +@@ -2400,7 +2478,8 @@ static void ath11k_dp_rx_h_undecap_nwifi u8 da[ETH_ALEN]; u8 sa[ETH_ALEN]; u16 qos_ctl = 0; @@ -288,7 +288,7 @@ Signed-off-by: Ramya Gnanasekar /* copy SA & DA and pull decapped header */ hdr = (struct ieee80211_hdr *)msdu->data; -@@ -2156,7 +2235,7 @@ static void ath11k_dp_rx_h_undecap_nwifi +@@ -2409,7 +2488,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)); @@ -297,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 */ -@@ -2186,16 +2265,23 @@ static void ath11k_dp_rx_h_undecap_nwifi +@@ -2439,16 +2518,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); @@ -326,7 +326,7 @@ Signed-off-by: Ramya Gnanasekar memcpy(skb_push(msdu, IEEE80211_QOS_CTL_LEN), &qos_ctl, IEEE80211_QOS_CTL_LEN); -@@ -2311,6 +2397,20 @@ static void ath11k_dp_rx_h_undecap_eth(s +@@ -2564,6 +2650,20 @@ static void ath11k_dp_rx_h_undecap_eth(s u8 da[ETH_ALEN]; u8 sa[ETH_ALEN]; void *rfc1042; @@ -347,7 +347,7 @@ Signed-off-by: Ramya Gnanasekar rfc1042 = ath11k_dp_rx_h_find_rfc1042(ar, msdu, enctype); if (WARN_ON_ONCE(!rfc1042)) -@@ -2339,6 +2439,7 @@ static void ath11k_dp_rx_h_undecap_eth(s +@@ -2592,6 +2692,7 @@ static void ath11k_dp_rx_h_undecap_eth(s memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); @@ -355,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 */ -@@ -2357,6 +2458,7 @@ static void ath11k_dp_rx_h_undecap_snap( +@@ -2610,6 +2711,7 @@ static void ath11k_dp_rx_h_undecap_snap( size_t hdr_len; u8 l3_pad_bytes; struct hal_rx_desc *rx_desc; @@ -363,7 +363,7 @@ Signed-off-by: Ramya Gnanasekar /* Delivered decapped frame: * [amsdu header] <-- replaced with 802.11 hdr -@@ -2370,6 +2472,11 @@ static void ath11k_dp_rx_h_undecap_snap( +@@ -2623,6 +2725,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); @@ -375,7 +375,7 @@ Signed-off-by: Ramya Gnanasekar hdr = (struct ieee80211_hdr *)first_hdr; hdr_len = ieee80211_hdrlen(hdr->frame_control); -@@ -2766,6 +2873,20 @@ static int ath11k_dp_rx_process_msdu(str +@@ -3097,6 +3204,20 @@ static int ath11k_dp_rx_process_msdu(str goto free_out; } @@ -396,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); -@@ -2778,8 +2899,9 @@ static int ath11k_dp_rx_process_msdu(str +@@ -3109,8 +3230,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); @@ -408,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; -@@ -3649,6 +3771,7 @@ static int ath11k_dp_rx_h_verify_tkip_mi +@@ -4069,6 +4191,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); @@ -416,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; -@@ -3929,8 +4052,8 @@ static void ath11k_dp_rx_h_sort_frags(st +@@ -4349,8 +4472,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) { @@ -426,7 +426,7 @@ Signed-off-by: Ramya Gnanasekar u8 *ehdr; u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; -@@ -4160,8 +4283,9 @@ ath11k_dp_process_rx_err_buf(struct ath1 +@@ -4580,8 +4703,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); @@ -438,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); -@@ -4784,6 +4908,47 @@ void ath11k_dp_rx_pdev_free(struct ath11 +@@ -5206,6 +5330,47 @@ void ath11k_dp_rx_pdev_free(struct ath11 ath11k_dp_rxdma_pdev_buf_free(ar); } @@ -486,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; -@@ -4877,6 +5042,12 @@ config_refill_ring: +@@ -5299,6 +5464,12 @@ config_refill_ring: } } @@ -501,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 -@@ -1183,6 +1183,8 @@ int ath11k_dp_tx_htt_rx_filter_setup(str +@@ -1264,6 +1264,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)); @@ -510,7 +510,7 @@ Signed-off-by: Ramya Gnanasekar cmd->info1 = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE, rx_buf_size); -@@ -1192,6 +1194,26 @@ int ath11k_dp_tx_htt_rx_filter_setup(str +@@ -1273,6 +1275,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; @@ -537,7 +537,7 @@ Signed-off-by: Ramya Gnanasekar ret = ath11k_htc_send(&ab->htc, ab->dp.eid, skb); if (ret) goto err_free; -@@ -1270,6 +1292,7 @@ int ath11k_dp_tx_htt_monitor_mode_ring_c +@@ -1351,6 +1373,7 @@ int ath11k_dp_tx_htt_monitor_mode_ring_c } ring_id = dp->rxdma_mon_buf_ring.refill_buf_ring.ring_id; @@ -559,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); } @@ -698,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) { @@ -710,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) { @@ -722,11 +722,10 @@ Signed-off-by: Ramya Gnanasekar } static bool ath11k_hw_wcn6855_rx_desc_encrypt_valid(struct hal_rx_desc *desc) -@@ -929,6 +1047,98 @@ static u32 ath11k_hw_qcn9074_rx_desc_get - return FIELD_GET(HAL_RX_MPDU_INFO_INFO1_MPDU_LEN, - __le32_to_cpu(mpdu_info->u.qcn9074.info1)); +@@ -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) +{ @@ -817,11 +816,10 @@ Signed-off-by: Ramya Gnanasekar + 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]); +} -+ - 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, -@@ -1009,6 +1219,13 @@ const struct ath11k_hw_ops ipq6018_ops = + + 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, @@ -834,8 +832,8 @@ Signed-off-by: Ramya Gnanasekar + .rx_desc_get_crypto_header = ath11k_hw_ipq8074_rx_desc_get_crypto_hdr, }; - const struct ath11k_hw_ops qca6390_ops = { -@@ -1050,6 +1267,13 @@ const struct ath11k_hw_ops qca6390_ops = + const struct ath11k_hw_ops ipq6018_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, @@ -848,9 +846,9 @@ Signed-off-by: Ramya Gnanasekar + .rx_desc_get_crypto_header = ath11k_hw_ipq8074_rx_desc_get_crypto_hdr, }; - const struct ath11k_hw_ops qcn9074_ops = { -@@ -1132,6 +1356,13 @@ const struct ath11k_hw_ops wcn6855_ops = - .rx_desc_mpdu_start_addr2 = ath11k_hw_wcn6855_rx_desc_mpdu_start_addr2, + 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 @@ -862,18 +860,15 @@ Signed-off-by: Ramya Gnanasekar + .rx_desc_get_crypto_header = ath11k_hw_ipq8074_rx_desc_get_crypto_hdr, }; - const struct ath11k_hw_ops wcn6750_ops = { -@@ -1180,6 +1411,8 @@ const struct ath11k_hw_ops ipq5018_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, + 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, - .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, -@@ -1214,6 +1447,13 @@ const struct ath11k_hw_ops ipq5018_ops = - .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, +#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M @@ -885,7 +880,7 @@ Signed-off-by: Ramya Gnanasekar + .rx_desc_get_crypto_header = ath11k_hw_qcn9074_rx_desc_get_crypto_hdr, }; - #define ATH11K_TX_RING_MASK_0 BIT(0) + const struct ath11k_hw_ops wcn6855_ops = { --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -22,6 +22,11 @@ @@ -909,21 +904,20 @@ Signed-off-by: Ramya Gnanasekar #endif /* Num of peers for Single Radio mode */ -@@ -128,6 +135,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]; -@@ -285,7 +294,17 @@ 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); -+ u32 (*rx_desc_get_hal_mpdu_len) (struct hal_rx_mpdu_info *mpdu_info); + 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 @@ -939,7 +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 -@@ -6343,6 +6343,7 @@ static int ath11k_mac_config_mon_status_ +@@ -6455,6 +6455,7 @@ static int ath11k_mac_config_mon_status_ tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar); } @@ -1005,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 -@@ -2230,7 +2230,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/nss/ath11k/999-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 new file mode 100644 index 00000000000000..c95960f2de04bf --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/999-311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch @@ -0,0 +1,109 @@ +From 246e530a47d9adab9106fb6f2b92197cace17e53 Mon Sep 17 00:00:00 2001 +From: Seevalamuthu Mariappan +Date: Fri, 21 May 2021 14:16:22 +0530 +Subject: [PATCH] ath11k: configure nss radio priority during pdev_init + +pdev's priority value is read from dts. Get scheme_id +using pdev priority. Configure scheme_id during pdev_init. + +Signed-off-by: Seevalamuthu Mariappan +--- + drivers/net/wireless/ath/ath11k/nss.c | 20 +++++++++++++++++++- + drivers/net/wireless/ath/ath11k/nss.h | 3 +++ + 2 files changed, 22 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath11k/nss.c ++++ b/drivers/net/wireless/ath/ath11k/nss.c +@@ -2,6 +2,7 @@ + /* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + */ ++#include + + #include "debug.h" + #include "mac.h" +@@ -4342,6 +4343,7 @@ static int ath11k_nss_init(struct ath11k + nss_tx_status_t status; + struct ath11k_dp *dp; + int i, ret; ++ struct device *dev = ab->dev; + + dp = &ab->dp; + +@@ -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; ++ if (of_property_read_bool(dev->of_node, "nss-radio-priority")) ++ wim->flags |= WIFILI_MULTISOC_THREAD_MAP_ENABLE; + + /* fill hal srng message */ + wim->hssm.dev_base_addr = (u32)ab->mem_pa; +@@ -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; ++ struct device *dev = ab->dev; + int radio_if_num = -1; + int refill_ring_id; + int features = 0; + int dyn_if_type; +- int ret, i; ++ int ret, i, scheme_id = 0; ++ u32 nss_radio_priority; + + dyn_if_type = ath11k_nss_get_dynamic_interface_type(ab); + +@@ -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); + ++ if (!of_property_read_u32(dev->of_node, "nss-radio-priority", &nss_radio_priority)) { ++ scheme_id = nss_wifili_thread_scheme_alloc(ab->nss.ctx, ar->nss.if_num, nss_radio_priority); ++ if (scheme_id == WIFILI_SCHEME_ID_INVALID) { ++ ath11k_warn(ab, "received invalid scheme_id, configuring default value\n"); ++ scheme_id = 0; ++ } ++ } ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "ifnum: %d scheme_id: %d nss_radio_priority: %d\n", ar->nss.if_num, scheme_id, nss_radio_priority); ++ + wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); + if (!wlmsg) { + ret = -ENOMEM; +@@ -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; ++ pdevmsg->scheme_id = scheme_id; + + /* Store rxdma ring info to the message */ + refill_ring_id = ar->dp.rx_refill_buf_ring.refill_buf_ring.ring_id; +@@ -4887,6 +4903,9 @@ int ath11k_nss_pdev_deinit(struct ath11k + /* pdev deinit msg success, dealloc, deregister and return */ + ret = 0; + ++ /* reset thread scheme*/ ++ nss_wifili_thread_scheme_dealloc(ab->nss.ctx, ar->nss.if_num); ++ + nss_dynamic_interface_dealloc_node(ar->nss.if_num, dyn_if_type); + nss_unregister_wifili_radio_if(ar->nss.if_num); + free: +--- a/drivers/net/wireless/ath/ath11k/nss.h ++++ b/drivers/net/wireless/ath/ath11k/nss.h +@@ -70,6 +70,7 @@ struct hal_rx_user_status; + /* Init Flags */ + #define WIFILI_NSS_CCE_DISABLED 0x1 + #define WIFILI_ADDTL_MEM_SEG_SET 0x000000002 ++#define WIFILI_MULTISOC_THREAD_MAP_ENABLE 0x10 + + /* ATH11K NSS PEER Info */ + /* Host memory allocated for peer info storage in nss */ +@@ -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 ++ + enum ath11k_nss_opmode { + ATH11K_NSS_OPMODE_UNKNOWN, + ATH11K_NSS_OPMODE_AP, 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 00000000000000..1f554ae95ccc69 --- /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 +@@ -5994,6 +5994,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; +@@ -6001,6 +6002,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 +@@ -306,6 +306,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 00000000000000..499f720caba8cb --- /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 +@@ -3336,18 +3336,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); +@@ -4574,17 +4572,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), +@@ -5005,18 +5000,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); +@@ -5131,16 +5124,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, +@@ -6399,16 +6390,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 index c2cc4f2f89f43e..c5134fca93a867 100644 --- 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 @@ -130,25 +130,24 @@ Signed-off-by: Tamizh Chelvam srng = &ab->hal.srng_list[dp->reo_dst_ring[ring_id].ring_id]; -@@ -3383,8 +3405,16 @@ try_again: +@@ -3385,8 +3407,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_find(&rx_ring->bufs_idr, buf_id); +- 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); + spin_unlock_bh(&rx_ring->idr_lock); if (unlikely(!msdu)) { ath11k_warn(ab, "frame rx with invalid buf_id %d\n", - buf_id); -@@ -3464,9 +3494,12 @@ try_again: +@@ -3464,9 +3493,12 @@ try_again: rx_ring = &ar->dp.rx_refill_buf_ring; ath11k_dp_rxbufs_replenish(ab, i, rx_ring, num_buffs_reaped[i], @@ -190,7 +189,24 @@ Signed-off-by: Tamizh Chelvam srng = &ab->hal.srng_list[dp->rx_rel_ring.ring_id]; -@@ -5129,7 +5165,7 @@ int ath11k_dp_rx_process_wbm_err(struct +@@ -5077,9 +5112,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", +@@ -5124,7 +5165,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], diff --git a/package/kernel/mac80211/patches/nss/ath11k/999-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 new file mode 100644 index 00000000000000..b58b13eebe1d40 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/999-374-ath11k-Check-skb_headroom-before-using-skb_push.patch @@ -0,0 +1,253 @@ +From efecc6e8355d02aeac7bf1a43397551440a8d0d8 Mon Sep 17 00:00:00 2001 +From: Tamizh Chelvam Raja +Date: Thu, 30 Mar 2023 22:12:56 +0530 +Subject: [PATCH] ath11k: Check skb_headroom before using skb_push + +Below kernel panic may occur if there is no +skb_headroom available for performing skb_push. + +<4>[67506.565072] CPU: 1 PID: 1741 Comm: ap-wireless-opt Not tainted 5.4.89+ #0 +<4>[67506.578860] Hardware name: Generic DT based system +<4>[67506.585728] PC is at fortify_panic+0x10/0x18 +<4>[67506.590406] LR is at fortify_panic+0x10/0x18 + +(fortify_panic) from [<7f2cd3cc>] (ath11k_dp_rx_crypto_icv_len+0x1e0/0x161c [ath11k]) +(ath11k_dp_rx_crypto_icv_len [ath11k]) from [<7f2cdbac>] (ath11k_dp_rx_crypto_icv_len+0x9c0/0x161c [ath11k]) +(ath11k_dp_rx_crypto_icv_len [ath11k]) from [<7f2ce0e8>] (ath11k_dp_rx_crypto_icv_len+0xefc/0x161c [ath11k]) +(ath11k_dp_rx_crypto_icv_len [ath11k]) from [<7f2cedb0>] (ath11k_dp_process_rx+0x4ec/0x544 [ath11k]) +(ath11k_dp_process_rx [ath11k]) from [<7f2c417c>] (ath11k_dp_service_srng+0xdc/0x2a0 [ath11k]) +(ath11k_dp_service_srng [ath11k]) from [<7f0d78c8>] (ath11k_pci_ext_grp_napi_poll+0x20/0x50 [ath11k_pci]) +(ath11k_pci_ext_grp_napi_poll [ath11k_pci]) from [<806a6a74>] (__napi_poll+0x28/0xb8) +(__napi_poll) from [<806a6c9c>] (net_rx_action+0xec/0x280) +(net_rx_action) from [<8010226c>] (__do_softirq+0xc4/0x248) +(__do_softirq) from [<8011f230>] (irq_exit+0x6c/0xcc) +(irq_exit) from [<80162a08>] (__handle_domain_irq+0x8c/0xb0) +(__handle_domain_irq) from [<803f0188>] (gic_handle_irq+0x54/0x8c) +(gic_handle_irq) from [<80101a8c>] (__irq_svc+0x6c/0xa8) + +Fix this by checking skb_headroom and expand the +headroom if required size is not available. + +Signed-off-by: Tamizh Chelvam Raja +--- + drivers/net/wireless/ath/ath11k/dp_rx.c | 70 +++++++++++++++++++++++++ + 1 file changed, 70 insertions(+) + +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -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; ++ int expand_by; + u8 *crypto_hdr; + + if (!(status->flag & RX_FLAG_IV_STRIPPED)) { + crypto_len = ath11k_dp_rx_crypto_param_len(ar, enctype); ++ if (skb_headroom(msdu) < crypto_len) { ++ expand_by = crypto_len - skb_headroom(msdu); ++ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) ++ return; ++ } + crypto_hdr = skb_push(msdu, crypto_len); + ath11k_dp_rx_desc_get_crypto_header(ab, rx_desc, crypto_hdr, enctype); + } + + fc = ath11k_dp_rxdesc_get_mpdu_frame_ctrl(ab, rx_desc); + hdr_len = ieee80211_hdrlen(fc); ++ 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; ++ } + skb_push(msdu, hdr_len); + hdr = (struct ieee80211_hdr *)msdu->data; + hdr->frame_control = fc; +@@ -2499,6 +2510,7 @@ static void ath11k_dp_rx_h_undecap_nwifi + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + u16 qos_ctl = 0; ++ int expand_by = 0; + u8 *qos, *crypto_hdr; + bool add_qos_ctrl = false; + +@@ -2543,26 +2555,46 @@ static void ath11k_dp_rx_h_undecap_nwifi + } + + if (!(status->flag & RX_FLAG_IV_STRIPPED)) { ++ 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; ++ } + if (first_hdr) { +- memcpy(skb_push(msdu, +- ath11k_dp_rx_crypto_param_len(ar, enctype)), +- (void *)hdr + hdr_len, +- ath11k_dp_rx_crypto_param_len(ar, enctype)); ++ memcpy(skb_push(msdu, crypto_param_len), ++ (void *)hdr + hdr_len, crypto_param_len); + } else { +- crypto_hdr = skb_push(msdu, ath11k_dp_rx_crypto_param_len(ar, enctype)); ++ crypto_hdr = skb_push(msdu, crypto_param_len); + ath11k_dp_rx_desc_get_crypto_header(ar->ab, + rxcb->rx_desc, crypto_hdr, enctype); + } + } + + if (!rxcb->is_first_msdu || add_qos_ctrl) { ++ if (skb_headroom(msdu) < IEEE80211_QOS_CTL_LEN) { ++ expand_by = IEEE80211_QOS_CTL_LEN - skb_headroom(msdu); ++ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) ++ return; ++ } + memcpy(skb_push(msdu, + IEEE80211_QOS_CTL_LEN), &qos_ctl, + IEEE80211_QOS_CTL_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), decap_hdr, hdr_len); + return; + } + ++ 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); + + /* original 802.11 header has a different DA and in +@@ -2671,6 +2703,7 @@ static void ath11k_dp_rx_h_undecap_eth(s + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + void *rfc1042; ++ int expand_by; + struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); + struct ath11k_dp_rfc1042_hdr rfc = {0xaa, 0xaa, 0x03, {0x00, 0x00, 0x00}}; + +@@ -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)); ++ if (skb_headroom(msdu) < sizeof(struct ath11k_dp_rfc1042_hdr)) { ++ expand_by = sizeof(struct ath11k_dp_rfc1042_hdr) - skb_headroom(msdu); ++ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) ++ return; ++ } + 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); +@@ -2697,6 +2735,11 @@ static void ath11k_dp_rx_h_undecap_eth(s + skb_pull(msdu, sizeof(struct ethhdr)); + + /* push rfc1042/llc/snap */ ++ if (skb_headroom(msdu) < sizeof(struct ath11k_dp_rfc1042_hdr)) { ++ expand_by = sizeof(struct ath11k_dp_rfc1042_hdr) - skb_headroom(msdu); ++ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) ++ return; ++ } + memcpy(skb_push(msdu, sizeof(struct ath11k_dp_rfc1042_hdr)), rfc1042, + sizeof(struct ath11k_dp_rfc1042_hdr)); + +@@ -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)) { +- 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); + + exit: +@@ -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); + } + +@@ -2890,7 +2954,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; +@@ -3123,10 +3187,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; ++ int expand_by; + + if (status->encoding == RX_ENC_HE && + !(status->flag & RX_FLAG_RADIOTAP_HE) && + !(status->flag & RX_FLAG_SKIP_MONITOR)) { ++ if (skb_headroom(msdu) < sizeof(known)) { ++ expand_by = sizeof(known) - skb_headroom(msdu); ++ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) ++ goto exit; ++ } + he = skb_push(msdu, sizeof(known)); + memcpy(he, &known, sizeof(known)); + status->flag |= RX_FLAG_RADIOTAP_HE; +@@ -3182,6 +3252,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); + } + 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 00000000000000..cf712593cc15b8 --- /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/nss/subsys/199-001-mac80211-add-nss-support.patch b/package/kernel/mac80211/patches/nss/subsys/199-001-mac80211-add-nss-support.patch index 2943f6b04bad5c..fc8fec0660f352 100644 --- a/package/kernel/mac80211/patches/nss/subsys/199-001-mac80211-add-nss-support.patch +++ b/package/kernel/mac80211/patches/nss/subsys/199-001-mac80211-add-nss-support.patch @@ -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/nss/subsys/649-nl80211-Add-support-to-enable-disable-bss-color-coll.patch b/package/kernel/mac80211/patches/nss/subsys/649-nl80211-Add-support-to-enable-disable-bss-color-coll.patch deleted file mode 100644 index 058d983c8a15f6..00000000000000 --- a/package/kernel/mac80211/patches/nss/subsys/649-nl80211-Add-support-to-enable-disable-bss-color-coll.patch +++ /dev/null @@ -1,78 +0,0 @@ -From e4439779d28949a61228b359a27f399df9b42b1a Mon Sep 17 00:00:00 2001 -From: Rameshkumar Sundaram -Date: Mon, 25 Oct 2021 19:06:04 +0530 -Subject: [PATCH 1/2] nl80211: add support to enable/disable bss color - collision detection - -As per 802.11ax-2021, STAs shall process BSS Color Change Announcement -(BCCA) from AP and switch to new color, but some STAs aren't processing -BCCA from AP and not doing color switch, causing them to drop data -frames from AP post color change. - -Provide an option to disable color collision detection and therefore -not to do BCCA to mitigate the same from AP. If it's required in case -where STA supports BCCA handling, then it can enabled in AP using this -option. - -Signed-off-by: Rameshkumar Sundaram -Signed-off-by: Dinesh Karthikeyan ---- - include/net/cfg80211.h | 2 ++ - include/uapi/linux/nl80211.h | 3 +++ - net/wireless/nl80211.c | 3 +++ - 3 files changed, 8 insertions(+) - ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -312,11 +312,13 @@ struct ieee80211_he_obss_pd { - * @color: the current color. - * @enabled: HE BSS color is used - * @partial: define the AID equation. -+ * @collision_detection_enabled: HE BSS color collision detection is enabled. - */ - struct cfg80211_he_bss_color { - u8 color; - bool enabled; - bool partial; -+ bool collision_detection_enabled; - }; - - /** ---- a/include/uapi/linux/nl80211.h -+++ b/include/uapi/linux/nl80211.h -@@ -7566,6 +7566,8 @@ enum nl80211_obss_pd_attributes { - * @NL80211_HE_BSS_COLOR_ATTR_COLOR: the current BSS Color. - * @NL80211_HE_BSS_COLOR_ATTR_DISABLED: is BSS coloring disabled. - * @NL80211_HE_BSS_COLOR_ATTR_PARTIAL: the AID equation to be used.. -+ * @NL80211_HE_BSS_COLOR_ATTR_COLLISION_DETECTION_DISABLED: is BSS -+ * color collision detection disabled. - * - * @__NL80211_HE_BSS_COLOR_ATTR_LAST: Internal - * @NL80211_HE_BSS_COLOR_ATTR_MAX: highest BSS Color attribute. -@@ -7576,6 +7578,7 @@ enum nl80211_bss_color_attributes { - NL80211_HE_BSS_COLOR_ATTR_COLOR, - NL80211_HE_BSS_COLOR_ATTR_DISABLED, - NL80211_HE_BSS_COLOR_ATTR_PARTIAL, -+ NL80211_HE_BSS_COLOR_ATTR_COLLISION_DETECTION_DISABLED, - - /* keep last */ - __NL80211_HE_BSS_COLOR_ATTR_LAST, ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -378,6 +378,7 @@ he_bss_color_policy[NL80211_HE_BSS_COLOR - [NL80211_HE_BSS_COLOR_ATTR_COLOR] = NLA_POLICY_RANGE(NLA_U8, 1, 63), - [NL80211_HE_BSS_COLOR_ATTR_DISABLED] = { .type = NLA_FLAG }, - [NL80211_HE_BSS_COLOR_ATTR_PARTIAL] = { .type = NLA_FLAG }, -+ [NL80211_HE_BSS_COLOR_ATTR_COLLISION_DETECTION_DISABLED] = { .type = NLA_FLAG }, - }; - - static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = { -@@ -5495,6 +5496,8 @@ static int nl80211_parse_he_bss_color(st - !nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_DISABLED]); - he_bss_color->partial = - nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_PARTIAL]); -+ he_bss_color->collision_detection_enabled = -+ !nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_COLLISION_DETECTION_DISABLED]); - - return 0; - } diff --git a/package/kernel/mac80211/patches/nss/subsys/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch b/package/kernel/mac80211/patches/nss/subsys/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch deleted file mode 100644 index 8d8c3c68d58c91..00000000000000 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -4571,6 +4571,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; -@@ -4834,7 +4835,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/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 00000000000000..098767aa3f36db --- /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 +@@ -2396,7 +2396,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; +@@ -2409,8 +2409,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; +@@ -2480,7 +2485,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; +@@ -2680,7 +2685,7 @@ void sta_set_sinfo(struct sta_info *sta, + struct ieee80211_sta_rx_stats *last_rxstats; + struct link_sta_info *link_sta = NULL; + +- last_rxstats = sta_get_last_rx_stats(sta); ++ last_rxstats = sta_get_last_rx_stats(sta, false); + + sinfo->generation = sdata->local->sta_generation; + +@@ -2924,7 +2929,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/nss/subsys/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 index 6b5cf7f3e24660..50466d46c37880 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 @@ -67,15 +67,7 @@ Signed-off-by: Tamizh Chelvam Raja if (!skb) { len = 0; goto out; -@@ -4571,7 +4573,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; -@@ -4715,7 +4716,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4714,7 +4716,7 @@ static void ieee80211_8023_xmit(struct i } } @@ -84,27 +76,6 @@ Signed-off-by: Tamizh Chelvam Raja if (!skb) return; -@@ -4835,6 +4836,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 = {}; -@@ -4869,9 +4871,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 @@ -2267,6 +2267,10 @@ int ieee80211_if_add(struct ieee80211_lo diff --git a/target/linux/qualcommax/config-6.6 b/target/linux/qualcommax/config-6.6 index 71b54041c50e59..bbe5009473ae10 100644 --- a/target/linux/qualcommax/config-6.6 +++ b/target/linux/qualcommax/config-6.6 @@ -504,6 +504,11 @@ CONFIG_SERIAL_MSM=y CONFIG_SERIAL_MSM_CONSOLE=y CONFIG_SGL_ALLOC=y CONFIG_SG_POOL=y +# CONFIG_ALLOC_SKB_PAGE_FRAG_DISABLE is not set +# CONFIG_DEBUG_OBJECTS_SKBUFF is not set +CONFIG_SKB_RECYCLER=y +CONFIG_SKB_RECYCLER_MULTI_CPU=y +# CONFIG_SKB_FAST_RECYCLABLE_DEBUG_ENABLE is not set CONFIG_SMP=y # CONFIG_SM_CAMCC_6350 is not set # CONFIG_SM_CAMCC_8450 is not set diff --git a/target/linux/qualcommax/files/net/core/skbuff_debug.c b/target/linux/qualcommax/files/net/core/skbuff_debug.c new file mode 100644 index 00000000000000..50d06759210995 --- /dev/null +++ b/target/linux/qualcommax/files/net/core/skbuff_debug.c @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include "skbuff_debug.h" +#include "skbuff_notifier.h" +#include "skbuff_recycle.h" + +static int skbuff_debugobj_enabled __read_mostly = 1; + +static int skbuff_debug_event_handler(struct notifier_block *nb, + unsigned long action, void *data); +static struct notifier_block skbuff_debug_notify = { + .notifier_call = skbuff_debug_event_handler, + .priority = 0 +}; + +inline u32 skbuff_debugobj_sum(struct sk_buff *skb) +{ + int pos = offsetof(struct sk_buff, free_addr); + u32 sum = 0; + + while (pos--) + sum += ((u8 *)skb)[pos]; + + return sum; +} + +struct skbuff_debugobj_walking { + int pos; + void **d; +}; + +#ifdef CONFIG_ARM +static int skbuff_debugobj_walkstack(struct stackframe *frame, void *p) { + struct skbuff_debugobj_walking *w = (struct skbuff_debugobj_walking *)p; + unsigned long pc = frame->pc; + + if (w->pos < DEBUG_OBJECTS_SKBUFF_STACKSIZE - 1) { + w->d[w->pos++] = (void *)pc; + return 0; + } + + return -ENOENT; +} +#else +static bool skbuff_debugobj_walkstack(void *p, unsigned long pc) +{ + struct skbuff_debugobj_walking *w = (struct skbuff_debugobj_walking *)p; + + if (w->pos < DEBUG_OBJECTS_SKBUFF_STACKSIZE - 1) { + w->d[w->pos++] = (void *)pc; + return true; + } + + return false; +} +#endif + +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) +static void skbuff_debugobj_get_stack(void **ret) +{ + struct skbuff_debugobj_walking w = {0, ret}; + void *p = &w; + +#ifdef CONFIG_ARM + struct stackframe frame; + register unsigned long current_sp asm ("sp"); + + frame.lr = (unsigned long)__builtin_return_address(0); + frame.fp = (unsigned long)__builtin_frame_address(0); + frame.sp = current_sp; + frame.pc = (unsigned long)skbuff_debugobj_get_stack; + + walk_stackframe(&frame, skbuff_debugobj_walkstack, p); +#else + arch_stack_walk(skbuff_debugobj_walkstack, p, current, NULL); +#endif + + ret[w.pos] = NULL; +} +#else +#error +static void skbuff_debugobj_get_stack(void **ret) +{ + /* not supported */ + ret[0] = 0xdeadbeef; +} +#endif + +void skbuff_debugobj_print_stack(void *const *stack) +{ + int i; + + for (i = 0; stack[i]; i++) + pr_emerg("\t %pS (0x%p)\n", stack[i], stack[i]); +} + +static const char *skbuff_debugobj_state_name(const struct sk_buff *skb) +{ + int obj_state; + + obj_state = debug_object_get_state((struct sk_buff *)skb); + switch (obj_state) { + case ODEBUG_STATE_NONE: + return "none"; + case ODEBUG_STATE_INIT: + return "init"; + case ODEBUG_STATE_INACTIVE: + return "inactive"; + case ODEBUG_STATE_ACTIVE: + return "active"; + case ODEBUG_STATE_DESTROYED: + return "destroyed"; + case ODEBUG_STATE_NOTAVAILABLE: + return "not available"; + default: + return "invalid"; + } +} + +void skbuff_debugobj_print_skb(const struct sk_buff *skb) +{ + pr_emerg("skb_debug: current process = %s (pid %i)\n", + current->comm, current->pid); + pr_emerg("skb_debug: skb 0x%p, next 0x%p, prev 0x%p, state = %s\n", skb, + skb->next, skb->prev, skbuff_debugobj_state_name(skb)); + pr_emerg("skb_debug: free stack:\n"); + skbuff_debugobj_print_stack(skb->free_addr); + pr_emerg("skb_debug: alloc stack:\n"); + skbuff_debugobj_print_stack(skb->alloc_addr); +} +EXPORT_SYMBOL(skbuff_debugobj_print_skb); + +/* skbuff_debugobj_fixup(): + * Called when an error is detected in the state machine for + * the objects + */ +static bool skbuff_debugobj_fixup(void *addr, enum debug_obj_state state) +{ + struct sk_buff *skb = (struct sk_buff *)addr; + ftrace_dump(DUMP_ALL); + WARN(1, "skb_debug: state = %d, skb = 0x%p sum = %d (now %d)\n", + state, skb, skb->sum, skbuff_debugobj_sum(skb)); + skb_recycler_notifier_send_event(SKB_RECYCLER_NOTIFIER_FSM, skb); + + return true; +} + +static struct debug_obj_descr skbuff_debug_descr = { + .name = "sk_buff_struct", + .fixup_init = skbuff_debugobj_fixup, + .fixup_activate = skbuff_debugobj_fixup, + .fixup_destroy = skbuff_debugobj_fixup, + .fixup_free = skbuff_debugobj_fixup, +}; + +inline void skbuff_debugobj_activate(struct sk_buff *skb) +{ + int ret = 0; + + if (!skbuff_debugobj_enabled) + return; + + skbuff_debugobj_get_stack(skb->alloc_addr); + ret = debug_object_activate(skb, &skbuff_debug_descr); + if (ret) + goto err_act; + + skbuff_debugobj_sum_validate(skb); + + return; + +err_act: + ftrace_dump(DUMP_ALL); + WARN(1, "skb_debug: failed to activate err = %d skb = 0x%p sum = %d (now %d)\n", + ret, skb, skb->sum, skbuff_debugobj_sum(skb)); + skb_recycler_notifier_send_event(SKB_RECYCLER_NOTIFIER_DBLALLOC, skb); +} + +inline void skbuff_debugobj_init_and_activate(struct sk_buff *skb) +{ + if (!skbuff_debugobj_enabled) + return; + + /* if we're coming from the slab, the skb->sum might + * be invalid anyways + */ + skb->sum = skbuff_debugobj_sum(skb); + + debug_object_init(skb, &skbuff_debug_descr); + skbuff_debugobj_activate(skb); +} + +inline void skbuff_debugobj_deactivate(struct sk_buff *skb) +{ + int obj_state; + + if (!skbuff_debugobj_enabled) + return; + + skb->sum = skbuff_debugobj_sum(skb); + + obj_state = debug_object_get_state(skb); + + if (obj_state == ODEBUG_STATE_ACTIVE) { + debug_object_deactivate(skb, &skbuff_debug_descr); + skbuff_debugobj_get_stack(skb->free_addr); + return; + } + + ftrace_dump(DUMP_ALL); + WARN(1, "skb_debug: deactivating inactive object skb=0x%p state=%d sum = %d (now %d)\n", + skb, obj_state, skb->sum, skbuff_debugobj_sum(skb)); + skb_recycler_notifier_send_event(SKB_RECYCLER_NOTIFIER_DBLFREE, skb); +} + +inline void _skbuff_debugobj_sum_validate(struct sk_buff *skb, + const char *var, const char *src, + int line, const char *fxn) +{ + if (!skbuff_debugobj_enabled || !skb) + return; + + if (skb->sum == skbuff_debugobj_sum(skb)) + return; + + ftrace_dump(DUMP_ALL); + WARN(1, "skb_debug: skb sum changed skb = 0x%p sum = %d (now %d)\n", + skb, skb->sum, skbuff_debugobj_sum(skb)); + pr_emerg("skb_debug: %s() checking %s in %s:%d\n", fxn, var, src, line); + skb_recycler_notifier_send_event(SKB_RECYCLER_NOTIFIER_SUMERR, skb); +} + +inline void skbuff_debugobj_sum_update(struct sk_buff *skb) +{ + if (!skbuff_debugobj_enabled || !skb) + return; + + skb->sum = skbuff_debugobj_sum(skb); +} + +inline void skbuff_debugobj_destroy(struct sk_buff *skb) +{ + if (!skbuff_debugobj_enabled) + return; + + debug_object_destroy(skb, &skbuff_debug_descr); +} + +static int __init disable_object_debug(char *str) +{ + skbuff_debugobj_enabled = 0; + + pr_info("skb_debug: debug objects is disabled\n"); + return 0; +} + +early_param("no_skbuff_debug_objects", disable_object_debug); + +void skbuff_debugobj_print_skb_list(const struct sk_buff *skb_list, + const char *list_title, int cpu) +{ + int count; + struct sk_buff *skb_i = (struct sk_buff *)skb_list; + u32 sum_i, sum_now; + int obj_state; + + if (cpu < 0) { + cpu = get_cpu(); + put_cpu(); + } + pr_emerg("skb_debug: start skb list '%s' [CPU#%d]\n", list_title, cpu); + count = 0; + if (skb_list) { + do { + obj_state = + debug_object_get_state(skb_i); + if (obj_state < ODEBUG_STATE_NOTAVAILABLE) { + sum_i = skb_i->sum; + sum_now = skbuff_debugobj_sum(skb_i); + } else { + sum_i = 0; + sum_now = 0; + } + if (sum_i != sum_now) { + pr_emerg("skb_debug: [%02d] skb 0x%p, next 0x%p, prev 0x%p, state %d (%s), sum %d (now %d)\n", + count, skb_i, skb_i->next, skb_i->prev, + obj_state, skbuff_debugobj_state_name(skb_i), + sum_i, sum_now); + } + skb_i = skb_i->next; + count++; + } while (skb_list != skb_i); + } + pr_emerg("skb_debug: end skb list '%s'. In total %d skbs iterated.\n", list_title, count); +} + +void skbuff_debugobj_register_callback(void) +{ + skb_recycler_notifier_register(&skbuff_debug_notify); +} + +int skbuff_debug_event_handler(struct notifier_block *nb, unsigned long action, + void *data) +{ + struct sk_buff *skb = (struct sk_buff *)data; + + pr_emerg("skb_debug: notifier event %lu\n", action); + skbuff_debugobj_print_skb(skb); + skb_recycler_print_all_lists(); + + return NOTIFY_DONE; +} diff --git a/target/linux/qualcommax/files/net/core/skbuff_debug.h b/target/linux/qualcommax/files/net/core/skbuff_debug.h new file mode 100644 index 00000000000000..43e37ba43b645e --- /dev/null +++ b/target/linux/qualcommax/files/net/core/skbuff_debug.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#ifndef _LINUX_SKBBUFF_DEBUG_OBJECTS +#define _LINUX_SKBBUFF_DEBUG_OBJECTS + +#ifdef CONFIG_DEBUG_OBJECTS_SKBUFF +void skbuff_debugobj_init_and_activate(struct sk_buff *skb); +void skbuff_debugobj_activate(struct sk_buff *skb); +void skbuff_debugobj_deactivate(struct sk_buff *skb); +void skbuff_debugobj_destroy(struct sk_buff *skb); +#define skbuff_debugobj_sum_validate(skb) _skbuff_debugobj_sum_validate(skb, \ + #skb, __FILE__, __LINE__, __func__) +void _skbuff_debugobj_sum_validate(struct sk_buff *skb, const char *var, + const char *src, int line, const char *fxn); +void skbuff_debugobj_sum_update(struct sk_buff *skb); +void skbuff_debugobj_print_skb(const struct sk_buff *skb); + +void skbuff_debugobj_print_skb_list(const struct sk_buff *skb_list, + const char *list_title, int cpu); +void skbuff_debugobj_register_callback(void); + +#else +static inline void skbuff_debugobj_init_and_activate(struct sk_buff *skb) { } +static inline void skbuff_debugobj_activate(struct sk_buff *skb) { } +static inline void skbuff_debugobj_deactivate(struct sk_buff *skb) { } +static inline void skbuff_debugobj_destroy(struct sk_buff *skb) { } +static inline void skbuff_debugobj_sum_validate(struct sk_buff *skb) { } +static inline void skbuff_debugobj_sum_update(struct sk_buff *skb) { } +static inline void skbuff_debugobj_print_skb(const struct sk_buff *skb) { } + +static inline void skbuff_debugobj_print_skb_list + (const struct sk_buff *skb_list, const char *list_title, int cpu) { } +static inline void skbuff_debugobj_register_callback(void) { } +#endif + +#endif /* _LINUX_SKBBUFF_DEBUG_OBJECTS */ diff --git a/target/linux/qualcommax/files/net/core/skbuff_notifier.c b/target/linux/qualcommax/files/net/core/skbuff_notifier.c new file mode 100644 index 00000000000000..8c59476db7fe38 --- /dev/null +++ b/target/linux/qualcommax/files/net/core/skbuff_notifier.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* Notifier interface for the SKB Recycler */ + +#include "skbuff_notifier.h" + +static BLOCKING_NOTIFIER_HEAD(skb_recycler_notifier); + +int skb_recycler_notifier_register(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&skb_recycler_notifier, nb); +} +EXPORT_SYMBOL(skb_recycler_notifier_register); + +int skb_recycler_notifier_unregister(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&skb_recycler_notifier, nb); +} +EXPORT_SYMBOL(skb_recycler_notifier_unregister); + +int skb_recycler_notifier_send_event(unsigned long action, struct sk_buff *skb) +{ + int ret; + + ret = blocking_notifier_call_chain(&skb_recycler_notifier, action, skb); + + return 0; +} diff --git a/target/linux/qualcommax/files/net/core/skbuff_notifier.h b/target/linux/qualcommax/files/net/core/skbuff_notifier.h new file mode 100644 index 00000000000000..3d8bfa586fc94b --- /dev/null +++ b/target/linux/qualcommax/files/net/core/skbuff_notifier.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef SKBUFF_NOTIFIER_H +#define SKBUFF_NOTIFIER_H + +#include +#include + +/* notifier events */ +#define SKB_RECYCLER_NOTIFIER_SUMERR 0x0001 +#define SKB_RECYCLER_NOTIFIER_DBLFREE 0x0002 +#define SKB_RECYCLER_NOTIFIER_DBLALLOC 0x0004 +#define SKB_RECYCLER_NOTIFIER_FSM 0x0008 + +#if defined(CONFIG_DEBUG_OBJECTS_SKBUFF) +int skb_recycler_notifier_register(struct notifier_block *nb); +int skb_recycler_notifier_unregister(struct notifier_block *nb); +int skb_recycler_notifier_send_event(unsigned long action, + struct sk_buff *skb); +#else +static inline int skb_recycler_notifier_register(struct notifier_block *nb) +{ + return 0; +} + +static inline int skb_recycler_notifier_unregister(struct notifier_block *nb) +{ + return 0; +} + +static inline int skb_recycler_notifier_send_event(unsigned long action, + struct sk_buff *skb) +{ + return 1; +} +#endif /* CONFIG_DEBUG_OBJECTS_SKBUFF */ + +#endif /* SKBUFF_NOTIFIER_H */ diff --git a/target/linux/qualcommax/files/net/core/skbuff_recycle.c b/target/linux/qualcommax/files/net/core/skbuff_recycle.c new file mode 100644 index 00000000000000..41add8d3098fca --- /dev/null +++ b/target/linux/qualcommax/files/net/core/skbuff_recycle.c @@ -0,0 +1,729 @@ +/* + * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* Generic skb recycler */ + +#include "skbuff_recycle.h" +#include +#include + +#include "skbuff_debug.h" + +static struct proc_dir_entry *proc_net_skbrecycler; + +static DEFINE_PER_CPU(struct sk_buff_head, recycle_list); +static int skb_recycle_max_skbs = SKB_RECYCLE_MAX_SKBS; + +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU +static DEFINE_PER_CPU(struct sk_buff_head, recycle_spare_list); +static struct global_recycler glob_recycler; +static int skb_recycle_spare_max_skbs = SKB_RECYCLE_SPARE_MAX_SKBS; +#endif + +inline struct sk_buff *skb_recycler_alloc(struct net_device *dev, + unsigned int length) +{ + unsigned long flags; + struct sk_buff_head *h; + struct sk_buff *skb = NULL; + struct sk_buff *ln = NULL; + + if (unlikely(length > SKB_RECYCLE_SIZE)) + return NULL; + + h = &get_cpu_var(recycle_list); + local_irq_save(flags); + skb = skb_peek(h); + if (skb) { + ln = skb_peek_next(skb, h); + skbuff_debugobj_activate(skb); + /* Recalculate the sum for skb->next as next and prev pointers + * of skb->next will be updated in __skb_unlink + */ + skbuff_debugobj_sum_validate(ln); + __skb_unlink(skb, h); + skbuff_debugobj_sum_update(ln); + } +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + if (unlikely(!skb)) { + u8 head; + + spin_lock(&glob_recycler.lock); + /* If global recycle list is not empty, use global buffers */ + head = glob_recycler.head; + if (unlikely(head == glob_recycler.tail)) { + spin_unlock(&glob_recycler.lock); + } else { + struct sk_buff *gn = glob_recycler.pool[head].next; + struct sk_buff *gp = glob_recycler.pool[head].prev; + + /* Move SKBs from global list to CPU pool */ + skbuff_debugobj_sum_validate(gn); + skbuff_debugobj_sum_validate(gp); + skb_queue_splice_init(&glob_recycler.pool[head], h); + skbuff_debugobj_sum_update(gn); + skbuff_debugobj_sum_update(gp); + + head = (head + 1) & SKB_RECYCLE_MAX_SHARED_POOLS_MASK; + glob_recycler.head = head; + spin_unlock(&glob_recycler.lock); + /* We have refilled the CPU pool - dequeue */ + skb = skb_peek(h); + if (skb) { + /* Recalculate the sum for skb->next as next and + * prev pointers of skb->next will be updated + * in __skb_unlink + */ + ln = skb_peek_next(skb, h); + skbuff_debugobj_activate(skb); + skbuff_debugobj_sum_validate(ln); + __skb_unlink(skb, h); + skbuff_debugobj_sum_update(ln); + } + } + } +#endif + local_irq_restore(flags); + put_cpu_var(recycle_list); + + if (likely(skb)) { + struct skb_shared_info *shinfo; + + /* We're about to write a large amount to the skb to + * zero most of the structure so prefetch the start + * of the shinfo region now so it's in the D-cache + * before we start to write that. + */ + shinfo = skb_shinfo(skb); + prefetchw(shinfo); + + zero_struct(skb, offsetof(struct sk_buff, tail)); + refcount_set(&skb->users, 1); + skb->mac_header = (typeof(skb->mac_header))~0U; + skb->transport_header = (typeof(skb->transport_header))~0U; + zero_struct(shinfo, offsetof(struct skb_shared_info, dataref)); + atomic_set(&shinfo->dataref, 1); + + skb->data = skb->head + NET_SKB_PAD; + skb_reset_tail_pointer(skb); + + skb->dev = dev; + } + + return skb; +} + +inline bool skb_recycler_consume(struct sk_buff *skb) +{ + unsigned long flags; + struct sk_buff_head *h; + struct sk_buff *ln = NULL; + /* Can we recycle this skb? If not, simply return that we cannot */ + if (unlikely(!consume_skb_can_recycle(skb, SKB_RECYCLE_MIN_SIZE, + SKB_RECYCLE_MAX_SIZE))) + return false; + + /* If we can, then it will be much faster for us to recycle this one + * later than to allocate a new one from scratch. + */ + h = &get_cpu_var(recycle_list); + local_irq_save(flags); + /* Attempt to enqueue the CPU hot recycle list first */ + if (likely(skb_queue_len(h) < skb_recycle_max_skbs)) { + ln = skb_peek(h); + /* Recalculate the sum for peek of list as next and prev + * pointers of skb->next will be updated in __skb_queue_head + */ + skbuff_debugobj_sum_validate(ln); + __skb_queue_head(h, skb); + skbuff_debugobj_deactivate(skb); + skbuff_debugobj_sum_update(ln); + local_irq_restore(flags); + preempt_enable(); + return true; + } +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + h = this_cpu_ptr(&recycle_spare_list); + + /* The CPU hot recycle list was full; if the spare list is also full, + * attempt to move the spare list to the global list for other CPUs to + * use. + */ + if (unlikely(skb_queue_len(h) >= skb_recycle_spare_max_skbs)) { + u8 cur_tail, next_tail; + + spin_lock(&glob_recycler.lock); + cur_tail = glob_recycler.tail; + next_tail = (cur_tail + 1) & SKB_RECYCLE_MAX_SHARED_POOLS_MASK; + if (next_tail != glob_recycler.head) { + struct sk_buff_head *p = &glob_recycler.pool[cur_tail]; + struct sk_buff *hn = h->next, *hp = h->prev; + + /* Move SKBs from CPU pool to Global pool*/ + skbuff_debugobj_sum_validate(hp); + skbuff_debugobj_sum_validate(hn); + skb_queue_splice_init(h, p); + skbuff_debugobj_sum_update(hp); + skbuff_debugobj_sum_update(hn); + + /* Done with global list init */ + glob_recycler.tail = next_tail; + spin_unlock(&glob_recycler.lock); + + /* Recalculate the sum for peek of list as next and prev + * pointers of skb->next will be updated in + * __skb_queue_head + */ + ln = skb_peek(h); + skbuff_debugobj_sum_validate(ln); + /* We have now cleared room in the spare; + * Initialize and enqueue skb into spare + */ + __skb_queue_head(h, skb); + skbuff_debugobj_sum_update(ln); + skbuff_debugobj_deactivate(skb); + + local_irq_restore(flags); + preempt_enable(); + return true; + } + /* We still have a full spare because the global is also full */ + spin_unlock(&glob_recycler.lock); + } else { + /* We have room in the spare list; enqueue to spare list */ + ln = skb_peek(h); + /* Recalculate the sum for peek of list as next and prev + * pointers of skb->next will be updated in __skb_queue_head + */ + skbuff_debugobj_sum_validate(ln); + __skb_queue_head(h, skb); + skbuff_debugobj_deactivate(skb); + skbuff_debugobj_sum_update(ln); + local_irq_restore(flags); + preempt_enable(); + return true; + } +#endif + + local_irq_restore(flags); + preempt_enable(); + + return false; +} + +/** + * skb_recycler_consume_list_fast - free a list of skbs + * @skb_list: head of the buffer list + * + * Add the list of given SKBs to CPU list. Assumption is that these buffers + * have been allocated originally from recycler and have been transmitted through + * a controlled fast xmit path, thus removing the need for additional checks + * before recycling the buffers back to pool + */ +#ifdef CONFIG_DEBUG_OBJECTS_SKBUFF +inline bool skb_recycler_consume_list_fast(struct sk_buff_head *skb_list) +{ + struct sk_buff *skb = NULL, *next = NULL; + + skb_queue_walk_safe(skb_list, skb, next) { + if (skb) { + __skb_unlink(skb, skb_list); + skb_recycler_consume(skb); + } + } + + return true; +} +#else +inline bool skb_recycler_consume_list_fast(struct sk_buff_head *skb_list) +{ + unsigned long flags; + struct sk_buff_head *h; + + h = &get_cpu_var(recycle_list); + local_irq_save(flags); + /* Attempt to enqueue the CPU hot recycle list first */ + if (likely(skb_queue_len(h) < skb_recycle_max_skbs)) { + skb_queue_splice(skb_list,h); + local_irq_restore(flags); + preempt_enable(); + return true; + } + + local_irq_restore(flags); + preempt_enable(); + + return false; +} +#endif + +static void skb_recycler_free_skb(struct sk_buff_head *list) +{ + struct sk_buff *skb = NULL, *next = NULL; + unsigned long flags; + + spin_lock_irqsave(&list->lock, flags); + while ((skb = skb_peek(list)) != NULL) { + skbuff_debugobj_activate(skb); + next = skb->next; + __skb_unlink(skb, list); + skb_release_data(skb); + kfree_skbmem(skb); + /* + * Update the skb->sum for next due to skb_link operation + */ + if (next) { + skbuff_debugobj_sum_update(next); + } + } + spin_unlock_irqrestore(&list->lock, flags); +} + +static int skb_cpu_callback(unsigned int ocpu) +{ + unsigned long oldcpu = (unsigned long)ocpu; + + skb_recycler_free_skb(&per_cpu(recycle_list, oldcpu)); +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + spin_lock(&glob_recycler.lock); + skb_recycler_free_skb(&per_cpu(recycle_spare_list, oldcpu)); + spin_unlock(&glob_recycler.lock); +#endif + + return NOTIFY_DONE; +} + +#ifdef CONFIG_SKB_RECYCLER_PREALLOC +static int __init skb_prealloc_init_list(void) +{ + int i; + struct sk_buff *skb; + + for (i = 0; i < SKB_RECYCLE_MAX_PREALLOC_SKBS; i++) { + skb = __alloc_skb(SKB_RECYCLE_MAX_SIZE + NET_SKB_PAD, + GFP_KERNEL, 0, NUMA_NO_NODE); + if (unlikely(!skb)) + return -ENOMEM; + + skb_reserve(skb, NET_SKB_PAD); + + skb_recycler_consume(skb); + } + return 0; +} +#endif + +/* procfs: count + * Show skb counts + */ +static int proc_skb_count_show(struct seq_file *seq, void *v) +{ + int cpu; + int len; + int total; +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + unsigned int i; + unsigned long flags; +#endif + + total = 0; + + for_each_online_cpu(cpu) { + len = skb_queue_len(&per_cpu(recycle_list, cpu)); + seq_printf(seq, "recycle_list[%d]: %d\n", cpu, len); + total += len; + } + +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + for_each_online_cpu(cpu) { + len = skb_queue_len(&per_cpu(recycle_spare_list, cpu)); + seq_printf(seq, "recycle_spare_list[%d]: %d\n", cpu, len); + total += len; + } + + for (i = 0; i < SKB_RECYCLE_MAX_SHARED_POOLS; i++) { + spin_lock_irqsave(&glob_recycler.lock, flags); + len = skb_queue_len(&glob_recycler.pool[i]); + spin_unlock_irqrestore(&glob_recycler.lock, flags); + seq_printf(seq, "global_list[%d]: %d\n", i, len); + total += len; + } +#endif + + seq_printf(seq, "total: %d\n", total); + return 0; +} + +static int proc_skb_count_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_skb_count_show, pde_data(inode)); +} + +static const struct proc_ops proc_skb_count_fops = { + .proc_open = proc_skb_count_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_release = single_release, +}; + +/* procfs: flush + * Flush skbs + */ +static void skb_recycler_flush_task(struct work_struct *work) +{ + unsigned long flags; + struct sk_buff_head *h; + struct sk_buff_head tmp; + struct sk_buff *skb = NULL; + + skb_queue_head_init(&tmp); + + h = &get_cpu_var(recycle_list); + local_irq_save(flags); + skb_queue_splice_init(h, &tmp); + /* + * Update the sum for first skb present in tmp list. + * Since the skb is changed in splice init + */ + skb = skb_peek(&tmp); + skbuff_debugobj_sum_update(skb); + local_irq_restore(flags); + put_cpu_var(recycle_list); + skb_recycler_free_skb(&tmp); + +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + h = &get_cpu_var(recycle_spare_list); + local_irq_save(flags); + skb_queue_splice_init(h, &tmp); + skb = skb_peek(&tmp); + skbuff_debugobj_sum_update(skb); + local_irq_restore(flags); + put_cpu_var(recycle_spare_list); + skb_recycler_free_skb(&tmp); +#endif +} + +static ssize_t proc_skb_flush_write(struct file *file, + const char __user *buf, + size_t count, + loff_t *ppos) +{ +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + unsigned int i; + unsigned long flags; +#endif + schedule_on_each_cpu(&skb_recycler_flush_task); + +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + spin_lock_irqsave(&glob_recycler.lock, flags); + for (i = 0; i < SKB_RECYCLE_MAX_SHARED_POOLS; i++) + skb_recycler_free_skb(&glob_recycler.pool[i]); + glob_recycler.head = 0; + glob_recycler.tail = 0; + spin_unlock_irqrestore(&glob_recycler.lock, flags); +#endif + return count; +} + +static const struct proc_ops proc_skb_flush_fops = { + .proc_write = proc_skb_flush_write, + .proc_open = simple_open, + .proc_lseek = noop_llseek, +}; + +/* procfs: max_skbs + * Show max skbs + */ +static int proc_skb_max_skbs_show(struct seq_file *seq, void *v) +{ + seq_printf(seq, "%d\n", skb_recycle_max_skbs); + return 0; +} + +static int proc_skb_max_skbs_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_skb_max_skbs_show, pde_data(inode)); +} + +static ssize_t proc_skb_max_skbs_write(struct file *file, + const char __user *buf, + size_t count, + loff_t *ppos) +{ + int ret; + int max; + char buffer[13]; + + memset(buffer, 0, sizeof(buffer)); + if (count > sizeof(buffer) - 1) + count = sizeof(buffer) - 1; + if (copy_from_user(buffer, buf, count) != 0) + return -EFAULT; + ret = kstrtoint(strstrip(buffer), 10, &max); + if (ret == 0 && max >= 0) + skb_recycle_max_skbs = max; + + return count; +} + +static const struct proc_ops proc_skb_max_skbs_fops = { + .proc_open = proc_skb_max_skbs_open, + .proc_read = seq_read, + .proc_write = proc_skb_max_skbs_write, + .proc_release = single_release, +}; + +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU +/* procfs: max_spare_skbs + * Show max spare skbs + */ +static int proc_skb_max_spare_skbs_show(struct seq_file *seq, void *v) +{ + seq_printf(seq, "%d\n", skb_recycle_spare_max_skbs); + return 0; +} + +static int proc_skb_max_spare_skbs_open(struct inode *inode, struct file *file) +{ + return single_open(file, + proc_skb_max_spare_skbs_show, + pde_data(inode)); +} + +static ssize_t +proc_skb_max_spare_skbs_write(struct file *file, + const char __user *buf, + size_t count, + loff_t *ppos) +{ + int ret; + int max; + char buffer[13]; + + memset(buffer, 0, sizeof(buffer)); + if (count > sizeof(buffer) - 1) + count = sizeof(buffer) - 1; + if (copy_from_user(buffer, buf, count) != 0) + return -EFAULT; + ret = kstrtoint(strstrip(buffer), 10, &max); + if (ret == 0 && max >= 0) + skb_recycle_spare_max_skbs = max; + + return count; +} + +static const struct proc_ops proc_skb_max_spare_skbs_fops = { + .proc_open = proc_skb_max_spare_skbs_open, + .proc_read = seq_read, + .proc_write = proc_skb_max_spare_skbs_write, + .proc_release = single_release, +}; +#endif /* CONFIG_SKB_RECYCLER_MULTI_CPU */ + +static void skb_recycler_init_procfs(void) +{ + proc_net_skbrecycler = proc_mkdir("skb_recycler", init_net.proc_net); + if (!proc_net_skbrecycler) { + pr_err("cannot create skb_recycle proc dir"); + return; + } + + if (!proc_create("count", + S_IRUGO, + proc_net_skbrecycler, + &proc_skb_count_fops)) + pr_err("cannot create proc net skb_recycle held\n"); + + if (!proc_create("flush", + S_IWUGO, + proc_net_skbrecycler, + &proc_skb_flush_fops)) + pr_err("cannot create proc net skb_recycle flush\n"); + + if (!proc_create("max_skbs", + S_IRUGO | S_IWUGO, + proc_net_skbrecycler, + &proc_skb_max_skbs_fops)) + pr_err("cannot create proc net skb_recycle max_skbs\n"); + +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + if (!proc_create("max_spare_skbs", + S_IRUGO | S_IWUGO, + proc_net_skbrecycler, + &proc_skb_max_spare_skbs_fops)) + pr_err("cannot create proc net skb_recycle max_spare_skbs\n"); +#endif +} + +void __init skb_recycler_init(void) +{ + int cpu; +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + unsigned int i; +#endif + + for_each_possible_cpu(cpu) { + skb_queue_head_init(&per_cpu(recycle_list, cpu)); + } + +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + for_each_possible_cpu(cpu) { + skb_queue_head_init(&per_cpu(recycle_spare_list, cpu)); + } + + spin_lock_init(&glob_recycler.lock); + + for (i = 0; i < SKB_RECYCLE_MAX_SHARED_POOLS; i++) + skb_queue_head_init(&glob_recycler.pool[i]); + glob_recycler.head = 0; + glob_recycler.tail = 0; +#endif + +#ifdef CONFIG_SKB_RECYCLER_PREALLOC + if (skb_prealloc_init_list()) + pr_err("Failed to preallocate SKBs for recycle list\n"); +#endif + cpuhp_setup_state_nocalls(CPUHP_SKB_RECYCLER_DEAD, "net/skbuff_recycler:dead:",NULL, skb_cpu_callback); + skbuff_debugobj_register_callback(); + skb_recycler_init_procfs(); +} + +void skb_recycler_print_all_lists(void) +{ + unsigned long flags; + int cpu; +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU + int i; + struct sk_buff_head *h; + + cpu = get_cpu(); + spin_lock_irqsave(&glob_recycler.lock, flags); + for (i = 0; i < SKB_RECYCLE_MAX_SHARED_POOLS; i++) + skbuff_debugobj_print_skb_list((&glob_recycler.pool[i])->next, + "Global Pool", -1); + spin_unlock_irqrestore(&glob_recycler.lock, flags); + + preempt_disable(); + local_irq_save(flags); + + h = &per_cpu(recycle_spare_list, cpu); + skbuff_debugobj_print_skb_list(h->next, "Recycle Spare", cpu); + + local_irq_restore(flags); + preempt_enable(); +#endif + + preempt_disable(); + local_irq_save(flags); + h = &per_cpu(recycle_list, cpu); + skbuff_debugobj_print_skb_list(h->next, "Recycle List", cpu); + + local_irq_restore(flags); + preempt_enable(); +} + +#ifdef SKB_FAST_RECYCLABLE_DEBUG_ENABLE +/** + * consume_skb_can_fast_recycle_debug - Debug API to flag any sanity check + * failures on a fast recycled skb + * @skb: buffer to be checked + * @min_skb_size: minimum skb size allowed + * @max_skb_size: maximum skb size allowed + * + * Returns false with warning message if any of the checks fail + */ +static inline bool consume_skb_can_fast_recycle_debug(const struct sk_buff *skb, + int min_skb_size, int max_skb_size) +{ + if (unlikely(irqs_disabled())) { + WARN(1, "skb_debug: irqs_disabled for skb = 0x%p \n", skb); + return false; + } + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY)) { + WARN(1, "skb_debug: ZEROCOPY flag set for skb = 0x%p \n", skb); + return false; + } + if (unlikely(skb_is_nonlinear(skb))) { + WARN(1, "skb_debug: non-linear skb = 0x%p \n", skb); + return false; + } + if (unlikely(skb_shinfo(skb)->frag_list)) { + WARN(1, "skb_debug: set frag_list for skb = 0x%p \n", skb); + return false; + } + if (unlikely(skb_shinfo(skb)->nr_frags)) { + WARN(1, "skb_debug: set nr_frags for skb = 0x%p \n", skb); + return false; + } + if (unlikely(skb->fclone != SKB_FCLONE_UNAVAILABLE)) { + WARN(1, "skb_debug: FCLONE available for skb = 0x%p \n", skb); + return false; + } + min_skb_size = SKB_DATA_ALIGN(min_skb_size + NET_SKB_PAD); + if (unlikely(skb_end_pointer(skb) - skb->head < min_skb_size)) { + WARN(1, "skb_debug: invalid min size for skb = 0x%p \n", skb); + return false; + } + max_skb_size = SKB_DATA_ALIGN(max_skb_size + NET_SKB_PAD); + if (unlikely(skb_end_pointer(skb) - skb->head > max_skb_size)) { + WARN(1, "skb_debug: invalid max size for skb = 0x%p \n", skb); + return false; + } + if (unlikely(skb_cloned(skb))) { + WARN(1, "skb_debug: cloned skb = 0x%p \n", skb); + return false; + } + if (unlikely(skb_pfmemalloc(skb))) { + WARN(1, "skb_debug: enabled pfmemalloc for skb = 0x%p \n", skb); + return false; + } + if (skb->_skb_refdst) { + WARN(1, "skb_debug: _skb_refdst flag enabled = 0x%p \n", skb); + return false; + } + if (skb->destructor) { + WARN(1, "skb_debug: destructor flag enabled = 0x%p \n", skb); + return false; + } + if (skb->active_extensions) { + WARN(1, "skb_debug: active_extensions flag enabled = 0x%p \n", + skb); + return false; + } +#if IS_ENABLED(CONFIG_NF_CONNTRACK) + if (skb->_nfct & NFCT_PTRMASK) { + WARN(1, "skb_debug: nfctinfo bits set for skb = 0x%p \n", skb); + return false; + } +#endif + return true; +} + +/** + * check_skb_fast_recyclable - Debug API to flag any sanity check failures + * on a fast recycled skb + * @skb: buffer to be checked + * + * Checks skb recyclability + */ +void check_skb_fast_recyclable(struct sk_buff *skb) +{ + bool check = true; + check = consume_skb_can_fast_recycle_debug(skb, SKB_RECYCLE_MIN_SIZE, SKB_RECYCLE_MAX_SIZE); + if (!check) + BUG_ON(1); +} +EXPORT_SYMBOL(check_skb_fast_recyclable); +#endif diff --git a/target/linux/qualcommax/files/net/core/skbuff_recycle.h b/target/linux/qualcommax/files/net/core/skbuff_recycle.h new file mode 100644 index 00000000000000..cbbc3ee1f0d6ee --- /dev/null +++ b/target/linux/qualcommax/files/net/core/skbuff_recycle.h @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. + * + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ +/* Definitions for the skb recycler functions */ + +#ifndef _LINUX_SKBUFF_RECYCLE_H +#define _LINUX_SKBUFF_RECYCLE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_NET_CLS_ACT +#include +#endif +#include +#include +#include +#include +#include +#include + +#define SKB_RECYCLE_SIZE 2304 +#define SKB_RECYCLE_MIN_SIZE SKB_RECYCLE_SIZE +#define SKB_RECYCLE_MAX_SIZE SKB_RECYCLE_SIZE +#define SKB_RECYCLE_MAX_SKBS 1024 + +#define SKB_RECYCLE_SPARE_MAX_SKBS 256 + +#ifdef CONFIG_SKB_RECYCLER_PREALLOC +#define SKB_RECYCLE_MAX_PREALLOC_SKBS CONFIG_SKB_RECYCLE_MAX_PREALLOC_SKBS +#define SKB_RECYCLE_MAX_SHARED_POOLS \ + DIV_ROUND_UP(SKB_RECYCLE_MAX_PREALLOC_SKBS, \ + SKB_RECYCLE_SPARE_MAX_SKBS) +#else +#define SKB_RECYCLE_MAX_SHARED_POOLS 8 +#endif + +#define SKB_RECYCLE_MAX_SHARED_POOLS_MASK \ + (SKB_RECYCLE_MAX_SHARED_POOLS - 1) + +#ifdef CONFIG_SKB_RECYCLER_MULTI_CPU +struct global_recycler { + /* Global circular list which holds the shared skb pools */ + struct sk_buff_head pool[SKB_RECYCLE_MAX_SHARED_POOLS]; + u8 head; /* head of the circular list */ + u8 tail; /* tail of the circular list */ + spinlock_t lock; +}; +#endif + +static __always_inline void zero_struct(void *v, int size) +{ + u32 *s = (u32 *)v; + + /* We assume that size is word aligned; in fact, it's constant */ + WARN_ON((size & 3) != 0); + + /* This looks odd but we "know" size is a constant, and so the + * compiler can fold away all of the conditionals. The compiler is + * pretty smart here, and can fold away the loop, too! + */ + while (size > 0) { + if (size >= 4) + s[0] = 0; + if (size >= 8) + s[1] = 0; + if (size >= 12) + s[2] = 0; + if (size >= 16) + s[3] = 0; + if (size >= 20) + s[4] = 0; + if (size >= 24) + s[5] = 0; + if (size >= 28) + s[6] = 0; + if (size >= 32) + s[7] = 0; + if (size >= 36) + s[8] = 0; + if (size >= 40) + s[9] = 0; + if (size >= 44) + s[10] = 0; + if (size >= 48) + s[11] = 0; + if (size >= 52) + s[12] = 0; + if (size >= 56) + s[13] = 0; + if (size >= 60) + s[14] = 0; + if (size >= 64) + s[15] = 0; + size -= 64; + s += 16; + } +} + +static inline bool consume_skb_can_recycle(const struct sk_buff *skb, + int min_skb_size, int max_skb_size) +{ + if (unlikely(irqs_disabled())) + return false; + + if (unlikely(skb_shinfo(skb)->tx_flags & SKBFL_ZEROCOPY_ENABLE)) + return false; + + if (unlikely(skb->head_frag)) + return false; + + if (unlikely(skb_is_nonlinear(skb))) + return false; + + if (unlikely(skb_shinfo(skb)->frag_list)) + return false; + + if (unlikely(skb_shinfo(skb)->nr_frags)) + return false; + + if (unlikely(skb->fclone != SKB_FCLONE_UNAVAILABLE)) + return false; + + min_skb_size = SKB_DATA_ALIGN(min_skb_size + NET_SKB_PAD); + if (unlikely(skb_end_pointer(skb) - skb->head < min_skb_size)) + return false; + + max_skb_size = SKB_DATA_ALIGN(max_skb_size + NET_SKB_PAD); + if (unlikely(skb_end_pointer(skb) - skb->head > max_skb_size)) + return false; + + if (unlikely(skb_cloned(skb))) + return false; + + if (unlikely(skb_pfmemalloc(skb))) + return false; + + return true; +} + +#ifdef CONFIG_SKB_RECYCLER +void __init skb_recycler_init(void); +struct sk_buff *skb_recycler_alloc(struct net_device *dev, unsigned int length); +bool skb_recycler_consume(struct sk_buff *skb); +bool skb_recycler_consume_list_fast(struct sk_buff_head *skb_list); +void skb_recycler_print_all_lists(void); +#else +#define skb_recycler_init() {} +#define skb_recycler_alloc(dev, len) NULL +#define skb_recycler_consume(skb) false +#define skb_recycler_consume_list_fast(skb_list) false +#define skb_recycler_print_all_lists() false +#endif +#endif From c15213280aa2778dc4e1f3b12fa29ccc1e12c88f Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 24 Mar 2024 21:33:21 -0400 Subject: [PATCH 214/225] qualcommax: Move QCE to user selectable module The performance of Qualcomm Crypto Engine is 10x slower than kernel based encryption via ARMv8 crypto extensions. Rather than building it into the kernel allow users to select it as module which can be tested with other HW based crypto APIs via cryptodev-linux. --- package/kernel/linux/modules/crypto.mk | 17 +++++++++++++++++ target/linux/qualcommax/config-6.6 | 12 ++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/package/kernel/linux/modules/crypto.mk b/package/kernel/linux/modules/crypto.mk index 4a8a283d377321..f448ea4cb7900f 100644 --- a/package/kernel/linux/modules/crypto.mk +++ b/package/kernel/linux/modules/crypto.mk @@ -1159,3 +1159,20 @@ endef $(eval $(call KernelPackage,crypto-xts)) +define KernelPackage/crypto-qce + TITLE:=QTI Crypto Engine (QCE) + KCONFIG:= \ + CONFIG_CRYPTO_DEV_QCE \ + CONFIG_CRYPTO_DEV_QCE_AEAD=y \ + CONFIG_CRYPTO_DEV_QCE_ENABLE_ALL=y \ + CONFIG_CRYPTO_DEV_QCE_SHA=y \ + CONFIG_CRYPTO_DEV_QCE_SKCIPHER=y \ + CONFIG_CRYPTO_DEV_QCE_SW_MAX_LEN=512 + FILES:= \ + $(LINUX_DIR)/drivers/crypto/qce/qcrypto.ko + AUTOLOAD:=$(call AutoLoad,09,qcrypto) + DEPENDS:=@TARGET_qualcommax +kmod-crypto-manager +kmod-crypto-hash +kmod-crypto-des + $(call AddDepends/crypto) +endef + +$(eval $(call KernelPackage,crypto-qce)) diff --git a/target/linux/qualcommax/config-6.6 b/target/linux/qualcommax/config-6.6 index bbe5009473ae10..ca90fd924ed187 100644 --- a/target/linux/qualcommax/config-6.6 +++ b/target/linux/qualcommax/config-6.6 @@ -101,15 +101,15 @@ CONFIG_CRC8=y CONFIG_CRYPTO_AUTHENC=y CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_DEV_QCE=y -CONFIG_CRYPTO_DEV_QCE_AEAD=y +# CONFIG_CRYPTO_DEV_QCE=y +# CONFIG_CRYPTO_DEV_QCE_AEAD=y # CONFIG_CRYPTO_DEV_QCE_ENABLE_AEAD is not set -CONFIG_CRYPTO_DEV_QCE_ENABLE_ALL=y +# CONFIG_CRYPTO_DEV_QCE_ENABLE_ALL=y # CONFIG_CRYPTO_DEV_QCE_ENABLE_SHA is not set # CONFIG_CRYPTO_DEV_QCE_ENABLE_SKCIPHER is not set -CONFIG_CRYPTO_DEV_QCE_SHA=y -CONFIG_CRYPTO_DEV_QCE_SKCIPHER=y -CONFIG_CRYPTO_DEV_QCE_SW_MAX_LEN=512 +# CONFIG_CRYPTO_DEV_QCE_SHA=y +# CONFIG_CRYPTO_DEV_QCE_SKCIPHER=y +# CONFIG_CRYPTO_DEV_QCE_SW_MAX_LEN=512 CONFIG_CRYPTO_DEV_QCOM_RNG=y CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_HASH_INFO=y From a27a101affb903c4aadbb8401b5b542131d24a50 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 24 Mar 2024 22:44:54 -0400 Subject: [PATCH 215/225] qualcommax: NSS: kernel 6.6 support --- package/kernel/linux/modules/netfilter.mk | 1 + target/linux/qualcommax/config-6.6 | 22 +- .../files/net/core/skbuff_recycle.c | 5 + ...added-for-necessary-clocks-and-reset.patch | 311 +++++++ ...-gcc_snoc_bus_timeout_ahb_clk-offset.patch | 44 + ...074-Fix-gcc_blsp1_ahb_clk-properties.patch | 41 + .../0600-1-qca-nss-ecm-support-CORE.patch | 865 +++++++++++++++++ ...x-IPv6-user-route-change-event-calls.patch | 87 ++ ...-2-qca-nss-ecm-support-PPPOE-offload.patch | 600 ++++++++++++ ...00-3-qca-nss-ecm-support-net-bonding.patch | 46 + ...pport-net-bonding-over-LAG-interface.patch | 685 ++++++++++++++ .../0600-5-qca-nss-ecm-support-macvlan.patch | 96 ++ ...nss-ecm-support-netfilter-DSCPREMARK.patch | 154 +++ ...601-1-qca-add-nss-bridge-mgr-support.patch | 92 ++ ...0602-1-qca-nss-drv-add-qdisc-support.patch | 25 + ...-1-qca-nss-clients-add-qdisc-support.patch | 463 +++++++++ ...3-2-qca-nss-clients-add-l2tp-support.patch | 46 + ...3-3-qca-nss-clients-add-PPTP-support.patch | 478 ++++++++++ ...qca-nss-clients-add-iptunnel-support.patch | 77 ++ ...-5-qca-nss-clients-add-vxlan-support.patch | 103 ++ ...-clients-add-l2tp-offloading-support.patch | 368 ++++++++ ...a-nss-clients-iptunnel-lock-this-cpu.patch | 22 + ...-qca-nss-clients-add-tls-mgr-support.patch | 24 + .../0604-1-qca-add-mcs-support.patch | 876 ++++++++++++++++++ .../0605-1-qca-nss-cfi-support.patch | 111 +++ ..._ecache-Fix-NSS-ECM-BRK-kernel-panic.patch | 10 + .../9990-1-qca-skb_recycler-support.patch | 396 ++++++++ ...-api-disallow-identical-driver-names.patch | 10 + .../9999-silence-UBI-NAND-warnings.patch | 13 + 29 files changed, 6067 insertions(+), 4 deletions(-) create mode 100644 target/linux/qualcommax/patches-6.6/0170-clk-qcom-ipq8074-Support-added-for-necessary-clocks-and-reset.patch create mode 100644 target/linux/qualcommax/patches-6.6/0171-1-clk-qcom-ipq8074-Fix-gcc_snoc_bus_timeout_ahb_clk-offset.patch create mode 100644 target/linux/qualcommax/patches-6.6/0171-2-clk-qcom-ipq8074-Fix-gcc_blsp1_ahb_clk-properties.patch create mode 100644 target/linux/qualcommax/patches-6.6/0600-1-qca-nss-ecm-support-CORE.patch create mode 100644 target/linux/qualcommax/patches-6.6/0600-2-qca-nss-ecm-support-CORE-Fix-IPv6-user-route-change-event-calls.patch create mode 100644 target/linux/qualcommax/patches-6.6/0600-2-qca-nss-ecm-support-PPPOE-offload.patch create mode 100644 target/linux/qualcommax/patches-6.6/0600-3-qca-nss-ecm-support-net-bonding.patch create mode 100644 target/linux/qualcommax/patches-6.6/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch create mode 100644 target/linux/qualcommax/patches-6.6/0600-5-qca-nss-ecm-support-macvlan.patch create mode 100644 target/linux/qualcommax/patches-6.6/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch create mode 100644 target/linux/qualcommax/patches-6.6/0601-1-qca-add-nss-bridge-mgr-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/0602-1-qca-nss-drv-add-qdisc-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/0603-1-qca-nss-clients-add-qdisc-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/0603-2-qca-nss-clients-add-l2tp-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/0603-3-qca-nss-clients-add-PPTP-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/0603-4-qca-nss-clients-add-iptunnel-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/0603-5-qca-nss-clients-add-vxlan-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/0603-6-qca-nss-clients-add-l2tp-offloading-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch create mode 100644 target/linux/qualcommax/patches-6.6/0603-8-qca-nss-clients-add-tls-mgr-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/0604-1-qca-add-mcs-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/0605-1-qca-nss-cfi-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch create mode 100644 target/linux/qualcommax/patches-6.6/9990-1-qca-skb_recycler-support.patch create mode 100644 target/linux/qualcommax/patches-6.6/9999-revert-crypto-api-disallow-identical-driver-names.patch create mode 100644 target/linux/qualcommax/patches-6.6/9999-silence-UBI-NAND-warnings.patch diff --git a/package/kernel/linux/modules/netfilter.mk b/package/kernel/linux/modules/netfilter.mk index da3e69e49ac6f1..42d29d485a3915 100644 --- a/package/kernel/linux/modules/netfilter.mk +++ b/package/kernel/linux/modules/netfilter.mk @@ -312,6 +312,7 @@ $(eval $(call KernelPackage,ipt-offload)) define KernelPackage/ipt-ipopt TITLE:=Modules for matching/changing IP packet options KCONFIG:=$(KCONFIG_IPT_IPOPT) + DEPENDS:=+PACKAGE_kmod-nf-conntrack:kmod-nf-conntrack FILES:=$(foreach mod,$(IPT_IPOPT-m),$(LINUX_DIR)/net/$(mod).ko) AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_IPOPT-m))) $(call AddDepends/ipt) diff --git a/target/linux/qualcommax/config-6.6 b/target/linux/qualcommax/config-6.6 index ca90fd924ed187..8b6c100be8eb12 100644 --- a/target/linux/qualcommax/config-6.6 +++ b/target/linux/qualcommax/config-6.6 @@ -44,6 +44,8 @@ CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE=y CONFIG_ARM_AMBA=y CONFIG_ARM_ARCH_TIMER=y CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +# CONFIG_ARM_SMMU_V3_PMU is not set +# CONFIG_ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU is not set CONFIG_ARM_GIC=y CONFIG_ARM_GIC_V2M=y CONFIG_ARM_GIC_V3=y @@ -78,11 +80,11 @@ CONFIG_COREDUMP=y CONFIG_CPUFREQ_DT=y CONFIG_CPUFREQ_DT_PLATDEV=y CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set CONFIG_CPU_FREQ_GOV_ATTR_SET=y # CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set -# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_GOV_ONDEMAND=y CONFIG_CPU_FREQ_GOV_PERFORMANCE=y # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y @@ -125,6 +127,8 @@ CONFIG_CRYPTO_RNG=y CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_SHA1=y CONFIG_CRYPTO_SHA256=y +# CONFIG_CRYPTO_SM4_ARM64_CE_CCM is not set +# CONFIG_CRYPTO_SM4_ARM64_CE_GCM is not set CONFIG_CRYPTO_XTS=y CONFIG_CRYPTO_ZSTD=y CONFIG_DCACHE_WORD_ACCESS=y @@ -192,6 +196,11 @@ CONFIG_HAS_IOPORT=y CONFIG_HAS_IOPORT_MAP=y CONFIG_HWSPINLOCK=y CONFIG_HWSPINLOCK_QCOM=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MSM=y +CONFIG_HZ=1000 +# CONFIG_HZ_100 is not set +CONFIG_HZ_1000=y CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y @@ -375,7 +384,12 @@ CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y CONFIG_POWER_RESET=y # CONFIG_POWER_RESET_MSM is not set CONFIG_POWER_SUPPLY=y -CONFIG_PREEMPT_NONE_BUILD=y +CONFIG_PREEMPT=y +CONFIG_PREEMPT_COUNT=y +# CONFIG_PREEMPT_DYNAMIC is not set +# CONFIG_PREEMPT_NONE_BUILD is not set +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_RCU=y CONFIG_PRINTK_TIME=y CONFIG_PTP_1588_CLOCK_OPTIONAL=y CONFIG_QCA807X_PHY=y diff --git a/target/linux/qualcommax/files/net/core/skbuff_recycle.c b/target/linux/qualcommax/files/net/core/skbuff_recycle.c index 41add8d3098fca..cbcbc46c70d0a5 100644 --- a/target/linux/qualcommax/files/net/core/skbuff_recycle.c +++ b/target/linux/qualcommax/files/net/core/skbuff_recycle.c @@ -18,6 +18,7 @@ #include "skbuff_recycle.h" #include #include +#include #include "skbuff_debug.h" @@ -279,7 +280,11 @@ static void skb_recycler_free_skb(struct sk_buff_head *list) skbuff_debugobj_activate(skb); next = skb->next; __skb_unlink(skb, list); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,2,0) + skb_release_data(skb, SKB_CONSUMED, false); +#else skb_release_data(skb); +#endif kfree_skbmem(skb); /* * Update the skb->sum for next due to skb_link operation diff --git a/target/linux/qualcommax/patches-6.6/0170-clk-qcom-ipq8074-Support-added-for-necessary-clocks-and-reset.patch b/target/linux/qualcommax/patches-6.6/0170-clk-qcom-ipq8074-Support-added-for-necessary-clocks-and-reset.patch new file mode 100644 index 00000000000000..76cc8caac9a412 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0170-clk-qcom-ipq8074-Support-added-for-necessary-clocks-and-reset.patch @@ -0,0 +1,311 @@ +From 6504bc9edeb1a2a54d813f4bb5d0267e7bf827f9 Mon Sep 17 00:00:00 2001 +From: Praveenkumar I +Date: Thu, 6 Feb 2020 17:35:42 +0530 +Subject: [PATCH 4/8] clk: ipq8074: Support added for necessary clocks and + reset + +Change-Id: I21a76a44185f766e9b6dcba274392ea8e599718b +Signed-off-by: Praveenkumar I +Signed-off-by: Rajkumar Ayyasamy +--- + drivers/clk/qcom/gcc-ipq8074.c | 238 ++++++++++++++++++- + include/dt-bindings/clock/qcom,gcc-ipq8074.h | 35 ++- + 2 files changed, 258 insertions(+), 15 deletions(-) + +--- a/drivers/clk/qcom/gcc-ipq8074.c ++++ b/drivers/clk/qcom/gcc-ipq8074.c +@@ -48,6 +48,22 @@ enum { + P_UNIPHY2_TX, + }; + ++static const char * const gcc_xo_gpll4_gpll0_gpll6_gpll0_div2[] = { ++ "xo", ++ "gpll4", ++ "gpll0", ++ "gpll6", ++ "gpll0_out_main_div2", ++}; ++ ++static const struct parent_map gcc_xo_gpll4_gpll0_gpll6_gpll0_div2_map[] = { ++ { P_XO, 0 }, ++ { P_GPLL4, 1 }, ++ { P_GPLL0, 2 }, ++ { P_GPLL6, 3 }, ++ { P_GPLL0_DIV2, 4 }, ++}; ++ + static struct clk_alpha_pll gpll0_main = { + .offset = 0x21000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], +@@ -629,6 +645,12 @@ static const struct freq_tbl ftbl_pcie_a + { } + }; + ++struct freq_tbl ftbl_pcie_rchng_clk_src[] = { ++ F(19200000, P_XO, 1, 0, 0), ++ F(100000000, P_GPLL0, 8, 0, 0), ++ { } ++}; ++ + static struct clk_rcg2 pcie0_axi_clk_src = { + .cmd_rcgr = 0x75054, + .freq_tbl = ftbl_pcie_axi_clk_src, +@@ -2029,6 +2051,78 @@ static struct clk_rcg2 gp3_clk_src = { + }, + }; + ++struct freq_tbl ftbl_qdss_tsctr_clk_src[] = { ++ F(160000000, P_GPLL0_DIV2, 2.5, 0, 0), ++ F(320000000, P_GPLL0, 2.5, 0, 0), ++ F(600000000, P_GPLL6, 2, 0, 0), ++ { } ++}; ++ ++struct clk_rcg2 qdss_tsctr_clk_src = { ++ .cmd_rcgr = 0x29064, ++ .freq_tbl = ftbl_qdss_tsctr_clk_src, ++ .hid_width = 5, ++ .parent_map = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2_map, ++ .clkr.hw.init = &(struct clk_init_data){ ++ .name = "qdss_tsctr_clk_src", ++ .parent_names = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2, ++ .num_parents = 5, ++ .ops = &clk_rcg2_ops, ++ }, ++}; ++ ++static struct clk_fixed_factor qdss_dap_sync_clk_src = { ++ .mult = 1, ++ .div = 4, ++ .hw.init = &(struct clk_init_data){ ++ .name = "qdss_dap_sync_clk_src", ++ .parent_names = (const char *[]){ ++ "qdss_tsctr_clk_src" ++ }, ++ .num_parents = 1, ++ .ops = &clk_fixed_factor_ops, ++ }, ++}; ++ ++struct freq_tbl ftbl_qdss_at_clk_src[] = { ++ F(66670000, P_GPLL0_DIV2, 6, 0, 0), ++ F(240000000, P_GPLL6, 6, 0, 0), ++ { } ++}; ++ ++struct clk_rcg2 qdss_at_clk_src = { ++ .cmd_rcgr = 0x2900c, ++ .freq_tbl = ftbl_qdss_at_clk_src, ++ .hid_width = 5, ++ .parent_map = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2_map, ++ .clkr.hw.init = &(struct clk_init_data){ ++ .name = "qdss_at_clk_src", ++ .parent_names = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2, ++ .num_parents = 5, ++ .ops = &clk_rcg2_ops, ++ }, ++}; ++ ++ ++struct freq_tbl ftbl_adss_pwm_clk_src[] = { ++ F(19200000, P_XO, 1, 0, 0), ++ F(200000000, P_GPLL0, 4, 0, 0), ++ { } ++}; ++ ++struct clk_rcg2 adss_pwm_clk_src = { ++ .cmd_rcgr = 0x1c008, ++ .freq_tbl = ftbl_adss_pwm_clk_src, ++ .hid_width = 5, ++ .parent_map = gcc_xo_gpll0_map, ++ .clkr.hw.init = &(struct clk_init_data){ ++ .name = "adss_pwm_clk_src", ++ .parent_data = gcc_xo_gpll0, ++ .num_parents = 2, ++ .ops = &clk_rcg2_ops, ++ }, ++}; ++ + static struct clk_branch gcc_blsp1_ahb_clk = { + .halt_reg = 0x01008, + .clkr = { +@@ -4224,13 +4318,7 @@ static struct clk_branch gcc_gp3_clk = { + }, + }; + +-static const struct freq_tbl ftbl_pcie_rchng_clk_src[] = { +- F(19200000, P_XO, 1, 0, 0), +- F(100000000, P_GPLL0, 8, 0, 0), +- { } +-}; +- +-static struct clk_rcg2 pcie0_rchng_clk_src = { ++struct clk_rcg2 pcie0_rchng_clk_src = { + .cmd_rcgr = 0x75070, + .freq_tbl = ftbl_pcie_rchng_clk_src, + .hid_width = 5, +@@ -4322,6 +4410,114 @@ static const struct alpha_pll_config nss + .alpha_en_mask = BIT(24), + }; + ++static struct clk_branch gcc_snoc_bus_timeout2_ahb_clk = { ++ .halt_reg = 0x4700c, ++ .halt_bit = 31, ++ .clkr = { ++ .enable_reg = 0x4700c, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_snoc_bus_timeout2_ahb_clk", ++ .parent_names = (const char *[]){ ++ "usb0_master_clk_src" ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_snoc_bus_timeout3_ahb_clk = { ++ .halt_reg = 0x47014, ++ .halt_bit = 31, ++ .clkr = { ++ .enable_reg = 0x47014, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_snoc_bus_timeout3_ahb_clk", ++ .parent_names = (const char *[]){ ++ "usb1_master_clk_src" ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_dcc_clk = { ++ .halt_reg = 0x77004, ++ .halt_bit = 31, ++ .clkr = { ++ .enable_reg = 0x77004, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_dcc_clk", ++ .parent_names = (const char *[]){ ++ "pcnoc_clk_src" ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_qdss_at_clk = { ++ .halt_reg = 0x29024, ++ .halt_bit = 31, ++ .clkr = { ++ .enable_reg = 0x29024, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_qdss_at_clk", ++ .parent_names = (const char *[]){ ++ "qdss_at_clk_src" ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_qdss_dap_clk = { ++ .halt_reg = 0x29084, ++ .halt_bit = 31, ++ .clkr = { ++ .enable_reg = 0x29084, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_qdss_dap_clk", ++ .parent_names = (const char *[]){ ++ "qdss_dap_sync_clk_src" ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_adss_pwm_clk = { ++ .halt_reg = 0x1c020, ++ .halt_bit = 31, ++ .clkr = { ++ .enable_reg = 0x1c020, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_adss_pwm_clk", ++ .parent_names = (const char *[]){ ++ "adss_pwm_clk_src" ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ + static struct clk_hw *gcc_ipq8074_hws[] = { + &gpll0_out_main_div2.hw, + &gpll6_out_main_div2.hw, +@@ -4330,6 +4526,7 @@ static struct clk_hw *gcc_ipq8074_hws[] + &gcc_xo_div4_clk_src.hw, + &nss_noc_clk_src.hw, + &nss_ppe_cdiv_clk_src.hw, ++ &qdss_dap_sync_clk_src.hw, + }; + + static struct clk_regmap *gcc_ipq8074_clks[] = { +@@ -4561,6 +4758,15 @@ static struct clk_regmap *gcc_ipq8074_cl + [GCC_PCIE0_RCHNG_CLK] = &gcc_pcie0_rchng_clk.clkr, + [GCC_PCIE0_AXI_S_BRIDGE_CLK] = &gcc_pcie0_axi_s_bridge_clk.clkr, + [GCC_CRYPTO_PPE_CLK] = &gcc_crypto_ppe_clk.clkr, ++ [GCC_SNOC_BUS_TIMEOUT2_AHB_CLK] = &gcc_snoc_bus_timeout2_ahb_clk.clkr, ++ [GCC_SNOC_BUS_TIMEOUT3_AHB_CLK] = &gcc_snoc_bus_timeout3_ahb_clk.clkr, ++ [GCC_DCC_CLK] = &gcc_dcc_clk.clkr, ++ [QDSS_TSCTR_CLK_SRC] = &qdss_tsctr_clk_src.clkr, ++ [QDSS_AT_CLK_SRC] = &qdss_at_clk_src.clkr, ++ [GCC_QDSS_AT_CLK] = &gcc_qdss_at_clk.clkr, ++ [GCC_QDSS_DAP_CLK] = &gcc_qdss_dap_clk.clkr, ++ [ADSS_PWM_CLK_SRC] = &adss_pwm_clk_src.clkr, ++ [GCC_ADSS_PWM_CLK] = &gcc_adss_pwm_clk.clkr, + }; + + static const struct qcom_reset_map gcc_ipq8074_resets[] = { +--- a/include/dt-bindings/clock/qcom,gcc-ipq8074.h ++++ b/include/dt-bindings/clock/qcom,gcc-ipq8074.h +@@ -230,10 +230,19 @@ + #define GCC_GP1_CLK 221 + #define GCC_GP2_CLK 222 + #define GCC_GP3_CLK 223 +-#define GCC_PCIE0_AXI_S_BRIDGE_CLK 224 +-#define GCC_PCIE0_RCHNG_CLK_SRC 225 +-#define GCC_PCIE0_RCHNG_CLK 226 +-#define GCC_CRYPTO_PPE_CLK 227 ++#define GCC_CRYPTO_PPE_CLK 224 ++#define GCC_PCIE0_RCHNG_CLK_SRC 225 ++#define GCC_PCIE0_RCHNG_CLK 226 ++#define GCC_PCIE0_AXI_S_BRIDGE_CLK 227 ++#define GCC_SNOC_BUS_TIMEOUT2_AHB_CLK 228 ++#define GCC_SNOC_BUS_TIMEOUT3_AHB_CLK 229 ++#define GCC_DCC_CLK 230 ++#define ADSS_PWM_CLK_SRC 231 ++#define GCC_ADSS_PWM_CLK 232 ++#define QDSS_TSCTR_CLK_SRC 233 ++#define QDSS_AT_CLK_SRC 234 ++#define GCC_QDSS_AT_CLK 235 ++#define GCC_QDSS_DAP_CLK 236 + + #define GCC_BLSP1_BCR 0 + #define GCC_BLSP1_QUP1_BCR 1 diff --git a/target/linux/qualcommax/patches-6.6/0171-1-clk-qcom-ipq8074-Fix-gcc_snoc_bus_timeout_ahb_clk-offset.patch b/target/linux/qualcommax/patches-6.6/0171-1-clk-qcom-ipq8074-Fix-gcc_snoc_bus_timeout_ahb_clk-offset.patch new file mode 100644 index 00000000000000..b1393fc9ad43c2 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0171-1-clk-qcom-ipq8074-Fix-gcc_snoc_bus_timeout_ahb_clk-offset.patch @@ -0,0 +1,44 @@ +From 462aa0c53397ec5bf78e3e7f68aa8a3ca300f4ba Mon Sep 17 00:00:00 2001 +From: Selvam Sathappan Periakaruppan +Date: Tue, 24 Mar 2020 19:09:38 +0530 +Subject: [PATCH 5/8] clk: qcom: ipq8074: Fix gcc_snoc_bus_timeout_ahb_clk + offset + +By default, the ipq8074 V2 clks are provided in the gcc driver. +Updating the gcc_snoc_bus_timeout_ahb_clk offsets also as needed +in ipq8074 V2. + +Change-Id: I5a6e98d002f5c3354a804e55dd9ebb1f83f7f974 +Signed-off-by: Selvam Sathappan Periakaruppan +--- + drivers/clk/qcom/gcc-ipq8074.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/clk/qcom/gcc-ipq8074.c ++++ b/drivers/clk/qcom/gcc-ipq8074.c +@@ -4411,10 +4411,10 @@ static const struct alpha_pll_config nss + }; + + static struct clk_branch gcc_snoc_bus_timeout2_ahb_clk = { +- .halt_reg = 0x4700c, ++ .halt_reg = 0x47014, + .halt_bit = 31, + .clkr = { +- .enable_reg = 0x4700c, ++ .enable_reg = 0x47014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_snoc_bus_timeout2_ahb_clk", +@@ -4429,10 +4429,10 @@ static struct clk_branch gcc_snoc_bus_ti + }; + + static struct clk_branch gcc_snoc_bus_timeout3_ahb_clk = { +- .halt_reg = 0x47014, ++ .halt_reg = 0x4701C, + .halt_bit = 31, + .clkr = { +- .enable_reg = 0x47014, ++ .enable_reg = 0x4701C, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_snoc_bus_timeout3_ahb_clk", diff --git a/target/linux/qualcommax/patches-6.6/0171-2-clk-qcom-ipq8074-Fix-gcc_blsp1_ahb_clk-properties.patch b/target/linux/qualcommax/patches-6.6/0171-2-clk-qcom-ipq8074-Fix-gcc_blsp1_ahb_clk-properties.patch new file mode 100644 index 00000000000000..a7abddd5fddf18 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0171-2-clk-qcom-ipq8074-Fix-gcc_blsp1_ahb_clk-properties.patch @@ -0,0 +1,41 @@ +From 52315bec6ed633b6a71f28b746029602f8bd70b9 Mon Sep 17 00:00:00 2001 +From: Balaji Prakash J +Date: Wed, 22 Apr 2020 20:35:30 +0530 +Subject: [PATCH] clk: ipq8074: fix gcc_blsp1_ahb_clk properties + +All the voting enabled clocks does not support the enable +from CBCR register. So, updated gcc_blsp1_ahb_clk enable +register and mask to enable bit in APCS_CLOCK_BRANCH_ENA_VOTE. + +Also, the voting controlled clocks are shared among multiple +components like APSS, RPM, NSS, TZ, etc. So, turning the +voting off from APSS does not make the clock off if it has +been voted from another component. Added the flag +BRANCH_HALT_VOTED in order to skip checking the clock +disable status. + +This change is referred from the below commits, +1. 246b4fb3af9bd65d8af794aac2f0e7b1ed9cc2dd +2. c8374157d5ae91d3b3e0d513d62808a798b32d3a + +Signed-off-by: Balaji Prakash J +Change-Id: I505cb560b31ad27a02c165fbe13bb33a2fc7d230 +--- + drivers/clk/qcom/gcc-ipq8074.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/clk/qcom/gcc-ipq8074.c ++++ b/drivers/clk/qcom/gcc-ipq8074.c +@@ -2125,9 +2125,10 @@ struct clk_rcg2 adss_pwm_clk_src = { + + static struct clk_branch gcc_blsp1_ahb_clk = { + .halt_reg = 0x01008, ++ .halt_check = BRANCH_HALT_VOTED, + .clkr = { +- .enable_reg = 0x01008, +- .enable_mask = BIT(0), ++ .enable_reg = 0x0b004, ++ .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ diff --git a/target/linux/qualcommax/patches-6.6/0600-1-qca-nss-ecm-support-CORE.patch b/target/linux/qualcommax/patches-6.6/0600-1-qca-nss-ecm-support-CORE.patch new file mode 100644 index 00000000000000..21006721e11666 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0600-1-qca-nss-ecm-support-CORE.patch @@ -0,0 +1,865 @@ +--- a/include/linux/if_bridge.h ++++ b/include/linux/if_bridge.h +@@ -71,6 +71,9 @@ void brioctl_set(int (*hook)(struct net + void __user *uarg)); + int br_ioctl_call(struct net *net, struct net_bridge *br, unsigned int cmd, + struct ifreq *ifr, void __user *uarg); ++extern void br_dev_update_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *nlstats); ++extern bool br_is_hairpin_enabled(struct net_device *dev); + + #if IS_ENABLED(CONFIG_BRIDGE) && IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING) + int br_multicast_list_adjacent(struct net_device *dev, +@@ -213,4 +216,42 @@ static inline clock_t br_get_ageing_time + } + #endif + ++/* QCA NSS ECM support - Start */ ++extern struct net_device *br_port_dev_get(struct net_device *dev, ++ unsigned char *addr, ++ struct sk_buff *skb, ++ unsigned int cookie); ++extern void br_refresh_fdb_entry(struct net_device *dev, const char *addr); ++extern void br_fdb_entry_refresh(struct net_device *dev, const char *addr, __u16 vid); ++extern struct net_bridge_fdb_entry *br_fdb_has_entry(struct net_device *dev, ++ const char *addr, ++ __u16 vid); ++extern void br_fdb_update_register_notify(struct notifier_block *nb); ++extern void br_fdb_update_unregister_notify(struct notifier_block *nb); ++ ++typedef struct net_bridge_port *br_port_dev_get_hook_t(struct net_device *dev, ++ struct sk_buff *skb, ++ unsigned char *addr, ++ unsigned int cookie); ++extern br_port_dev_get_hook_t __rcu *br_port_dev_get_hook; ++ ++#define BR_FDB_EVENT_ADD 0x01 ++#define BR_FDB_EVENT_DEL 0x02 ++ ++struct br_fdb_event { ++ struct net_device *dev; ++ unsigned char addr[6]; ++ unsigned char is_local; ++ struct net_bridge *br; ++ struct net_device *orig_dev; ++}; ++extern void br_fdb_register_notify(struct notifier_block *nb); ++extern void br_fdb_unregister_notify(struct notifier_block *nb); ++ ++typedef struct net_bridge_port *br_get_dst_hook_t( ++ const struct net_bridge_port *src, ++ struct sk_buff **skb); ++extern br_get_dst_hook_t __rcu *br_get_dst_hook; ++/* QCA NSS ECM support - End */ ++ + #endif +--- a/include/linux/if_vlan.h ++++ b/include/linux/if_vlan.h +@@ -143,7 +143,10 @@ extern struct net_device *__vlan_find_de + extern int vlan_for_each(struct net_device *dev, + int (*action)(struct net_device *dev, int vid, + void *arg), void *arg); ++extern void __vlan_dev_update_accel_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *stats); /* QCA NSS ECM support */ + extern struct net_device *vlan_dev_real_dev(const struct net_device *dev); ++extern struct net_device *vlan_dev_next_dev(const struct net_device *dev); /* QCA NSS ECM support */ + extern u16 vlan_dev_vlan_id(const struct net_device *dev); + extern __be16 vlan_dev_vlan_proto(const struct net_device *dev); + +@@ -236,6 +239,12 @@ extern void vlan_vids_del_by_dev(struct + extern bool vlan_uses_dev(const struct net_device *dev); + + #else ++static inline void __vlan_dev_update_accel_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *stats) ++{ ++ ++} /* QCA NSS ECM support */ ++ + static inline struct net_device * + __vlan_find_dev_deep_rcu(struct net_device *real_dev, + __be16 vlan_proto, u16 vlan_id) +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -2936,6 +2936,10 @@ enum netdev_cmd { + NETDEV_OFFLOAD_XSTATS_REPORT_USED, + NETDEV_OFFLOAD_XSTATS_REPORT_DELTA, + NETDEV_XDP_FEAT_CHANGE, ++ /* QCA NSS ECM Support - Start */ ++ NETDEV_BR_JOIN, ++ NETDEV_BR_LEAVE, ++ /* QCA NSS ECM Support - End */ + }; + const char *netdev_cmd_to_name(enum netdev_cmd cmd); + +--- a/include/net/ip6_route.h ++++ b/include/net/ip6_route.h +@@ -207,6 +207,11 @@ void rt6_multipath_rebalance(struct fib6 + void rt6_uncached_list_add(struct rt6_info *rt); + void rt6_uncached_list_del(struct rt6_info *rt); + ++/* QCA NSS ECM support - Start */ ++int rt6_register_notifier(struct notifier_block *nb); ++int rt6_unregister_notifier(struct notifier_block *nb); ++/* QCA NSS ECM support - End */ ++ + static inline const struct rt6_info *skb_rt6_info(const struct sk_buff *skb) + { + const struct dst_entry *dst = skb_dst(skb); +--- a/include/net/neighbour.h ++++ b/include/net/neighbour.h +@@ -249,6 +249,13 @@ static inline int neigh_parms_family(str + return p->tbl->family; + } + ++/* QCA NSS ECM support - Start */ ++struct neigh_mac_update { ++ unsigned char old_mac[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; ++ unsigned char update_mac[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; ++}; ++/* QCA NSS ECM support - End */ ++ + #define NEIGH_PRIV_ALIGN sizeof(long long) + #define NEIGH_ENTRY_SIZE(size) ALIGN((size), NEIGH_PRIV_ALIGN) + +@@ -395,6 +402,11 @@ void __neigh_for_each_release(struct nei + int (*cb)(struct neighbour *)); + int neigh_xmit(int fam, struct net_device *, const void *, struct sk_buff *); + ++/* QCA NSS ECM support - Start */ ++extern void neigh_mac_update_register_notify(struct notifier_block *nb); ++extern void neigh_mac_update_unregister_notify(struct notifier_block *nb); ++/* QCA NSS ECM support - End */ ++ + struct neigh_seq_state { + struct seq_net_private p; + struct neigh_table *tbl; +@@ -600,4 +612,5 @@ static inline void neigh_update_is_route + *notify = 1; + } + } ++ + #endif +--- a/include/net/route.h ++++ b/include/net/route.h +@@ -237,6 +237,11 @@ struct rtable *rt_dst_alloc(struct net_d + unsigned int flags, u16 type, bool noxfrm); + struct rtable *rt_dst_clone(struct net_device *dev, struct rtable *rt); + ++/* QCA NSS ECM support - Start */ ++int ip_rt_register_notifier(struct notifier_block *nb); ++int ip_rt_unregister_notifier(struct notifier_block *nb); ++/* QCA NSS ECM support - End */ ++ + struct in_ifaddr; + void fib_add_ifaddr(struct in_ifaddr *); + void fib_del_ifaddr(struct in_ifaddr *, struct in_ifaddr *); +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -2266,4 +2266,6 @@ void br_do_suppress_nd(struct sk_buff *s + u16 vid, struct net_bridge_port *p, struct nd_msg *msg); + struct nd_msg *br_is_nd_neigh_msg(struct sk_buff *skb, struct nd_msg *m); + bool br_is_neigh_suppress_enabled(const struct net_bridge_port *p, u16 vid); ++#define __br_get(__hook, __default, __args ...) \ ++ (__hook ? (__hook(__args)) : (__default)) /* QCA NSS ECM support */ + #endif +--- a/net/8021q/vlan_core.c ++++ b/net/8021q/vlan_core.c +@@ -72,6 +72,28 @@ bool vlan_do_receive(struct sk_buff **sk + return true; + } + ++/* QCA NSS ECM support - Start */ ++/* Update the VLAN device with statistics from network offload engines */ ++void __vlan_dev_update_accel_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *nlstats) ++{ ++ struct vlan_pcpu_stats *stats; ++ ++ if (!is_vlan_dev(dev)) ++ return; ++ ++ stats = per_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats, 0); ++ ++ u64_stats_update_begin(&stats->syncp); ++ u64_stats_add(&stats->rx_packets, nlstats->rx_packets); ++ u64_stats_add(&stats->rx_bytes, nlstats->rx_bytes); ++ u64_stats_add(&stats->tx_packets, nlstats->tx_packets); ++ u64_stats_add(&stats->tx_bytes, nlstats->tx_bytes); ++ u64_stats_update_end(&stats->syncp); ++} ++EXPORT_SYMBOL(__vlan_dev_update_accel_stats); ++/* QCA NSS ECM support - End */ ++ + /* Must be invoked with rcu_read_lock. */ + struct net_device *__vlan_find_dev_deep_rcu(struct net_device *dev, + __be16 vlan_proto, u16 vlan_id) +@@ -110,6 +132,15 @@ struct net_device *vlan_dev_real_dev(con + } + EXPORT_SYMBOL(vlan_dev_real_dev); + ++/* QCA NSS ECM support - Start */ ++/* Caller is responsible to hold the reference of the returned device */ ++struct net_device *vlan_dev_next_dev(const struct net_device *dev) ++{ ++ return vlan_dev_priv(dev)->real_dev; ++} ++EXPORT_SYMBOL(vlan_dev_next_dev); ++/* QCA NSS ECM support - End */ ++ + u16 vlan_dev_vlan_id(const struct net_device *dev) + { + return vlan_dev_priv(dev)->vlan_id; +--- a/net/bridge/br_fdb.c ++++ b/net/bridge/br_fdb.c +@@ -33,6 +33,20 @@ static const struct rhashtable_params br + + static struct kmem_cache *br_fdb_cache __read_mostly; + ++ATOMIC_NOTIFIER_HEAD(br_fdb_notifier_list); ++ ++void br_fdb_register_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_register(&br_fdb_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(br_fdb_register_notify); ++ ++void br_fdb_unregister_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_unregister(&br_fdb_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(br_fdb_unregister_notify); ++ + int __init br_fdb_init(void) + { + br_fdb_cache = kmem_cache_create("bridge_fdb_cache", +@@ -195,6 +209,25 @@ static void fdb_notify(struct net_bridge + if (swdev_notify) + br_switchdev_fdb_notify(br, fdb, type); + ++ /* QCA NSS ECM support - Start */ ++ if (fdb->dst) { ++ int event; ++ struct br_fdb_event fdb_event; ++ ++ if (type == RTM_NEWNEIGH) ++ event = BR_FDB_EVENT_ADD; ++ else ++ event = BR_FDB_EVENT_DEL; ++ ++ fdb_event.dev = fdb->dst->dev; ++ ether_addr_copy(fdb_event.addr, fdb->key.addr.addr); ++ fdb_event.is_local = test_bit(BR_FDB_LOCAL, &fdb->flags); ++ atomic_notifier_call_chain(&br_fdb_notifier_list, ++ event, ++ (void *)&fdb_event); ++ } ++ /* QCA NSS ECM support - End */ ++ + skb = nlmsg_new(fdb_nlmsg_size(), GFP_ATOMIC); + if (skb == NULL) + goto errout; +@@ -519,6 +552,22 @@ out: + spin_unlock_bh(&br->hash_lock); + } + ++/* QCA NSS ECM support - Start */ ++ATOMIC_NOTIFIER_HEAD(br_fdb_update_notifier_list); ++ ++void br_fdb_update_register_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_register(&br_fdb_update_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(br_fdb_update_register_notify); ++ ++void br_fdb_update_unregister_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_unregister(&br_fdb_update_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(br_fdb_update_unregister_notify); ++/* QCA NSS ECM support - End */ ++ + void br_fdb_cleanup(struct work_struct *work) + { + struct net_bridge *br = container_of(work, struct net_bridge, +@@ -527,6 +576,7 @@ void br_fdb_cleanup(struct work_struct * + unsigned long delay = hold_time(br); + unsigned long work_delay = delay; + unsigned long now = jiffies; ++ u8 mac_addr[6]; /* QCA NSS ECM support */ + + /* this part is tricky, in order to avoid blocking learning and + * consequently forwarding, we rely on rcu to delete objects with +@@ -553,8 +603,15 @@ void br_fdb_cleanup(struct work_struct * + work_delay = min(work_delay, this_timer - now); + } else { + spin_lock_bh(&br->hash_lock); +- if (!hlist_unhashed(&f->fdb_node)) ++ if (!hlist_unhashed(&f->fdb_node)) { ++ ether_addr_copy(mac_addr, f->key.addr.addr); + fdb_delete(br, f, true); ++ /* QCA NSS ECM support - Start */ ++ atomic_notifier_call_chain( ++ &br_fdb_update_notifier_list, 0, ++ (void *)mac_addr); ++ /* QCA NSS ECM support - End */ ++ } + spin_unlock_bh(&br->hash_lock); + } + } +@@ -891,6 +948,12 @@ void br_fdb_update(struct net_bridge *br + */ + if (unlikely(test_bit(BR_FDB_LOCKED, &fdb->flags))) + clear_bit(BR_FDB_LOCKED, &fdb->flags); ++ ++ /* QCA NSS ECM support - Start */ ++ atomic_notifier_call_chain( ++ &br_fdb_update_notifier_list, ++ 0, (void *)addr); ++ /* QCA NSS ECM support - End */ + } + + if (unlikely(test_bit(BR_FDB_ADDED_BY_USER, &flags))) +@@ -914,6 +977,64 @@ void br_fdb_update(struct net_bridge *br + } + } + ++/* QCA NSS ECM support - Start */ ++/* Refresh FDB entries for bridge packets being forwarded by offload engines */ ++void br_refresh_fdb_entry(struct net_device *dev, const char *addr) ++{ ++ struct net_bridge_port *p = br_port_get_rcu(dev); ++ ++ if (!p || p->state == BR_STATE_DISABLED) ++ return; ++ ++ if (!is_valid_ether_addr(addr)) { ++ pr_info("bridge: Attempt to refresh with invalid ether address %pM\n", ++ addr); ++ return; ++ } ++ ++ rcu_read_lock(); ++ br_fdb_update(p->br, p, addr, 0, true); ++ rcu_read_unlock(); ++} ++EXPORT_SYMBOL_GPL(br_refresh_fdb_entry); ++ ++/* Update timestamp of FDB entries for bridge packets being forwarded by offload engines */ ++void br_fdb_entry_refresh(struct net_device *dev, const char *addr, __u16 vid) ++{ ++ struct net_bridge_fdb_entry *fdb; ++ struct net_bridge_port *p = br_port_get_rcu(dev); ++ ++ if (!p || p->state == BR_STATE_DISABLED) ++ return; ++ ++ rcu_read_lock(); ++ fdb = fdb_find_rcu(&p->br->fdb_hash_tbl, addr, vid); ++ if (likely(fdb)) { ++ fdb->updated = jiffies; ++ } ++ rcu_read_unlock(); ++} ++EXPORT_SYMBOL_GPL(br_fdb_entry_refresh); ++ ++/* Look up the MAC address in the device's bridge fdb table */ ++struct net_bridge_fdb_entry *br_fdb_has_entry(struct net_device *dev, ++ const char *addr, __u16 vid) ++{ ++ struct net_bridge_port *p = br_port_get_rcu(dev); ++ struct net_bridge_fdb_entry *fdb; ++ ++ if (!p || p->state == BR_STATE_DISABLED) ++ return NULL; ++ ++ rcu_read_lock(); ++ fdb = fdb_find_rcu(&p->br->fdb_hash_tbl, addr, vid); ++ rcu_read_unlock(); ++ ++ return fdb; ++} ++EXPORT_SYMBOL_GPL(br_fdb_has_entry); ++ ++/* QCA NSS ECM support - End */ + /* Dump information about entries, in response to GETNEIGH */ + int br_fdb_dump(struct sk_buff *skb, + struct netlink_callback *cb, +--- a/net/bridge/br_if.c ++++ b/net/bridge/br_if.c +@@ -26,6 +26,12 @@ + + #include "br_private.h" + ++/* QCA NSS ECM support - Start */ ++/* Hook for external forwarding logic */ ++br_port_dev_get_hook_t __rcu *br_port_dev_get_hook __read_mostly; ++EXPORT_SYMBOL_GPL(br_port_dev_get_hook); ++/* QCA NSS ECM support - End */ ++ + /* + * Determine initial path cost based on speed. + * using recommendations from 802.1d standard +@@ -697,6 +703,8 @@ int br_add_if(struct net_bridge *br, str + + kobject_uevent(&p->kobj, KOBJ_ADD); + ++ call_netdevice_notifiers(NETDEV_BR_JOIN, dev); /* QCA NSS ECM support */ ++ + return 0; + + err6: +@@ -732,6 +740,8 @@ int br_del_if(struct net_bridge *br, str + if (!p || p->br != br) + return -EINVAL; + ++ call_netdevice_notifiers(NETDEV_BR_LEAVE, dev); /* QCA NSS ECM support */ ++ + /* Since more than one interface can be attached to a bridge, + * there still maybe an alternate path for netconsole to use; + * therefore there is no reason for a NETDEV_RELEASE event. +@@ -775,3 +785,97 @@ bool br_port_flag_is_set(const struct ne + return p->flags & flag; + } + EXPORT_SYMBOL_GPL(br_port_flag_is_set); ++ ++/* br_port_dev_get() ++ * If a skb is provided, and the br_port_dev_get_hook_t hook exists, ++ * use that to try and determine the egress port for that skb. ++ * If not, or no egress port could be determined, use the given addr ++ * to identify the port to which it is reachable, ++ * returing a reference to the net device associated with that port. ++ * ++ * NOTE: Return NULL if given dev is not a bridge or the mac has no ++ * associated port. ++ */ ++struct net_device *br_port_dev_get(struct net_device *dev, unsigned char *addr, ++ struct sk_buff *skb, ++ unsigned int cookie) ++{ ++ struct net_bridge_fdb_entry *fdbe; ++ struct net_bridge *br; ++ struct net_device *netdev = NULL; ++ ++ /* Is this a bridge? */ ++ if (!(dev->priv_flags & IFF_EBRIDGE)) ++ return NULL; ++ ++ rcu_read_lock(); ++ ++ /* If the hook exists and the skb isn't NULL, try and get the port */ ++ if (skb) { ++ br_port_dev_get_hook_t *port_dev_get_hook; ++ ++ port_dev_get_hook = rcu_dereference(br_port_dev_get_hook); ++ if (port_dev_get_hook) { ++ struct net_bridge_port *pdst = ++ __br_get(port_dev_get_hook, NULL, dev, skb, ++ addr, cookie); ++ if (pdst) { ++ dev_hold(pdst->dev); ++ netdev = pdst->dev; ++ goto out; ++ } ++ } ++ } ++ ++ /* Either there is no hook, or can't ++ * determine the port to use - fall back to using FDB ++ */ ++ ++ br = netdev_priv(dev); ++ ++ /* Lookup the fdb entry and get reference to the port dev */ ++ fdbe = br_fdb_find_rcu(br, addr, 0); ++ if (fdbe && fdbe->dst) { ++ netdev = fdbe->dst->dev; /* port device */ ++ dev_hold(netdev); ++ } ++out: ++ rcu_read_unlock(); ++ return netdev; ++} ++EXPORT_SYMBOL_GPL(br_port_dev_get); ++ ++/* Update bridge statistics for bridge packets processed by offload engines */ ++void br_dev_update_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *nlstats) ++{ ++ struct pcpu_sw_netstats *tstats; ++ ++ /* Is this a bridge? */ ++ if (!(dev->priv_flags & IFF_EBRIDGE)) ++ return; ++ ++ tstats = this_cpu_ptr(dev->tstats); ++ ++ u64_stats_update_begin(&tstats->syncp); ++ u64_stats_add(&tstats->rx_packets, nlstats->rx_packets); ++ u64_stats_add(&tstats->rx_bytes, nlstats->rx_bytes); ++ u64_stats_add(&tstats->tx_packets, nlstats->tx_packets); ++ u64_stats_add(&tstats->tx_bytes, nlstats->tx_bytes); ++ u64_stats_update_end(&tstats->syncp); ++} ++EXPORT_SYMBOL_GPL(br_dev_update_stats); ++ ++/* QCA NSS ECM support - Start */ ++/* API to know if hairpin feature is enabled/disabled on this bridge port */ ++bool br_is_hairpin_enabled(struct net_device *dev) ++{ ++ struct net_bridge_port *port = br_port_get_check_rcu(dev); ++ ++ if (likely(port)) ++ return port->flags & BR_HAIRPIN_MODE; ++ return false; ++} ++EXPORT_SYMBOL_GPL(br_is_hairpin_enabled); ++ ++/* QCA NSS ECM support - End */ +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -1275,6 +1275,22 @@ static void neigh_update_hhs(struct neig + } + } + ++/* QCA NSS ECM support - Start */ ++ATOMIC_NOTIFIER_HEAD(neigh_mac_update_notifier_list); ++ ++void neigh_mac_update_register_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_register(&neigh_mac_update_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(neigh_mac_update_register_notify); ++ ++void neigh_mac_update_unregister_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_unregister(&neigh_mac_update_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(neigh_mac_update_unregister_notify); ++/* QCA NSS ECM support - End */ ++ + /* Generic update routine. + -- lladdr is new lladdr or NULL, if it is not supplied. + -- new is new state. +@@ -1303,6 +1319,7 @@ static int __neigh_update(struct neighbo + struct net_device *dev; + int err, notify = 0; + u8 old; ++ struct neigh_mac_update nmu; /* QCA NSS ECM support */ + + trace_neigh_update(neigh, lladdr, new, flags, nlmsg_pid); + +@@ -1317,7 +1334,10 @@ static int __neigh_update(struct neighbo + new = old; + goto out; + } +- if (!(flags & NEIGH_UPDATE_F_ADMIN) && ++ ++ memset(&nmu, 0, sizeof(struct neigh_mac_update)); /* QCA NSS ECM support */ ++ ++ if (!(flags & NEIGH_UPDATE_F_ADMIN) && + (old & (NUD_NOARP | NUD_PERMANENT))) + goto out; + +@@ -1354,7 +1374,12 @@ static int __neigh_update(struct neighbo + - compare new & old + - if they are different, check override flag + */ +- if ((old & NUD_VALID) && ++ /* QCA NSS ECM update - Start */ ++ memcpy(nmu.old_mac, neigh->ha, dev->addr_len); ++ memcpy(nmu.update_mac, lladdr, dev->addr_len); ++ /* QCA NSS ECM update - End */ ++ ++ if ((old & NUD_VALID) && + !memcmp(lladdr, neigh->ha, dev->addr_len)) + lladdr = neigh->ha; + } else { +@@ -1476,8 +1501,11 @@ out: + neigh_update_gc_list(neigh); + if (managed_update) + neigh_update_managed_list(neigh); +- if (notify) ++ if (notify) { + neigh_update_notify(neigh, nlmsg_pid); ++ atomic_notifier_call_chain(&neigh_mac_update_notifier_list, 0, ++ (struct neigh_mac_update *)&nmu); /* QCA NSS ECM support */ ++ } + trace_neigh_update_done(neigh, err); + return err; + } +--- a/net/ipv4/fib_trie.c ++++ b/net/ipv4/fib_trie.c +@@ -1211,6 +1211,9 @@ static bool fib_valid_key_len(u32 key, u + static void fib_remove_alias(struct trie *t, struct key_vector *tp, + struct key_vector *l, struct fib_alias *old); + ++/* Define route change notification chain. */ ++static BLOCKING_NOTIFIER_HEAD(iproute_chain); /* QCA NSS ECM support */ ++ + /* Caller must hold RTNL. */ + int fib_table_insert(struct net *net, struct fib_table *tb, + struct fib_config *cfg, struct netlink_ext_ack *extack) +@@ -1404,6 +1407,9 @@ int fib_table_insert(struct net *net, st + rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, new_fa->tb_id, + &cfg->fc_nlinfo, nlflags); + succeeded: ++ blocking_notifier_call_chain(&iproute_chain, ++ RTM_NEWROUTE, fi); ++ + return 0; + + out_remove_new_fa: +@@ -1775,6 +1781,9 @@ int fib_table_delete(struct net *net, st + if (fa_to_delete->fa_state & FA_S_ACCESSED) + rt_cache_flush(cfg->fc_nlinfo.nl_net); + ++ blocking_notifier_call_chain(&iproute_chain, ++ RTM_DELROUTE, fa_to_delete->fa_info); ++ + fib_release_info(fa_to_delete->fa_info); + alias_free_mem_rcu(fa_to_delete); + return 0; +@@ -2407,6 +2416,20 @@ void __init fib_trie_init(void) + 0, SLAB_PANIC | SLAB_ACCOUNT, NULL); + } + ++/* QCA NSS ECM support - Start */ ++int ip_rt_register_notifier(struct notifier_block *nb) ++{ ++ return blocking_notifier_chain_register(&iproute_chain, nb); ++} ++EXPORT_SYMBOL(ip_rt_register_notifier); ++ ++int ip_rt_unregister_notifier(struct notifier_block *nb) ++{ ++ return blocking_notifier_chain_unregister(&iproute_chain, nb); ++} ++EXPORT_SYMBOL(ip_rt_unregister_notifier); ++/* QCA NSS ECM support - End */ ++ + struct fib_table *fib_trie_table(u32 id, struct fib_table *alias) + { + struct fib_table *tb; +--- a/net/ipv6/ndisc.c ++++ b/net/ipv6/ndisc.c +@@ -666,6 +666,7 @@ void ndisc_send_ns(struct net_device *de + if (skb) + ndisc_send_skb(skb, daddr, saddr); + } ++EXPORT_SYMBOL(ndisc_send_ns); + + void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr, + const struct in6_addr *daddr) +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -197,6 +197,9 @@ static void rt6_uncached_list_flush_dev( + } + } + ++/* Define route change notification chain. */ ++ATOMIC_NOTIFIER_HEAD(ip6route_chain); /* QCA NSS ECM support */ ++ + static inline const void *choose_neigh_daddr(const struct in6_addr *p, + struct sk_buff *skb, + const void *daddr) +@@ -3864,6 +3867,10 @@ int ip6_route_add(struct fib6_config *cf + return PTR_ERR(rt); + + err = __ip6_ins_rt(rt, &cfg->fc_nlinfo, extack); ++ if (!err) ++ atomic_notifier_call_chain(&ip6route_chain, ++ RTM_NEWROUTE, rt); ++ + fib6_info_release(rt); + + return err; +@@ -3885,6 +3892,9 @@ static int __ip6_del_rt(struct fib6_info + err = fib6_del(rt, info); + spin_unlock_bh(&table->tb6_lock); + ++ if (!err) ++ atomic_notifier_call_chain(&ip6route_chain, ++ RTM_DELROUTE, rt); + out: + fib6_info_release(rt); + return err; +@@ -6329,6 +6339,20 @@ static int ip6_route_dev_notify(struct n + return NOTIFY_OK; + } + ++/* QCA NSS ECM support - Start */ ++int rt6_register_notifier(struct notifier_block *nb) ++{ ++ return atomic_notifier_chain_register(&ip6route_chain, nb); ++} ++EXPORT_SYMBOL(rt6_register_notifier); ++ ++int rt6_unregister_notifier(struct notifier_block *nb) ++{ ++ return atomic_notifier_chain_unregister(&ip6route_chain, nb); ++} ++EXPORT_SYMBOL(rt6_unregister_notifier); ++/* QCA NSS ECM support - End */ ++ + /* + * /proc + */ +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -1673,6 +1673,7 @@ const char *netdev_cmd_to_name(enum netd + N(PRE_CHANGEADDR) N(OFFLOAD_XSTATS_ENABLE) N(OFFLOAD_XSTATS_DISABLE) + N(OFFLOAD_XSTATS_REPORT_USED) N(OFFLOAD_XSTATS_REPORT_DELTA) + N(XDP_FEAT_CHANGE) ++ N(BR_JOIN) N(BR_LEAVE) + } + #undef N + return "UNKNOWN_NETDEV_EVENT"; +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -1002,6 +1002,7 @@ void inet6_ifa_finish_destroy(struct ine + + kfree_rcu(ifp, rcu); + } ++EXPORT_SYMBOL(inet6_ifa_finish_destroy); + + static void + ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) +--- a/include/net/vxlan.h ++++ b/include/net/vxlan.h +@@ -440,6 +440,15 @@ static inline __be32 vxlan_compute_rco(u + return vni_field; + } + ++/* ++ * vxlan_get_vni() ++ * Returns the vni corresponding to tunnel ++ */ ++static inline u32 vxlan_get_vni(struct vxlan_dev *vxlan_tun) ++{ ++ return be32_to_cpu(vxlan_tun->cfg.vni); ++} ++ + static inline unsigned short vxlan_get_sk_family(struct vxlan_sock *vs) + { + return vs->sock->sk->sk_family; +--- a/include/uapi/linux/in.h ++++ b/include/uapi/linux/in.h +@@ -63,6 +63,8 @@ enum { + #define IPPROTO_MTP IPPROTO_MTP + IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */ + #define IPPROTO_BEETPH IPPROTO_BEETPH ++ IPPROTO_ETHERIP = 97, /* ETHERIP protocol number */ ++#define IPPROTO_ETHERIP IPPROTO_ETHERIP + IPPROTO_ENCAP = 98, /* Encapsulation Header */ + #define IPPROTO_ENCAP IPPROTO_ENCAP + IPPROTO_PIM = 103, /* Protocol Independent Multicast */ +@@ -327,7 +329,7 @@ struct sockaddr_in { + #endif + + /* contains the htonl type stuff.. */ +-#include ++#include + + + #endif /* _UAPI_LINUX_IN_H */ +--- a/tools/include/uapi/linux/in.h ++++ b/tools/include/uapi/linux/in.h +@@ -63,6 +63,8 @@ enum { + #define IPPROTO_MTP IPPROTO_MTP + IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */ + #define IPPROTO_BEETPH IPPROTO_BEETPH ++ IPPROTO_ETHERIP = 97, /* ETHERIP protocol number */ ++#define IPPROTO_ETHERIP IPPROTO_ETHERIP + IPPROTO_ENCAP = 98, /* Encapsulation Header */ + #define IPPROTO_ENCAP IPPROTO_ENCAP + IPPROTO_PIM = 103, /* Protocol Independent Multicast */ +@@ -327,7 +329,7 @@ struct sockaddr_in { + #endif + + /* contains the htonl type stuff.. */ +-#include ++#include + + + #endif /* _UAPI_LINUX_IN_H */ +--- a/include/net/netns/conntrack.h ++++ b/include/net/netns/conntrack.h +@@ -26,6 +26,7 @@ struct nf_tcp_net { + unsigned int timeouts[TCP_CONNTRACK_TIMEOUT_MAX]; + u8 tcp_loose; + u8 tcp_be_liberal; ++ u8 tcp_no_window_check; + u8 tcp_max_retrans; + u8 tcp_ignore_invalid_rst; + #if IS_ENABLED(CONFIG_NF_FLOW_TABLE) +--- a/net/netfilter/nf_conntrack_proto_tcp.c ++++ b/net/netfilter/nf_conntrack_proto_tcp.c +@@ -515,11 +515,15 @@ tcp_in_window(struct nf_conn *ct, enum i + struct ip_ct_tcp *state = &ct->proto.tcp; + struct ip_ct_tcp_state *sender = &state->seen[dir]; + struct ip_ct_tcp_state *receiver = &state->seen[!dir]; ++ const struct nf_tcp_net *tn = nf_tcp_pernet(nf_ct_net(ct)); + __u32 seq, ack, sack, end, win, swin; + bool in_recv_win, seq_ok; + s32 receiver_offset; + u16 win_raw; + ++ if (tn->tcp_no_window_check) ++ return NFCT_TCP_ACCEPT; ++ + /* + * Get the required data from the packet. + */ +@@ -1285,7 +1289,7 @@ int nf_conntrack_tcp_packet(struct nf_co + IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED && + timeouts[new_state] > timeouts[TCP_CONNTRACK_UNACK]) + timeout = timeouts[TCP_CONNTRACK_UNACK]; +- else if (ct->proto.tcp.last_win == 0 && ++ else if (!tn->tcp_no_window_check && ct->proto.tcp.last_win == 0 && + timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS]) + timeout = timeouts[TCP_CONNTRACK_RETRANS]; + else +@@ -1601,6 +1605,9 @@ void nf_conntrack_tcp_init_net(struct ne + */ + tn->tcp_be_liberal = 0; + ++ /* Skip Windows Check */ ++ tn->tcp_no_window_check = 0; ++ + /* If it's non-zero, we turn off RST sequence number check */ + tn->tcp_ignore_invalid_rst = 0; + +--- a/net/netfilter/nf_conntrack_standalone.c ++++ b/net/netfilter/nf_conntrack_standalone.c +@@ -633,6 +633,7 @@ enum nf_ct_sysctl_index { + #endif + NF_SYSCTL_CT_PROTO_TCP_LOOSE, + NF_SYSCTL_CT_PROTO_TCP_LIBERAL, ++ NF_SYSCTL_CT_PROTO_TCP_NO_WINDOW_CHECK, + NF_SYSCTL_CT_PROTO_TCP_IGNORE_INVALID_RST, + NF_SYSCTL_CT_PROTO_TCP_MAX_RETRANS, + NF_SYSCTL_CT_PROTO_TIMEOUT_UDP, +@@ -840,6 +841,14 @@ static struct ctl_table nf_ct_sysctl_tab + .extra1 = SYSCTL_ZERO, + .extra2 = SYSCTL_ONE, + }, ++ [NF_SYSCTL_CT_PROTO_TCP_NO_WINDOW_CHECK] = { ++ .procname = "nf_conntrack_tcp_no_window_check", ++ .maxlen = sizeof(u8), ++ .mode = 0644, ++ .proc_handler = proc_dou8vec_minmax, ++ .extra1 = SYSCTL_ZERO, ++ .extra2 = SYSCTL_ONE, ++ }, + [NF_SYSCTL_CT_PROTO_TCP_IGNORE_INVALID_RST] = { + .procname = "nf_conntrack_tcp_ignore_invalid_rst", + .maxlen = sizeof(u8), +@@ -1050,6 +1059,7 @@ static void nf_conntrack_standalone_init + + XASSIGN(LOOSE, &tn->tcp_loose); + XASSIGN(LIBERAL, &tn->tcp_be_liberal); ++ XASSIGN(NO_WINDOW_CHECK, &tn->tcp_no_window_check); + XASSIGN(MAX_RETRANS, &tn->tcp_max_retrans); + XASSIGN(IGNORE_INVALID_RST, &tn->tcp_ignore_invalid_rst); + #undef XASSIGN diff --git a/target/linux/qualcommax/patches-6.6/0600-2-qca-nss-ecm-support-CORE-Fix-IPv6-user-route-change-event-calls.patch b/target/linux/qualcommax/patches-6.6/0600-2-qca-nss-ecm-support-CORE-Fix-IPv6-user-route-change-event-calls.patch new file mode 100644 index 00000000000000..e3081a79aafdbe --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0600-2-qca-nss-ecm-support-CORE-Fix-IPv6-user-route-change-event-calls.patch @@ -0,0 +1,87 @@ +From ce18a6fdff6a39a01111d74f513d2ef66142047c Mon Sep 17 00:00:00 2001 +From: Murat Sezgin +Date: Wed, 5 Aug 2020 13:21:27 -0700 +Subject: [PATCH 246/281] net:ipv6: Fix IPv6 user route change event calls + +These events should be called only when the route table is +changed by the userspace. So, we should call them in the +ioctl and the netlink message handler function. + +Change-Id: If7ec615014cfc79d5fa72878e49eaf99c2560c32 +Signed-off-by: Murat Sezgin +--- + net/ipv6/route.c | 31 +++++++++++++++++++++---------- + 1 file changed, 21 insertions(+), 10 deletions(-) + +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -3867,10 +3867,6 @@ int ip6_route_add(struct fib6_config *cf + return PTR_ERR(rt); + + err = __ip6_ins_rt(rt, &cfg->fc_nlinfo, extack); +- if (!err) +- atomic_notifier_call_chain(&ip6route_chain, +- RTM_NEWROUTE, rt); +- + fib6_info_release(rt); + + return err; +@@ -3892,9 +3888,6 @@ static int __ip6_del_rt(struct fib6_info + err = fib6_del(rt, info); + spin_unlock_bh(&table->tb6_lock); + +- if (!err) +- atomic_notifier_call_chain(&ip6route_chain, +- RTM_DELROUTE, rt); + out: + fib6_info_release(rt); + return err; +@@ -4500,6 +4493,10 @@ int ipv6_route_ioctl(struct net *net, un + break; + } + rtnl_unlock(); ++ if (!err) ++ atomic_notifier_call_chain(&ip6route_chain, ++ (cmd == SIOCADDRT) ? RTM_NEWROUTE : RTM_DELROUTE, &cfg); ++ + return err; + } + +@@ -5518,11 +5515,17 @@ static int inet6_rtm_delroute(struct sk_ + } + + if (cfg.fc_mp) +- return ip6_route_multipath_del(&cfg, extack); ++ err = ip6_route_multipath_del(&cfg, extack); + else { + cfg.fc_delete_all_nh = 1; +- return ip6_route_del(&cfg, extack); ++ err = ip6_route_del(&cfg, extack); + } ++ ++ if (!err) ++ atomic_notifier_call_chain(&ip6route_chain, ++ RTM_DELROUTE, &cfg); ++ ++ return err; + } + + static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, +@@ -5539,9 +5542,15 @@ static int inet6_rtm_newroute(struct sk_ + cfg.fc_metric = IP6_RT_PRIO_USER; + + if (cfg.fc_mp) +- return ip6_route_multipath_add(&cfg, extack); ++ err = ip6_route_multipath_add(&cfg, extack); + else +- return ip6_route_add(&cfg, GFP_KERNEL, extack); ++ err = ip6_route_add(&cfg, GFP_KERNEL, extack); ++ ++ if (!err) ++ atomic_notifier_call_chain(&ip6route_chain, ++ RTM_NEWROUTE, &cfg); ++ ++ return err; + } + + /* add the overhead of this fib6_nh to nexthop_len */ diff --git a/target/linux/qualcommax/patches-6.6/0600-2-qca-nss-ecm-support-PPPOE-offload.patch b/target/linux/qualcommax/patches-6.6/0600-2-qca-nss-ecm-support-PPPOE-offload.patch new file mode 100644 index 00000000000000..e59290878db29e --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0600-2-qca-nss-ecm-support-PPPOE-offload.patch @@ -0,0 +1,600 @@ +--- a/drivers/net/ppp/ppp_generic.c ++++ b/drivers/net/ppp/ppp_generic.c +@@ -48,6 +48,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -254,6 +255,25 @@ struct ppp_net { + #define seq_before(a, b) ((s32)((a) - (b)) < 0) + #define seq_after(a, b) ((s32)((a) - (b)) > 0) + ++ ++/* ++ * Registration/Unregistration methods ++ * for PPP channel connect and disconnect event notifications. ++ */ ++RAW_NOTIFIER_HEAD(ppp_channel_connection_notifier_list); ++ ++void ppp_channel_connection_register_notify(struct notifier_block *nb) ++{ ++ raw_notifier_chain_register(&ppp_channel_connection_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(ppp_channel_connection_register_notify); ++ ++void ppp_channel_connection_unregister_notify(struct notifier_block *nb) ++{ ++ raw_notifier_chain_unregister(&ppp_channel_connection_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(ppp_channel_connection_unregister_notify); ++ + /* Prototypes. */ + static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf, + struct file *file, unsigned int cmd, unsigned long arg); +@@ -3453,7 +3473,10 @@ ppp_connect_channel(struct channel *pch, + struct ppp_net *pn; + int ret = -ENXIO; + int hdrlen; ++ int ppp_proto; ++ int version; + ++ int notify = 0; + pn = ppp_pernet(pch->chan_net); + + mutex_lock(&pn->all_ppp_mutex); +@@ -3485,13 +3508,40 @@ ppp_connect_channel(struct channel *pch, + ++ppp->n_channels; + pch->ppp = ppp; + refcount_inc(&ppp->file.refcnt); ++ ++ /* Set the netdev priv flag if the prototype ++ * is L2TP or PPTP. Return success in all cases ++ */ ++ if (!pch->chan) ++ goto out2; ++ ++ ppp_proto = ppp_channel_get_protocol(pch->chan); ++ if (ppp_proto == PX_PROTO_PPTP) { ++ ppp->dev->priv_flags_ext |= IFF_EXT_PPP_PPTP; ++ } else if (ppp_proto == PX_PROTO_OL2TP) { ++ version = ppp_channel_get_proto_version(pch->chan); ++ if (version == 2) ++ ppp->dev->priv_flags_ext |= IFF_EXT_PPP_L2TPV2; ++ else if (version == 3) ++ ppp->dev->priv_flags_ext |= IFF_EXT_PPP_L2TPV3; ++ } ++ notify = 1; ++ ++ out2: + ppp_unlock(ppp); + ret = 0; +- + outl: + write_unlock_bh(&pch->upl); + out: + mutex_unlock(&pn->all_ppp_mutex); ++ ++ if (notify && ppp && ppp->dev) { ++ dev_hold(ppp->dev); ++ raw_notifier_call_chain(&ppp_channel_connection_notifier_list, ++ PPP_CHANNEL_CONNECT, ppp->dev); ++ dev_put(ppp->dev); ++ } ++ + return ret; + } + +@@ -3509,6 +3559,13 @@ ppp_disconnect_channel(struct channel *p + pch->ppp = NULL; + write_unlock_bh(&pch->upl); + if (ppp) { ++ if (ppp->dev) { ++ dev_hold(ppp->dev); ++ raw_notifier_call_chain(&ppp_channel_connection_notifier_list, ++ PPP_CHANNEL_DISCONNECT, ppp->dev); ++ dev_put(ppp->dev); ++ } ++ + /* remove it from the ppp unit's list */ + ppp_lock(ppp); + list_del(&pch->clist); +@@ -3588,6 +3645,222 @@ static void *unit_find(struct idr *p, in + return idr_find(p, n); + } + ++/* Updates the PPP interface statistics. */ ++void ppp_update_stats(struct net_device *dev, unsigned long rx_packets, ++ unsigned long rx_bytes, unsigned long tx_packets, ++ unsigned long tx_bytes, unsigned long rx_errors, ++ unsigned long tx_errors, unsigned long rx_dropped, ++ unsigned long tx_dropped) ++{ ++ struct ppp *ppp; ++ ++ if (!dev) ++ return; ++ ++ if (dev->type != ARPHRD_PPP) ++ return; ++ ++ ppp = netdev_priv(dev); ++ ++ ppp_xmit_lock(ppp); ++ ppp->stats64.tx_packets += tx_packets; ++ ppp->stats64.tx_bytes += tx_bytes; ++ ppp->dev->stats.tx_errors += tx_errors; ++ ppp->dev->stats.tx_dropped += tx_dropped; ++ if (tx_packets) ++ ppp->last_xmit = jiffies; ++ ppp_xmit_unlock(ppp); ++ ++ ppp_recv_lock(ppp); ++ ppp->stats64.rx_packets += rx_packets; ++ ppp->stats64.rx_bytes += rx_bytes; ++ ppp->dev->stats.rx_errors += rx_errors; ++ ppp->dev->stats.rx_dropped += rx_dropped; ++ if (rx_packets) ++ ppp->last_recv = jiffies; ++ ppp_recv_unlock(ppp); ++} ++ ++/* Returns >0 if the device is a multilink PPP netdevice, 0 if not or < 0 if ++ * the device is not PPP. ++ */ ++int ppp_is_multilink(struct net_device *dev) ++{ ++ struct ppp *ppp; ++ unsigned int flags; ++ ++ if (!dev) ++ return -1; ++ ++ if (dev->type != ARPHRD_PPP) ++ return -1; ++ ++ ppp = netdev_priv(dev); ++ ppp_lock(ppp); ++ flags = ppp->flags; ++ ppp_unlock(ppp); ++ ++ if (flags & SC_MULTILINK) ++ return 1; ++ ++ return 0; ++} ++EXPORT_SYMBOL(ppp_is_multilink); ++ ++/* ppp_channel_get_protocol() ++ * Call this to obtain the underlying protocol of the PPP channel, ++ * e.g. PX_PROTO_OE ++ * ++ * NOTE: Some channels do not use PX sockets so the protocol value may be very ++ * different for them. ++ * NOTE: -1 indicates failure. ++ * NOTE: Once you know the channel protocol you may then either cast 'chan' to ++ * its sub-class or use the channel protocol specific API's as provided by that ++ * channel sub type. ++ */ ++int ppp_channel_get_protocol(struct ppp_channel *chan) ++{ ++ if (!chan->ops->get_channel_protocol) ++ return -1; ++ ++ return chan->ops->get_channel_protocol(chan); ++} ++EXPORT_SYMBOL(ppp_channel_get_protocol); ++ ++/* ppp_channel_get_proto_version() ++ * Call this to get channel protocol version ++ */ ++int ppp_channel_get_proto_version(struct ppp_channel *chan) ++{ ++ if (!chan->ops->get_channel_protocol_ver) ++ return -1; ++ ++ return chan->ops->get_channel_protocol_ver(chan); ++} ++EXPORT_SYMBOL(ppp_channel_get_proto_version); ++ ++/* ppp_channel_hold() ++ * Call this to hold a channel. ++ * ++ * Returns true on success or false if the hold could not happen. ++ * ++ * NOTE: chan must be protected against destruction during this call - ++ * either by correct locking etc. or because you already have an implicit ++ * or explicit hold to the channel already and this is an additional hold. ++ */ ++bool ppp_channel_hold(struct ppp_channel *chan) ++{ ++ if (!chan->ops->hold) ++ return false; ++ ++ chan->ops->hold(chan); ++ return true; ++} ++EXPORT_SYMBOL(ppp_channel_hold); ++ ++/* ppp_channel_release() ++ * Call this to release a hold you have upon a channel ++ */ ++void ppp_channel_release(struct ppp_channel *chan) ++{ ++ chan->ops->release(chan); ++} ++EXPORT_SYMBOL(ppp_channel_release); ++ ++/* Check if ppp xmit lock is on hold */ ++bool ppp_is_xmit_locked(struct net_device *dev) ++{ ++ struct ppp *ppp; ++ ++ if (!dev) ++ return false; ++ ++ if (dev->type != ARPHRD_PPP) ++ return false; ++ ++ ppp = netdev_priv(dev); ++ if (!ppp) ++ return false; ++ ++ if (spin_is_locked(&(ppp)->wlock)) ++ return true; ++ ++ return false; ++} ++EXPORT_SYMBOL(ppp_is_xmit_locked); ++ ++/* ppp_hold_channels() ++ * Returns the PPP channels of the PPP device, storing each one into ++ * channels[]. ++ * ++ * channels[] has chan_sz elements. ++ * This function returns the number of channels stored, up to chan_sz. ++ * It will return < 0 if the device is not PPP. ++ * ++ * You MUST release the channels using ppp_release_channels(). ++ */ ++int ppp_hold_channels(struct net_device *dev, struct ppp_channel *channels[], ++ unsigned int chan_sz) ++{ ++ struct ppp *ppp; ++ int c; ++ struct channel *pch; ++ ++ if (!dev) ++ return -1; ++ ++ if (dev->type != ARPHRD_PPP) ++ return -1; ++ ++ ppp = netdev_priv(dev); ++ ++ c = 0; ++ ppp_lock(ppp); ++ list_for_each_entry(pch, &ppp->channels, clist) { ++ struct ppp_channel *chan; ++ ++ if (!pch->chan) { ++ /* Channel is going / gone away */ ++ continue; ++ } ++ ++ if (c == chan_sz) { ++ /* No space to record channel */ ++ ppp_unlock(ppp); ++ return c; ++ } ++ ++ /* Hold the channel, if supported */ ++ chan = pch->chan; ++ if (!chan->ops->hold) ++ continue; ++ ++ chan->ops->hold(chan); ++ ++ /* Record the channel */ ++ channels[c++] = chan; ++ } ++ ppp_unlock(ppp); ++ return c; ++} ++EXPORT_SYMBOL(ppp_hold_channels); ++ ++/* ppp_release_channels() ++ * Releases channels ++ */ ++void ppp_release_channels(struct ppp_channel *channels[], unsigned int chan_sz) ++{ ++ unsigned int c; ++ ++ for (c = 0; c < chan_sz; ++c) { ++ struct ppp_channel *chan; ++ ++ chan = channels[c]; ++ chan->ops->release(chan); ++ } ++} ++EXPORT_SYMBOL(ppp_release_channels); ++ + /* Module/initialization stuff */ + + module_init(ppp_init); +@@ -3604,6 +3877,7 @@ EXPORT_SYMBOL(ppp_input_error); + EXPORT_SYMBOL(ppp_output_wakeup); + EXPORT_SYMBOL(ppp_register_compressor); + EXPORT_SYMBOL(ppp_unregister_compressor); ++EXPORT_SYMBOL(ppp_update_stats); + MODULE_LICENSE("GPL"); + MODULE_ALIAS_CHARDEV(PPP_MAJOR, 0); + MODULE_ALIAS_RTNL_LINK("ppp"); +--- a/drivers/net/ppp/pppoe.c ++++ b/drivers/net/ppp/pppoe.c +@@ -62,6 +62,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -87,7 +88,7 @@ + static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb); + + static const struct proto_ops pppoe_ops; +-static const struct ppp_channel_ops pppoe_chan_ops; ++static const struct pppoe_channel_ops pppoe_chan_ops; + + /* per-net private data for this module */ + static unsigned int pppoe_net_id __read_mostly; +@@ -692,7 +693,7 @@ static int pppoe_connect(struct socket * + + po->chan.mtu = dev->mtu - sizeof(struct pppoe_hdr) - 2; + po->chan.private = sk; +- po->chan.ops = &pppoe_chan_ops; ++ po->chan.ops = (struct ppp_channel_ops *)&pppoe_chan_ops; + + error = ppp_register_net_channel(dev_net(dev), &po->chan); + if (error) { +@@ -995,9 +996,80 @@ static int pppoe_fill_forward_path(struc + return 0; + } + +-static const struct ppp_channel_ops pppoe_chan_ops = { +- .start_xmit = pppoe_xmit, +- .fill_forward_path = pppoe_fill_forward_path, ++/************************************************************************ ++ * ++ * function called by generic PPP driver to hold channel ++ * ++ ***********************************************************************/ ++static void pppoe_hold_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_hold(sk); ++} ++ ++/************************************************************************ ++ * ++ * function called by generic PPP driver to release channel ++ * ++ ***********************************************************************/ ++static void pppoe_release_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_put(sk); ++} ++ ++/************************************************************************ ++ * ++ * function called to get the channel protocol type ++ * ++ ***********************************************************************/ ++static int pppoe_get_channel_protocol(struct ppp_channel *chan) ++{ ++ return PX_PROTO_OE; ++} ++ ++/************************************************************************ ++ * ++ * function called to get the PPPoE channel addressing ++ * NOTE: This function returns a HOLD to the netdevice ++ * ++ ***********************************************************************/ ++static int pppoe_get_addressing(struct ppp_channel *chan, ++ struct pppoe_opt *addressing) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ struct pppox_sock *po = pppox_sk(sk); ++ int err = 0; ++ ++ *addressing = po->proto.pppoe; ++ if (!addressing->dev) ++ return -ENODEV; ++ ++ dev_hold(addressing->dev); ++ return err; ++} ++ ++/* pppoe_channel_addressing_get() ++ * Return PPPoE channel specific addressing information. ++ */ ++int pppoe_channel_addressing_get(struct ppp_channel *chan, ++ struct pppoe_opt *addressing) ++{ ++ return pppoe_get_addressing(chan, addressing); ++} ++EXPORT_SYMBOL(pppoe_channel_addressing_get); ++ ++static const struct pppoe_channel_ops pppoe_chan_ops = { ++ /* PPPoE specific channel ops */ ++ .get_addressing = pppoe_get_addressing, ++ /* General ppp channel ops */ ++ .ops.start_xmit = pppoe_xmit, ++ .ops.get_channel_protocol = pppoe_get_channel_protocol, ++ .ops.hold = pppoe_hold_chan, ++ .ops.release = pppoe_release_chan, ++ .ops.fill_forward_path = pppoe_fill_forward_path, + }; + + static int pppoe_recvmsg(struct socket *sock, struct msghdr *m, +--- a/include/linux/if_pppox.h ++++ b/include/linux/if_pppox.h +@@ -91,4 +91,17 @@ enum { + PPPOX_DEAD = 16 /* dead, useless, please clean me up!*/ + }; + ++/* ++ * PPPoE Channel specific operations ++ */ ++struct pppoe_channel_ops { ++ /* Must be first - general to all PPP channels */ ++ struct ppp_channel_ops ops; ++ int (*get_addressing)(struct ppp_channel *, struct pppoe_opt *); ++}; ++ ++/* Return PPPoE channel specific addressing information */ ++extern int pppoe_channel_addressing_get(struct ppp_channel *chan, ++ struct pppoe_opt *addressing); ++ + #endif /* !(__LINUX_IF_PPPOX_H) */ +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -1762,6 +1762,36 @@ enum netdev_priv_flags { + IFF_NO_IP_ALIGN = BIT_ULL(34), + }; + ++/** ++ * enum netdev_priv_flags_ext - &struct net_device priv_flags_ext ++ * ++ * These flags are used to check for device type and can be ++ * set and used by the drivers ++ * ++ * @IFF_EXT_TUN_TAP: device is a TUN/TAP device ++ * @IFF_EXT_PPP_L2TPV2: device is a L2TPV2 device ++ * @IFF_EXT_PPP_L2TPV3: device is a L2TPV3 device ++ * @IFF_EXT_PPP_PPTP: device is a PPTP device ++ * @IFF_EXT_GRE_V4_TAP: device is a GRE IPv4 TAP device ++ * @IFF_EXT_GRE_V6_TAP: device is a GRE IPv6 TAP device ++ * @IFF_EXT_IFB: device is an IFB device ++ * @IFF_EXT_MAPT: device is an MAPT device ++ * @IFF_EXT_HW_NO_OFFLOAD: device is an NON Offload device ++ * @IFF_EXT_L2TPV3: device is a L2TPV3 Ethernet device ++ */ ++enum netdev_priv_flags_ext { ++ IFF_EXT_TUN_TAP = 1<<0, ++ IFF_EXT_PPP_L2TPV2 = 1<<1, ++ IFF_EXT_PPP_L2TPV3 = 1<<2, ++ IFF_EXT_PPP_PPTP = 1<<3, ++ IFF_EXT_GRE_V4_TAP = 1<<4, ++ IFF_EXT_GRE_V6_TAP = 1<<5, ++ IFF_EXT_IFB = 1<<6, ++ IFF_EXT_MAPT = 1<<7, ++ IFF_EXT_HW_NO_OFFLOAD = 1<<8, ++ IFF_EXT_ETH_L2TPV3 = 1<<9, ++}; ++ + #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN + #define IFF_EBRIDGE IFF_EBRIDGE + #define IFF_BONDING IFF_BONDING +@@ -2127,6 +2157,7 @@ struct net_device { + unsigned int flags; + xdp_features_t xdp_features; + unsigned long long priv_flags; ++ unsigned int priv_flags_ext; + const struct net_device_ops *netdev_ops; + const struct xdp_metadata_ops *xdp_metadata_ops; + int ifindex; +--- a/include/linux/ppp_channel.h ++++ b/include/linux/ppp_channel.h +@@ -19,6 +19,10 @@ + #include + #include + #include ++#include ++ ++#define PPP_CHANNEL_DISCONNECT 0 ++#define PPP_CHANNEL_CONNECT 1 + + struct net_device_path; + struct net_device_path_ctx; +@@ -30,9 +34,19 @@ struct ppp_channel_ops { + int (*start_xmit)(struct ppp_channel *, struct sk_buff *); + /* Handle an ioctl call that has come in via /dev/ppp. */ + int (*ioctl)(struct ppp_channel *, unsigned int, unsigned long); ++ /* Get channel protocol type, one of PX_PROTO_XYZ or specific to ++ * the channel subtype ++ */ ++ int (*get_channel_protocol)(struct ppp_channel *); ++ /* Get channel protocol version */ ++ int (*get_channel_protocol_ver)(struct ppp_channel *); ++ /* Hold the channel from being destroyed */ ++ void (*hold)(struct ppp_channel *); ++ /* Release hold on the channel */ ++ void (*release)(struct ppp_channel *); + int (*fill_forward_path)(struct net_device_path_ctx *, +- struct net_device_path *, +- const struct ppp_channel *); ++ struct net_device_path *, ++ const struct ppp_channel *); + }; + + struct ppp_channel { +@@ -76,6 +90,51 @@ extern int ppp_unit_number(struct ppp_ch + /* Get the device name associated with a channel, or NULL if none */ + extern char *ppp_dev_name(struct ppp_channel *); + ++/* Call this to obtain the underlying protocol of the PPP channel, ++ * e.g. PX_PROTO_OE ++ */ ++extern int ppp_channel_get_protocol(struct ppp_channel *); ++ ++/* Call this get protocol version */ ++extern int ppp_channel_get_proto_version(struct ppp_channel *); ++ ++/* Call this to hold a channel */ ++extern bool ppp_channel_hold(struct ppp_channel *); ++ ++/* Call this to release a hold you have upon a channel */ ++extern void ppp_channel_release(struct ppp_channel *); ++ ++/* Release hold on PPP channels */ ++extern void ppp_release_channels(struct ppp_channel *channels[], ++ unsigned int chan_sz); ++ ++/* Hold PPP channels for the PPP device */ ++extern int ppp_hold_channels(struct net_device *dev, ++ struct ppp_channel *channels[], ++ unsigned int chan_sz); ++ ++/* Test if ppp xmit lock is locked */ ++extern bool ppp_is_xmit_locked(struct net_device *dev); ++ ++/* Test if the ppp device is a multi-link ppp device */ ++extern int ppp_is_multilink(struct net_device *dev); ++ ++/* Register the PPP channel connect notifier */ ++extern void ppp_channel_connection_register_notify(struct notifier_block *nb); ++ ++/* Unregister the PPP channel connect notifier */ ++extern void ppp_channel_connection_unregister_notify(struct notifier_block *nb); ++ ++/* Update statistics of the PPP net_device by incrementing related ++ * statistics field value with corresponding parameter ++ */ ++extern void ppp_update_stats(struct net_device *dev, unsigned long rx_packets, ++ unsigned long rx_bytes, unsigned long tx_packets, ++ unsigned long tx_bytes, unsigned long rx_errors, ++ unsigned long tx_errors, unsigned long rx_dropped, ++ unsigned long tx_dropped); ++ ++ + /* + * SMP locking notes: + * The channel code must ensure that when it calls ppp_unregister_channel, diff --git a/target/linux/qualcommax/patches-6.6/0600-3-qca-nss-ecm-support-net-bonding.patch b/target/linux/qualcommax/patches-6.6/0600-3-qca-nss-ecm-support-net-bonding.patch new file mode 100644 index 00000000000000..4e683e3a3e7e8e --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0600-3-qca-nss-ecm-support-net-bonding.patch @@ -0,0 +1,46 @@ +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -210,6 +210,7 @@ atomic_t netpoll_block_tx = ATOMIC_INIT( + #endif + + unsigned int bond_net_id __read_mostly; ++static unsigned long bond_id_mask = 0xFFFFFFF0; /* QCA NSS ECM bonding support */ + + static const struct flow_dissector_key flow_keys_bonding_keys[] = { + { +@@ -5872,6 +5873,11 @@ static void bond_destructor(struct net_d + if (bond->wq) + destroy_workqueue(bond->wq); + ++ /* QCA NSS ECM bonding support - Start */ ++ if (bond->id != (~0U)) ++ clear_bit(bond->id, &bond_id_mask); ++ /* QCA NSS ECM bonding support - End */ ++ + free_percpu(bond->rr_tx_counter); + } + +@@ -6421,6 +6427,13 @@ int bond_create(struct net *net, const c + + bond_work_init_all(bond); + ++ /* QCA NSS ECM bonding support - Start */ ++ bond->id = ~0U; ++ if (bond_id_mask != (~0UL)) { ++ bond->id = (u32)ffz(bond_id_mask); ++ set_bit(bond->id, &bond_id_mask); ++ } ++ /* QCA NSS ECM bonding support - End */ + out: + rtnl_unlock(); + return res; +--- a/include/net/bonding.h ++++ b/include/net/bonding.h +@@ -261,6 +261,7 @@ struct bonding { + spinlock_t ipsec_lock; + #endif /* CONFIG_XFRM_OFFLOAD */ + struct bpf_prog *xdp_prog; ++ u32 id;/* QCA NSS ECM bonding support */ + }; + + #define bond_slave_get_rcu(dev) \ diff --git a/target/linux/qualcommax/patches-6.6/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch b/target/linux/qualcommax/patches-6.6/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch new file mode 100644 index 00000000000000..e02e9090db8c4e --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0600-4-qca-nss-ecm-support-net-bonding-over-LAG-interface.patch @@ -0,0 +1,685 @@ +--- a/drivers/net/bonding/bond_3ad.c ++++ b/drivers/net/bonding/bond_3ad.c +@@ -116,6 +116,40 @@ static void ad_marker_response_received( + struct port *port); + static void ad_update_actor_keys(struct port *port, bool reset); + ++/* QCA NSS ECM bonding support - Start */ ++struct bond_cb __rcu *bond_cb; ++ ++int bond_register_cb(struct bond_cb *cb) ++{ ++ struct bond_cb *lag_cb; ++ ++ lag_cb = kzalloc(sizeof(*lag_cb), GFP_ATOMIC | __GFP_NOWARN); ++ if (!lag_cb) { ++ return -1; ++ } ++ ++ memcpy((void *)lag_cb, (void *)cb, sizeof(*cb)); ++ ++ rcu_read_lock(); ++ rcu_assign_pointer(bond_cb, lag_cb); ++ rcu_read_unlock(); ++ return 0; ++} ++EXPORT_SYMBOL(bond_register_cb); ++ ++void bond_unregister_cb(void) ++{ ++ struct bond_cb *lag_cb_main; ++ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ rcu_assign_pointer(bond_cb, NULL); ++ rcu_read_unlock(); ++ ++ kfree(lag_cb_main); ++} ++EXPORT_SYMBOL(bond_unregister_cb); ++/* QCA NSS ECM bonding support - End */ + + /* ================= api to bonding and kernel code ================== */ + +@@ -1073,7 +1107,31 @@ static void ad_mux_machine(struct port * + ad_disable_collecting_distributing(port, + update_slave_arr); + port->ntt = true; ++ ++ /* QCA NSS ECM bonding support - Start */ ++ /* Send a notificaton about change in state of this ++ * port. We only want to handle case where port moves ++ * from AD_MUX_COLLECTING_DISTRIBUTING -> ++ * AD_MUX_ATTACHED. ++ */ ++ if (bond_slave_is_up(port->slave) && ++ (last_state == AD_MUX_COLLECTING_DISTRIBUTING)) { ++ struct bond_cb *lag_cb_main; ++ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ if (lag_cb_main && ++ lag_cb_main->bond_cb_link_down) { ++ struct net_device *dev; ++ ++ dev = port->slave->dev; ++ lag_cb_main->bond_cb_link_down(dev); ++ } ++ rcu_read_unlock(); ++ } ++ + break; ++ /* QCA NSS ECM bonding support - End */ + case AD_MUX_COLLECTING_DISTRIBUTING: + port->actor_oper_port_state |= LACP_STATE_COLLECTING; + port->actor_oper_port_state |= LACP_STATE_DISTRIBUTING; +@@ -1917,6 +1975,7 @@ static void ad_enable_collecting_distrib + bool *update_slave_arr) + { + if (port->aggregator->is_active) { ++ struct bond_cb *lag_cb_main; /* QCA NSS ECM bonding support */ + slave_dbg(port->slave->bond->dev, port->slave->dev, + "Enabling port %d (LAG %d)\n", + port->actor_port_number, +@@ -1924,6 +1983,16 @@ static void ad_enable_collecting_distrib + __enable_port(port); + /* Slave array needs update */ + *update_slave_arr = true; ++ ++ /* QCA NSS ECM bonding support - Start */ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ ++ if (lag_cb_main && lag_cb_main->bond_cb_link_up) ++ lag_cb_main->bond_cb_link_up(port->slave->dev); ++ ++ rcu_read_unlock(); ++ /* QCA NSS ECM bonding support - End */ + } + } + +@@ -2683,6 +2752,104 @@ int bond_3ad_get_active_agg_info(struct + return ret; + } + ++/* QCA NSS ECM bonding support - Start */ ++/* bond_3ad_get_tx_dev - Calculate egress interface for a given packet, ++ * for a LAG that is configured in 802.3AD mode ++ * @skb: pointer to skb to be egressed ++ * @src_mac: pointer to source L2 address ++ * @dst_mac: pointer to destination L2 address ++ * @src: pointer to source L3 address ++ * @dst: pointer to destination L3 address ++ * @protocol: L3 protocol id from L2 header ++ * @bond_dev: pointer to bond master device ++ * ++ * If @skb is NULL, bond_xmit_hash is used to calculate hash using L2/L3 ++ * addresses. ++ * ++ * Returns: Either valid slave device, or NULL otherwise ++ */ ++struct net_device *bond_3ad_get_tx_dev(struct sk_buff *skb, u8 *src_mac, ++ u8 *dst_mac, void *src, ++ void *dst, u16 protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr) ++{ ++ struct bonding *bond = netdev_priv(bond_dev); ++ struct aggregator *agg; ++ struct ad_info ad_info; ++ struct list_head *iter; ++ struct slave *slave; ++ struct slave *first_ok_slave = NULL; ++ u32 hash = 0; ++ int slaves_in_agg; ++ int slave_agg_no = 0; ++ int agg_id; ++ ++ if (__bond_3ad_get_active_agg_info(bond, &ad_info)) { ++ pr_debug("%s: Error: __bond_3ad_get_active_agg_info failed\n", ++ bond_dev->name); ++ return NULL; ++ } ++ ++ slaves_in_agg = ad_info.ports; ++ agg_id = ad_info.aggregator_id; ++ ++ if (slaves_in_agg == 0) { ++ pr_debug("%s: Error: active aggregator is empty\n", ++ bond_dev->name); ++ return NULL; ++ } ++ ++ if (skb) { ++ hash = bond_xmit_hash(bond, skb); ++ slave_agg_no = hash % slaves_in_agg; ++ } else { ++ if (bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER23 && ++ bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER2 && ++ bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER34) { ++ pr_debug("%s: Error: Unsupported hash policy for 802.3AD fast path\n", ++ bond_dev->name); ++ return NULL; ++ } ++ ++ hash = bond_xmit_hash_without_skb(src_mac, dst_mac, ++ src, dst, protocol, ++ bond_dev, layer4hdr); ++ slave_agg_no = hash % slaves_in_agg; ++ } ++ ++ bond_for_each_slave_rcu(bond, slave, iter) { ++ agg = SLAVE_AD_INFO(slave)->port.aggregator; ++ if (!agg || agg->aggregator_identifier != agg_id) ++ continue; ++ ++ if (slave_agg_no >= 0) { ++ if (!first_ok_slave && bond_slave_can_tx(slave)) ++ first_ok_slave = slave; ++ slave_agg_no--; ++ continue; ++ } ++ ++ if (bond_slave_can_tx(slave)) ++ return slave->dev; ++ } ++ ++ if (slave_agg_no >= 0) { ++ pr_err("%s: Error: Couldn't find a slave to tx on for aggregator ID %d\n", ++ bond_dev->name, agg_id); ++ return NULL; ++ } ++ ++ /* we couldn't find any suitable slave after the agg_no, so use the ++ * first suitable found, if found. ++ */ ++ if (first_ok_slave) ++ return first_ok_slave->dev; ++ ++ return NULL; ++} ++/* QCA NSS ECM bonding support - End */ ++ + int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond, + struct slave *slave) + { +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -288,6 +288,21 @@ const char *bond_mode_name(int mode) + return names[mode]; + } + ++/* QCA NSS ECM bonding support */ ++int bond_get_id(struct net_device *bond_dev) ++{ ++ struct bonding *bond; ++ ++ if (!((bond_dev->priv_flags & IFF_BONDING) && ++ (bond_dev->flags & IFF_MASTER))) ++ return -EINVAL; ++ ++ bond = netdev_priv(bond_dev); ++ return bond->id; ++} ++EXPORT_SYMBOL(bond_get_id); ++/* QCA NSS ECM bonding support */ ++ + /** + * bond_dev_queue_xmit - Prepare skb for xmit. + * +@@ -1189,6 +1204,23 @@ void bond_change_active_slave(struct bon + if (BOND_MODE(bond) == BOND_MODE_8023AD) + bond_3ad_handle_link_change(new_active, BOND_LINK_UP); + ++ /* QCA NSS ECM bonding support - Start */ ++ if (bond->params.mode == BOND_MODE_XOR) { ++ struct bond_cb *lag_cb_main; ++ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ if (lag_cb_main && ++ lag_cb_main->bond_cb_link_up) { ++ struct net_device *dev; ++ ++ dev = new_active->dev; ++ lag_cb_main->bond_cb_link_up(dev); ++ } ++ rcu_read_unlock(); ++ } ++ /* QCA NSS ECM bonding support - End */ ++ + if (bond_is_lb(bond)) + bond_alb_handle_link_change(bond, new_active, BOND_LINK_UP); + } else { +@@ -1833,6 +1865,7 @@ int bond_enslave(struct net_device *bond + const struct net_device_ops *slave_ops = slave_dev->netdev_ops; + struct slave *new_slave = NULL, *prev_slave; + struct sockaddr_storage ss; ++ struct bond_cb *lag_cb_main; /* QCA NSS ECM bonding support */ + int link_reporting; + int res = 0, i; + +@@ -2278,6 +2311,15 @@ int bond_enslave(struct net_device *bond + bond_is_active_slave(new_slave) ? "an active" : "a backup", + new_slave->link != BOND_LINK_DOWN ? "an up" : "a down"); + ++ /* QCA NSS ECM bonding support - Start */ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ if (lag_cb_main && lag_cb_main->bond_cb_enslave) ++ lag_cb_main->bond_cb_enslave(slave_dev); ++ ++ rcu_read_unlock(); ++ /* QCA NSS ECM bonding support - End */ ++ + /* enslave is successful */ + bond_queue_slave_event(new_slave); + return 0; +@@ -2343,6 +2385,15 @@ err_undo_flags: + } + } + ++ /* QCA NSS ECM bonding support - Start */ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ if (lag_cb_main && lag_cb_main->bond_cb_enslave) ++ lag_cb_main->bond_cb_enslave(slave_dev); ++ ++ rcu_read_unlock(); ++ /* QCA NSS ECM bonding support - End */ ++ + return res; + } + +@@ -2364,6 +2415,7 @@ static int __bond_release_one(struct net + struct bonding *bond = netdev_priv(bond_dev); + struct slave *slave, *oldcurrent; + struct sockaddr_storage ss; ++ struct bond_cb *lag_cb_main; /* QCA NSS ECM bonding support */ + int old_flags = bond_dev->flags; + netdev_features_t old_features = bond_dev->features; + +@@ -2386,6 +2438,15 @@ static int __bond_release_one(struct net + + bond_set_slave_inactive_flags(slave, BOND_SLAVE_NOTIFY_NOW); + ++ /* QCA NSS ECM bonding support - Start */ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ if (lag_cb_main && lag_cb_main->bond_cb_release) ++ lag_cb_main->bond_cb_release(slave_dev); ++ ++ rcu_read_unlock(); ++ /* QCA NSS ECM bonding support - End */ ++ + bond_sysfs_slave_del(slave); + + /* recompute stats just before removing the slave */ +@@ -2708,6 +2769,8 @@ static void bond_miimon_commit(struct bo + struct slave *slave, *primary, *active; + bool do_failover = false; + struct list_head *iter; ++ struct net_device *slave_dev = NULL; /* QCA NSS ECM bonding support */ ++ struct bond_cb *lag_cb_main; /* QCA NSS ECM bonding support */ + + ASSERT_RTNL(); + +@@ -2747,6 +2810,12 @@ static void bond_miimon_commit(struct bo + bond_set_active_slave(slave); + } + ++ /* QCA NSS ECM bonding support - Start */ ++ if ((bond->params.mode == BOND_MODE_XOR) && ++ (!slave_dev)) ++ slave_dev = slave->dev; ++ /* QCA NSS ECM bonding support - End */ ++ + slave_info(bond->dev, slave->dev, "link status definitely up, %u Mbps %s duplex\n", + slave->speed == SPEED_UNKNOWN ? 0 : slave->speed, + slave->duplex ? "full" : "half"); +@@ -2795,6 +2864,16 @@ static void bond_miimon_commit(struct bo + unblock_netpoll_tx(); + } + ++ /* QCA NSS ECM bonding support - Start */ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ ++ if (slave_dev && lag_cb_main && lag_cb_main->bond_cb_link_up) ++ lag_cb_main->bond_cb_link_up(slave_dev); ++ ++ rcu_read_unlock(); ++ /* QCA NSS ECM bonding support - End */ ++ + bond_set_carrier(bond); + } + +@@ -4047,8 +4126,219 @@ static inline u32 bond_eth_hash(struct s + return 0; + + ep = (struct ethhdr *)(data + mhoff); +- return ep->h_dest[5] ^ ep->h_source[5] ^ be16_to_cpu(ep->h_proto); ++ return ep->h_dest[5] ^ ep->h_source[5]; /* QCA NSS ECM bonding support */ ++} ++ ++/* QCA NSS ECM bonding support - Start */ ++/* Extract the appropriate headers based on bond's xmit policy */ ++static bool bond_flow_dissect_without_skb(struct bonding *bond, ++ u8 *src_mac, u8 *dst_mac, ++ void *psrc, void *pdst, ++ u16 protocol, __be16 *layer4hdr, ++ struct flow_keys *fk) ++{ ++ u32 *src = NULL; ++ u32 *dst = NULL; ++ ++ fk->ports.ports = 0; ++ src = (uint32_t *)psrc; ++ dst = (uint32_t *)pdst; ++ ++ if (protocol == htons(ETH_P_IP)) { ++ /* V4 addresses and address type*/ ++ fk->addrs.v4addrs.src = src[0]; ++ fk->addrs.v4addrs.dst = dst[0]; ++ fk->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS; ++ } else if (protocol == htons(ETH_P_IPV6)) { ++ /* V6 addresses and address type*/ ++ memcpy(&fk->addrs.v6addrs.src, src, sizeof(struct in6_addr)); ++ memcpy(&fk->addrs.v6addrs.dst, dst, sizeof(struct in6_addr)); ++ fk->control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS; ++ } else { ++ return false; ++ } ++ if ((bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34) && ++ (layer4hdr)) ++ fk->ports.ports = *layer4hdr; ++ ++ return true; ++} ++ ++/* bond_xmit_hash_without_skb - Applies load balancing algorithm for a packet, ++ * to calculate hash for a given set of L2/L3 addresses. Does not ++ * calculate egress interface. ++ */ ++uint32_t bond_xmit_hash_without_skb(u8 *src_mac, u8 *dst_mac, ++ void *psrc, void *pdst, u16 protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr) ++{ ++ struct bonding *bond = netdev_priv(bond_dev); ++ struct flow_keys flow; ++ u32 hash = 0; ++ ++ if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER2 || ++ !bond_flow_dissect_without_skb(bond, src_mac, dst_mac, psrc, ++ pdst, protocol, layer4hdr, &flow)) ++ return (dst_mac[5] ^ src_mac[5]); ++ ++ if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER23) ++ hash = dst_mac[5] ^ src_mac[5]; ++ else if (layer4hdr) ++ hash = (__force u32)flow.ports.ports; ++ ++ hash ^= (__force u32)flow_get_u32_dst(&flow) ^ ++ (__force u32)flow_get_u32_src(&flow); ++ hash ^= (hash >> 16); ++ hash ^= (hash >> 8); ++ ++ return hash; ++} ++ ++/* bond_xor_get_tx_dev - Calculate egress interface for a given packet for a LAG ++ * that is configured in balance-xor mode ++ * @skb: pointer to skb to be egressed ++ * @src_mac: pointer to source L2 address ++ * @dst_mac: pointer to destination L2 address ++ * @src: pointer to source L3 address in network order ++ * @dst: pointer to destination L3 address in network order ++ * @protocol: L3 protocol ++ * @bond_dev: pointer to bond master device ++ * ++ * If @skb is NULL, bond_xmit_hash_without_skb is used to calculate hash using ++ * L2/L3 addresses. ++ * ++ * Returns: Either valid slave device, or NULL otherwise ++ */ ++static struct net_device *bond_xor_get_tx_dev(struct sk_buff *skb, ++ u8 *src_mac, u8 *dst_mac, ++ void *src, void *dst, ++ u16 protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr) ++{ ++ struct bonding *bond = netdev_priv(bond_dev); ++ int slave_cnt = READ_ONCE(bond->slave_cnt); ++ int slave_id = 0, i = 0; ++ u32 hash; ++ struct list_head *iter; ++ struct slave *slave; ++ ++ if (slave_cnt == 0) { ++ pr_debug("%s: Error: No slave is attached to the interface\n", ++ bond_dev->name); ++ return NULL; ++ } ++ ++ if (skb) { ++ hash = bond_xmit_hash(bond, skb); ++ slave_id = hash % slave_cnt; ++ } else { ++ if (bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER23 && ++ bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER2 && ++ bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER34) { ++ pr_debug("%s: Error: Unsupported hash policy for balance-XOR fast path\n", ++ bond_dev->name); ++ return NULL; ++ } ++ ++ hash = bond_xmit_hash_without_skb(src_mac, dst_mac, src, ++ dst, protocol, bond_dev, ++ layer4hdr); ++ slave_id = hash % slave_cnt; ++ } ++ ++ i = slave_id; ++ ++ /* Here we start from the slave with slave_id */ ++ bond_for_each_slave_rcu(bond, slave, iter) { ++ if (--i < 0) { ++ if (bond_slave_can_tx(slave)) ++ return slave->dev; ++ } ++ } ++ ++ /* Here we start from the first slave up to slave_id */ ++ i = slave_id; ++ bond_for_each_slave_rcu(bond, slave, iter) { ++ if (--i < 0) ++ break; ++ if (bond_slave_can_tx(slave)) ++ return slave->dev; ++ } ++ ++ return NULL; ++} ++ ++/* bond_get_tx_dev - Calculate egress interface for a given packet. ++ * ++ * Supports 802.3AD and balance-xor modes ++ * ++ * @skb: pointer to skb to be egressed, if valid ++ * @src_mac: pointer to source L2 address ++ * @dst_mac: pointer to destination L2 address ++ * @src: pointer to source L3 address in network order ++ * @dst: pointer to destination L3 address in network order ++ * @protocol: L3 protocol id from L2 header ++ * @bond_dev: pointer to bond master device ++ * ++ * Returns: Either valid slave device, or NULL for un-supported LAG modes ++ */ ++struct net_device *bond_get_tx_dev(struct sk_buff *skb, uint8_t *src_mac, ++ u8 *dst_mac, void *src, ++ void *dst, u16 protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr) ++{ ++ struct bonding *bond; ++ ++ if (!bond_dev) ++ return NULL; ++ ++ if (!((bond_dev->priv_flags & IFF_BONDING) && ++ (bond_dev->flags & IFF_MASTER))) ++ return NULL; ++ ++ bond = netdev_priv(bond_dev); ++ ++ switch (bond->params.mode) { ++ case BOND_MODE_XOR: ++ return bond_xor_get_tx_dev(skb, src_mac, dst_mac, ++ src, dst, protocol, ++ bond_dev, layer4hdr); ++ case BOND_MODE_8023AD: ++ return bond_3ad_get_tx_dev(skb, src_mac, dst_mac, ++ src, dst, protocol, ++ bond_dev, layer4hdr); ++ default: ++ return NULL; ++ } + } ++EXPORT_SYMBOL(bond_get_tx_dev); ++ ++/* In bond_xmit_xor() , we determine the output device by using a pre- ++ * determined xmit_hash_policy(), If the selected device is not enabled, ++ * find the next active slave. ++ */ ++static int bond_xmit_xor(struct sk_buff *skb, struct net_device *dev) ++{ ++ struct bonding *bond = netdev_priv(dev); ++ struct net_device *outdev; ++ ++ outdev = bond_xor_get_tx_dev(skb, NULL, NULL, NULL, ++ NULL, 0, dev, NULL); ++ if (!outdev) ++ goto out; ++ ++ bond_dev_queue_xmit(bond, skb, outdev); ++ goto final; ++out: ++ /* no suitable interface, frame not sent */ ++ dev_kfree_skb(skb); ++final: ++ return NETDEV_TX_OK; ++} ++/* QCA NSS ECM bonding support - End */ + + static bool bond_flow_ip(struct sk_buff *skb, struct flow_keys *fk, const void *data, + int hlen, __be16 l2_proto, int *nhoff, int *ip_proto, bool l34) +@@ -5177,15 +5467,18 @@ static netdev_tx_t bond_3ad_xor_xmit(str + struct net_device *dev) + { + struct bonding *bond = netdev_priv(dev); +- struct bond_up_slave *slaves; +- struct slave *slave; ++ /* QCA NSS ECM bonding support - Start */ ++ struct net_device *outdev = NULL; + +- slaves = rcu_dereference(bond->usable_slaves); +- slave = bond_xmit_3ad_xor_slave_get(bond, skb, slaves); +- if (likely(slave)) +- return bond_dev_queue_xmit(bond, skb, slave->dev); ++ outdev = bond_3ad_get_tx_dev(skb, NULL, NULL, NULL, ++ NULL, 0, dev, NULL); ++ if (!outdev) { ++ dev_kfree_skb(skb); ++ return NETDEV_TX_OK; ++ } + +- return bond_tx_drop(dev, skb); ++ return bond_dev_queue_xmit(bond, skb, outdev); ++ /* QCA NSS ECM bonding support - End */ + } + + /* in broadcast mode, we send everything to all usable interfaces. */ +@@ -5435,8 +5728,9 @@ static netdev_tx_t __bond_start_xmit(str + return bond_xmit_roundrobin(skb, dev); + case BOND_MODE_ACTIVEBACKUP: + return bond_xmit_activebackup(skb, dev); +- case BOND_MODE_8023AD: + case BOND_MODE_XOR: ++ return bond_xmit_xor(skb, dev); /* QCA NSS ECM bonding support */ ++ case BOND_MODE_8023AD: + return bond_3ad_xor_xmit(skb, dev); + case BOND_MODE_BROADCAST: + return bond_xmit_broadcast(skb, dev); +--- a/include/net/bond_3ad.h ++++ b/include/net/bond_3ad.h +@@ -302,8 +302,15 @@ int bond_3ad_lacpdu_recv(const struct sk + struct slave *slave); + int bond_3ad_set_carrier(struct bonding *bond); + void bond_3ad_update_lacp_rate(struct bonding *bond); ++/* QCA NSS ECM bonding support */ ++struct net_device *bond_3ad_get_tx_dev(struct sk_buff *skb, uint8_t *src_mac, ++ uint8_t *dst_mac, void *src, ++ void *dst, uint16_t protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr); ++/* QCA NSS ECM bonding support */ ++ + void bond_3ad_update_ad_actor_settings(struct bonding *bond); + int bond_3ad_stats_fill(struct sk_buff *skb, struct bond_3ad_stats *stats); + size_t bond_3ad_stats_size(void); + #endif /* _NET_BOND_3AD_H */ +- +--- a/include/net/bonding.h ++++ b/include/net/bonding.h +@@ -90,6 +90,8 @@ + #define BOND_XFRM_FEATURES (NETIF_F_HW_ESP | NETIF_F_HW_ESP_TX_CSUM | \ + NETIF_F_GSO_ESP) + ++extern struct bond_cb __rcu *bond_cb; /* QCA NSS ECM bonding support */ ++ + #ifdef CONFIG_NET_POLL_CONTROLLER + extern atomic_t netpoll_block_tx; + +@@ -653,6 +655,7 @@ struct bond_net { + + int bond_rcv_validate(const struct sk_buff *skb, struct bonding *bond, struct slave *slave); + netdev_tx_t bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); ++int bond_get_id(struct net_device *bond_dev); /* QCA NSS ECM bonding support */ + int bond_create(struct net *net, const char *name); + int bond_create_sysfs(struct bond_net *net); + void bond_destroy_sysfs(struct bond_net *net); +@@ -684,6 +687,13 @@ struct bond_vlan_tag *bond_verify_device + int level); + int bond_update_slave_arr(struct bonding *bond, struct slave *skipslave); + void bond_slave_arr_work_rearm(struct bonding *bond, unsigned long delay); ++/* QCA NSS ECM bonding support - Start */ ++uint32_t bond_xmit_hash_without_skb(uint8_t *src_mac, uint8_t *dst_mac, ++ void *psrc, void *pdst, uint16_t protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr); ++/* QCA NSS ECM bonding support - End */ ++ + void bond_work_init_all(struct bonding *bond); + + #ifdef CONFIG_PROC_FS +@@ -788,4 +798,18 @@ static inline netdev_tx_t bond_tx_drop(s + return NET_XMIT_DROP; + } + ++/* QCA NSS ECM bonding support - Start */ ++struct bond_cb { ++ void (*bond_cb_link_up)(struct net_device *slave); ++ void (*bond_cb_link_down)(struct net_device *slave); ++ void (*bond_cb_enslave)(struct net_device *slave); ++ void (*bond_cb_release)(struct net_device *slave); ++ void (*bond_cb_delete_by_slave)(struct net_device *slave); ++ void (*bond_cb_delete_by_mac)(uint8_t *mac_addr); ++}; ++ ++extern int bond_register_cb(struct bond_cb *cb); ++extern void bond_unregister_cb(void); ++/* QCA NSS ECM bonding support - End */ ++ + #endif /* _NET_BONDING_H */ diff --git a/target/linux/qualcommax/patches-6.6/0600-5-qca-nss-ecm-support-macvlan.patch b/target/linux/qualcommax/patches-6.6/0600-5-qca-nss-ecm-support-macvlan.patch new file mode 100644 index 00000000000000..29f7e96d791328 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0600-5-qca-nss-ecm-support-macvlan.patch @@ -0,0 +1,96 @@ +--- a/include/linux/if_macvlan.h ++++ b/include/linux/if_macvlan.h +@@ -15,6 +15,13 @@ struct macvlan_port; + #define MACVLAN_MC_FILTER_BITS 8 + #define MACVLAN_MC_FILTER_SZ (1 << MACVLAN_MC_FILTER_BITS) + ++/* QCA NSS ECM Support - Start */ ++/* ++ * Callback for updating interface statistics for macvlan flows offloaded from host CPU. ++ */ ++typedef void (*macvlan_offload_stats_update_cb_t)(struct net_device *dev, struct rtnl_link_stats64 *stats, bool update_mcast_rx_stats); ++/* QCA NSS ECM Support - End */ ++ + struct macvlan_dev { + struct net_device *dev; + struct list_head list; +@@ -35,6 +42,7 @@ struct macvlan_dev { + #ifdef CONFIG_NET_POLL_CONTROLLER + struct netpoll *netpoll; + #endif ++ macvlan_offload_stats_update_cb_t offload_stats_update; /* QCA NSS ECM support */ + }; + + static inline void macvlan_count_rx(const struct macvlan_dev *vlan, +@@ -107,4 +115,26 @@ static inline int macvlan_release_l2fw_o + macvlan->accel_priv = NULL; + return dev_uc_add(macvlan->lowerdev, dev->dev_addr); + } ++ ++/* QCA NSS ECM Support - Start */ ++#if IS_ENABLED(CONFIG_MACVLAN) ++static inline void ++macvlan_offload_stats_update(struct net_device *dev, ++ struct rtnl_link_stats64 *stats, ++ bool update_mcast_rx_stats) ++{ ++ struct macvlan_dev *macvlan = netdev_priv(dev); ++ ++ macvlan->offload_stats_update(dev, stats, update_mcast_rx_stats); ++} ++ ++static inline enum ++macvlan_mode macvlan_get_mode(struct net_device *dev) ++{ ++ struct macvlan_dev *macvlan = netdev_priv(dev); ++ ++ return macvlan->mode; ++} ++#endif ++/* QCA NSS ECM Support - End */ + #endif /* _LINUX_IF_MACVLAN_H */ +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -960,6 +960,34 @@ static void macvlan_uninit(struct net_de + macvlan_port_destroy(port->dev); + } + ++/* QCA NSS ECM Support - Start */ ++/* Update macvlan statistics processed by offload engines */ ++static void macvlan_dev_update_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *offl_stats, ++ bool update_mcast_rx_stats) ++{ ++ struct vlan_pcpu_stats *stats; ++ struct macvlan_dev *macvlan; ++ ++ /* Is this a macvlan? */ ++ if (!netif_is_macvlan(dev)) ++ return; ++ ++ macvlan = netdev_priv(dev); ++ stats = this_cpu_ptr(macvlan->pcpu_stats); ++ u64_stats_update_begin(&stats->syncp); ++ u64_stats_add(&stats->rx_packets, offl_stats->rx_packets); ++ u64_stats_add(&stats->rx_bytes, offl_stats->rx_bytes); ++ u64_stats_add(&stats->tx_packets, offl_stats->tx_packets); ++ u64_stats_add(&stats->tx_bytes, offl_stats->tx_bytes); ++ /* Update multicast statistics */ ++ if (unlikely(update_mcast_rx_stats)) { ++ u64_stats_add(&stats->rx_multicast, offl_stats->rx_packets); ++ } ++ u64_stats_update_end(&stats->syncp); ++} ++/* QCA NSS ECM Support - End */ ++ + static void macvlan_dev_get_stats64(struct net_device *dev, + struct rtnl_link_stats64 *stats) + { +@@ -1506,6 +1534,7 @@ int macvlan_common_newlink(struct net *s + vlan->dev = dev; + vlan->port = port; + vlan->set_features = MACVLAN_FEATURES; ++ vlan->offload_stats_update = macvlan_dev_update_stats; /* QCA NSS ECM Support */ + + vlan->mode = MACVLAN_MODE_VEPA; + if (data && data[IFLA_MACVLAN_MODE]) diff --git a/target/linux/qualcommax/patches-6.6/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch b/target/linux/qualcommax/patches-6.6/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch new file mode 100644 index 00000000000000..27650731a69612 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch @@ -0,0 +1,154 @@ +--- a/net/netfilter/Kconfig ++++ b/net/netfilter/Kconfig +@@ -174,6 +174,13 @@ config NF_CONNTRACK_TIMEOUT + + If unsure, say `N'. + ++config NF_CONNTRACK_DSCPREMARK_EXT ++ bool 'Connection tracking extension for dscp remark target' ++ depends on NETFILTER_ADVANCED ++ help ++ This option enables support for connection tracking extension ++ for dscp remark. ++ + config NF_CONNTRACK_TIMESTAMP + bool 'Connection tracking timestamping' + depends on NETFILTER_ADVANCED +--- a/include/net/netfilter/nf_conntrack_extend.h ++++ b/include/net/netfilter/nf_conntrack_extend.h +@@ -31,6 +31,10 @@ enum nf_ct_ext_id { + #if IS_ENABLED(CONFIG_NET_ACT_CT) + NF_CT_EXT_ACT_CT, + #endif ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ NF_CT_EXT_DSCPREMARK, /* QCA NSS ECM support */ ++#endif ++ + NF_CT_EXT_NUM, + }; + +--- a/net/netfilter/nf_conntrack_extend.c ++++ b/net/netfilter/nf_conntrack_extend.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + + #define NF_CT_EXT_PREALLOC 128u /* conntrack events are on by default */ +@@ -54,6 +55,9 @@ static const u8 nf_ct_ext_type_len[NF_CT + #if IS_ENABLED(CONFIG_NET_ACT_CT) + [NF_CT_EXT_ACT_CT] = sizeof(struct nf_conn_act_ct_ext), + #endif ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ [NF_CT_EXT_DSCPREMARK] = sizeof(struct nf_ct_dscpremark_ext), ++#endif + }; + + static __always_inline unsigned int total_extension_size(void) +@@ -86,6 +90,9 @@ static __always_inline unsigned int tota + #if IS_ENABLED(CONFIG_NET_ACT_CT) + + sizeof(struct nf_conn_act_ct_ext) + #endif ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ + sizeof(struct nf_ct_dscpremark_ext) ++#endif + ; + } + +--- a/net/netfilter/Makefile ++++ b/net/netfilter/Makefile +@@ -15,6 +15,7 @@ nf_conntrack-$(CONFIG_NF_CONNTRACK_OVS) + nf_conntrack-$(CONFIG_NF_CT_PROTO_DCCP) += nf_conntrack_proto_dccp.o + nf_conntrack-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o + nf_conntrack-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o ++nf_conntrack-$(CONFIG_NF_CONNTRACK_DSCPREMARK_EXT) += nf_conntrack_dscpremark_ext.o + ifeq ($(CONFIG_NF_CONNTRACK),m) + nf_conntrack-$(CONFIG_DEBUG_INFO_BTF_MODULES) += nf_conntrack_bpf.o + else ifeq ($(CONFIG_NF_CONNTRACK),y) +--- a/net/netfilter/nf_conntrack_core.c ++++ b/net/netfilter/nf_conntrack_core.c +@@ -45,6 +45,9 @@ + #include + #include + #include ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++#include ++#endif + #include + #include + #include +@@ -1740,6 +1743,9 @@ init_conntrack(struct net *net, struct n + nf_ct_acct_ext_add(ct, GFP_ATOMIC); + nf_ct_tstamp_ext_add(ct, GFP_ATOMIC); + nf_ct_labels_ext_add(ct); ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ nf_ct_dscpremark_ext_add(ct, GFP_ATOMIC); ++#endif + + #ifdef CONFIG_NF_CONNTRACK_EVENTS + ecache = tmpl ? nf_ct_ecache_find(tmpl) : NULL; +--- a/net/netfilter/xt_DSCP.c ++++ b/net/netfilter/xt_DSCP.c +@@ -15,6 +15,9 @@ + + #include + #include ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++#include ++#endif + + MODULE_AUTHOR("Harald Welte "); + MODULE_DESCRIPTION("Xtables: DSCP/TOS field modification"); +@@ -31,6 +34,10 @@ dscp_tg(struct sk_buff *skb, const struc + { + const struct xt_DSCP_info *dinfo = par->targinfo; + u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT; ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ struct nf_conn *ct; ++ enum ip_conntrack_info ctinfo; ++#endif + + if (dscp != dinfo->dscp) { + if (skb_ensure_writable(skb, sizeof(struct iphdr))) +@@ -39,6 +46,13 @@ dscp_tg(struct sk_buff *skb, const struc + ipv4_change_dsfield(ip_hdr(skb), XT_DSCP_ECN_MASK, + dinfo->dscp << XT_DSCP_SHIFT); + ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ ct = nf_ct_get(skb, &ctinfo); ++ if (!ct) ++ return XT_CONTINUE; ++ ++ nf_conntrack_dscpremark_ext_set_dscp_rule_valid(ct); ++#endif + } + return XT_CONTINUE; + } +@@ -48,13 +62,24 @@ dscp_tg6(struct sk_buff *skb, const stru + { + const struct xt_DSCP_info *dinfo = par->targinfo; + u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT; +- ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ struct nf_conn *ct; ++ enum ip_conntrack_info ctinfo; ++#endif + if (dscp != dinfo->dscp) { + if (skb_ensure_writable(skb, sizeof(struct ipv6hdr))) + return NF_DROP; + + ipv6_change_dsfield(ipv6_hdr(skb), XT_DSCP_ECN_MASK, + dinfo->dscp << XT_DSCP_SHIFT); ++ ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ ct = nf_ct_get(skb, &ctinfo); ++ if (!ct) ++ return XT_CONTINUE; ++ ++ nf_conntrack_dscpremark_ext_set_dscp_rule_valid(ct); ++#endif + } + return XT_CONTINUE; + } diff --git a/target/linux/qualcommax/patches-6.6/0601-1-qca-add-nss-bridge-mgr-support.patch b/target/linux/qualcommax/patches-6.6/0601-1-qca-add-nss-bridge-mgr-support.patch new file mode 100644 index 00000000000000..dcfd78d5932a6a --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0601-1-qca-add-nss-bridge-mgr-support.patch @@ -0,0 +1,92 @@ +From 3c17a0e1112be70071e98d5208da5b55dcec20a6 Mon Sep 17 00:00:00 2001 +From: Simon Casey +Date: Wed, 2 Feb 2022 19:37:29 +0100 +Subject: [PATCH] Update 607-qca-add-add-nss-bridge-mgr-support.patch for kernel 5.15 + +--- + include/linux/if_bridge.h | 4 ++++ + net/bridge/br_fdb.c | 25 +++++++++++++++++++++---- + 2 files changed, 25 insertions(+), 4 deletions(-) + +--- a/include/linux/if_bridge.h ++++ b/include/linux/if_bridge.h +@@ -254,4 +254,8 @@ typedef struct net_bridge_port *br_get_d + extern br_get_dst_hook_t __rcu *br_get_dst_hook; + /* QCA NSS ECM support - End */ + ++/* QCA NSS bridge-mgr support - Start */ ++extern struct net_device *br_fdb_bridge_dev_get_and_hold(struct net_bridge *br); ++/* QCA NSS bridge-mgr support - End */ ++ + #endif +--- a/net/bridge/br_fdb.c ++++ b/net/bridge/br_fdb.c +@@ -576,7 +576,7 @@ void br_fdb_cleanup(struct work_struct * + unsigned long delay = hold_time(br); + unsigned long work_delay = delay; + unsigned long now = jiffies; +- u8 mac_addr[6]; /* QCA NSS ECM support */ ++ struct br_fdb_event fdb_event; /* QCA NSS bridge-mgr support */ + + /* this part is tricky, in order to avoid blocking learning and + * consequently forwarding, we rely on rcu to delete objects with +@@ -604,12 +604,13 @@ void br_fdb_cleanup(struct work_struct * + } else { + spin_lock_bh(&br->hash_lock); + if (!hlist_unhashed(&f->fdb_node)) { +- ether_addr_copy(mac_addr, f->key.addr.addr); ++ memset(&fdb_event, 0, sizeof(fdb_event)); ++ ether_addr_copy(fdb_event.addr, f->key.addr.addr); + fdb_delete(br, f, true); + /* QCA NSS ECM support - Start */ + atomic_notifier_call_chain( + &br_fdb_update_notifier_list, 0, +- (void *)mac_addr); ++ (void *)&fdb_event); + /* QCA NSS ECM support - End */ + } + spin_unlock_bh(&br->hash_lock); +@@ -907,10 +908,21 @@ static bool __fdb_mark_active(struct net + test_and_clear_bit(BR_FDB_NOTIFY_INACTIVE, &fdb->flags)); + } + ++/* QCA NSS bridge-mgr support - Start */ ++/* Get the bridge device */ ++struct net_device *br_fdb_bridge_dev_get_and_hold(struct net_bridge *br) ++{ ++ dev_hold(br->dev); ++ return br->dev; ++} ++EXPORT_SYMBOL_GPL(br_fdb_bridge_dev_get_and_hold); ++/* QCA NSS bridge-mgr support - End */ ++ + void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, + const unsigned char *addr, u16 vid, unsigned long flags) + { + struct net_bridge_fdb_entry *fdb; ++ struct br_fdb_event fdb_event; /* QCA NSS bridge-mgr support */ + + /* some users want to always flood. */ + if (hold_time(br) == 0) +@@ -936,6 +948,12 @@ void br_fdb_update(struct net_bridge *br + if (unlikely(source != READ_ONCE(fdb->dst) && + !test_bit(BR_FDB_STICKY, &fdb->flags))) { + br_switchdev_fdb_notify(br, fdb, RTM_DELNEIGH); ++ /* QCA NSS bridge-mgr support - Start */ ++ ether_addr_copy(fdb_event.addr, addr); ++ fdb_event.br = br; ++ fdb_event.orig_dev = fdb->dst->dev; ++ fdb_event.dev = source->dev; ++ /* QCA NSS bridge-mgr support - End */ + WRITE_ONCE(fdb->dst, source); + fdb_modified = true; + /* Take over HW learned entry */ +@@ -952,7 +970,7 @@ void br_fdb_update(struct net_bridge *br + /* QCA NSS ECM support - Start */ + atomic_notifier_call_chain( + &br_fdb_update_notifier_list, +- 0, (void *)addr); ++ 0, (void *)&fdb_event); + /* QCA NSS ECM support - End */ + } + diff --git a/target/linux/qualcommax/patches-6.6/0602-1-qca-nss-drv-add-qdisc-support.patch b/target/linux/qualcommax/patches-6.6/0602-1-qca-nss-drv-add-qdisc-support.patch new file mode 100644 index 00000000000000..2926faacefebd7 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0602-1-qca-nss-drv-add-qdisc-support.patch @@ -0,0 +1,25 @@ +--- a/include/uapi/linux/pkt_cls.h ++++ b/include/uapi/linux/pkt_cls.h +@@ -139,6 +139,7 @@ enum tca_id { + TCA_ID_MPLS, + TCA_ID_CT, + TCA_ID_GATE, ++ TCA_ID_MIRRED_NSS, /* QCA NSS Qdisc IGS Support */ + /* other actions go here */ + __TCA_ID_MAX = 255 + }; +@@ -817,4 +818,14 @@ enum { + TCF_EM_OPND_LT + }; + ++/* QCA NSS Qdisc Support - Start */ ++#define _TC_MAKE32(x) ((x)) ++#define _TC_MAKEMASK1(n) (_TC_MAKE32(1) << _TC_MAKE32(n)) ++ ++#define TC_NCLS _TC_MAKEMASK1(8) ++#define TC_NCLS_NSS _TC_MAKEMASK1(12) ++#define SET_TC_NCLS_NSS(v) ( TC_NCLS_NSS | ((v) & ~TC_NCLS_NSS)) ++#define CLR_TC_NCLS_NSS(v) ( (v) & ~TC_NCLS_NSS) ++/* QCA NSS Qdisc Support - End */ ++ + #endif diff --git a/target/linux/qualcommax/patches-6.6/0603-1-qca-nss-clients-add-qdisc-support.patch b/target/linux/qualcommax/patches-6.6/0603-1-qca-nss-clients-add-qdisc-support.patch new file mode 100644 index 00000000000000..9220aca1c78be7 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0603-1-qca-nss-clients-add-qdisc-support.patch @@ -0,0 +1,463 @@ +--- a/include/linux/timer.h ++++ b/include/linux/timer.h +@@ -17,6 +17,7 @@ struct timer_list { + unsigned long expires; + void (*function)(struct timer_list *); + u32 flags; ++ unsigned long cust_data; + + #ifdef CONFIG_LOCKDEP + struct lockdep_map lockdep_map; +--- a/drivers/net/ifb.c ++++ b/drivers/net/ifb.c +@@ -151,6 +151,31 @@ resched: + + } + ++void ifb_update_offload_stats(struct net_device *dev, struct pcpu_sw_netstats *offload_stats) ++{ ++ struct ifb_dev_private *dp; ++ struct ifb_q_private *txp; ++ ++ if (!dev || !offload_stats) { ++ return; ++ } ++ ++ if (!(dev->priv_flags_ext & IFF_EXT_IFB)) { ++ return; ++ } ++ ++ dp = netdev_priv(dev); ++ txp = dp->tx_private; ++ ++ u64_stats_update_begin(&txp->rx_stats.sync); ++ txp->rx_stats.packets += u64_stats_read(&offload_stats->rx_packets); ++ txp->rx_stats.bytes += u64_stats_read(&offload_stats->rx_bytes); ++ txp->tx_stats.packets += u64_stats_read(&offload_stats->tx_packets); ++ txp->tx_stats.bytes += u64_stats_read(&offload_stats->tx_bytes); ++ u64_stats_update_end(&txp->rx_stats.sync); ++} ++EXPORT_SYMBOL(ifb_update_offload_stats); ++ + static void ifb_stats64(struct net_device *dev, + struct rtnl_link_stats64 *stats) + { +@@ -326,6 +351,7 @@ static void ifb_setup(struct net_device + dev->flags |= IFF_NOARP; + dev->flags &= ~IFF_MULTICAST; + dev->priv_flags &= ~IFF_TX_SKB_SHARING; ++ dev->priv_flags_ext |= IFF_EXT_IFB; /* Mark the device as an IFB device. */ + netif_keep_dst(dev); + eth_hw_addr_random(dev); + dev->needs_free_netdev = true; +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -4696,6 +4696,15 @@ void dev_uc_flush(struct net_device *dev + void dev_uc_init(struct net_device *dev); + + /** ++ * ifb_update_offload_stats - Update the IFB interface stats ++ * @dev: IFB device to update the stats ++ * @offload_stats: per CPU stats structure ++ * ++ * Allows update of IFB stats when flows are offloaded to an accelerator. ++ **/ ++void ifb_update_offload_stats(struct net_device *dev, struct pcpu_sw_netstats *offload_stats); ++ ++/** + * __dev_uc_sync - Synchonize device's unicast list + * @dev: device to sync + * @sync: function to call if address should be added +@@ -5222,6 +5231,11 @@ static inline bool netif_is_failover_sla + return dev->priv_flags & IFF_FAILOVER_SLAVE; + } + ++static inline bool netif_is_ifb_dev(const struct net_device *dev) ++{ ++ return dev->priv_flags_ext & IFF_EXT_IFB; ++} ++ + /* This device needs to keep skb dst for qdisc enqueue or ndo_start_xmit() */ + static inline void netif_keep_dst(struct net_device *dev) + { +--- a/include/uapi/linux/pkt_sched.h ++++ b/include/uapi/linux/pkt_sched.h +@@ -1306,4 +1306,248 @@ enum { + + #define TCA_ETS_MAX (__TCA_ETS_MAX - 1) + ++/* QCA NSS Clients Support - Start */ ++enum { ++ TCA_NSS_ACCEL_MODE_NSS_FW, ++ TCA_NSS_ACCEL_MODE_PPE, ++ TCA_NSS_ACCEL_MODE_MAX ++}; ++ ++/* NSSFIFO section */ ++ ++enum { ++ TCA_NSSFIFO_UNSPEC, ++ TCA_NSSFIFO_PARMS, ++ __TCA_NSSFIFO_MAX ++}; ++ ++#define TCA_NSSFIFO_MAX (__TCA_NSSFIFO_MAX - 1) ++ ++struct tc_nssfifo_qopt { ++ __u32 limit; /* Queue length: bytes for bfifo, packets for pfifo */ ++ __u8 set_default; /* Sets qdisc to be the default qdisc for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSWRED section */ ++ ++enum { ++ TCA_NSSWRED_UNSPEC, ++ TCA_NSSWRED_PARMS, ++ __TCA_NSSWRED_MAX ++}; ++ ++#define TCA_NSSWRED_MAX (__TCA_NSSWRED_MAX - 1) ++#define NSSWRED_CLASS_MAX 6 ++struct tc_red_alg_parameter { ++ __u32 min; /* qlen_avg < min: pkts are all enqueued */ ++ __u32 max; /* qlen_avg > max: pkts are all dropped */ ++ __u32 probability;/* Drop probability at qlen_avg = max */ ++ __u32 exp_weight_factor;/* exp_weight_factor for calculate qlen_avg */ ++}; ++ ++struct tc_nsswred_traffic_class { ++ __u32 limit; /* Queue length */ ++ __u32 weight_mode_value; /* Weight mode value */ ++ struct tc_red_alg_parameter rap;/* Parameters for RED alg */ ++}; ++ ++/* ++ * Weight modes for WRED ++ */ ++enum tc_nsswred_weight_modes { ++ TC_NSSWRED_WEIGHT_MODE_DSCP = 0,/* Weight mode is DSCP */ ++ TC_NSSWRED_WEIGHT_MODES, /* Must be last */ ++}; ++ ++struct tc_nsswred_qopt { ++ __u32 limit; /* Queue length */ ++ enum tc_nsswred_weight_modes weight_mode; ++ /* Weight mode */ ++ __u32 traffic_classes; /* How many traffic classes: DPs */ ++ __u32 def_traffic_class; /* Default traffic if no match: def_DP */ ++ __u32 traffic_id; /* The traffic id to be configured: DP */ ++ __u32 weight_mode_value; /* Weight mode value */ ++ struct tc_red_alg_parameter rap;/* RED algorithm parameters */ ++ struct tc_nsswred_traffic_class tntc[NSSWRED_CLASS_MAX]; ++ /* Traffic settings for dumpping */ ++ __u8 ecn; /* Setting ECN bit or dropping */ ++ __u8 set_default; /* Sets qdisc to be the default for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSCODEL section */ ++ ++enum { ++ TCA_NSSCODEL_UNSPEC, ++ TCA_NSSCODEL_PARMS, ++ __TCA_NSSCODEL_MAX ++}; ++ ++#define TCA_NSSCODEL_MAX (__TCA_NSSCODEL_MAX - 1) ++ ++struct tc_nsscodel_qopt { ++ __u32 target; /* Acceptable queueing delay */ ++ __u32 limit; /* Max number of packets that can be held in the queue */ ++ __u32 interval; /* Monitoring interval */ ++ __u32 flows; /* Number of flow buckets */ ++ __u32 quantum; /* Weight (in bytes) used for DRR of flow buckets */ ++ __u8 ecn; /* 0 - disable ECN, 1 - enable ECN */ ++ __u8 set_default; /* Sets qdisc to be the default qdisc for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++struct tc_nsscodel_xstats { ++ __u32 peak_queue_delay; /* Peak delay experienced by a dequeued packet */ ++ __u32 peak_drop_delay; /* Peak delay experienced by a dropped packet */ ++}; ++ ++/* NSSFQ_CODEL section */ ++ ++struct tc_nssfq_codel_xstats { ++ __u32 new_flow_count; /* Total number of new flows seen */ ++ __u32 new_flows_len; /* Current number of new flows */ ++ __u32 old_flows_len; /* Current number of old flows */ ++ __u32 ecn_mark; /* Number of packets marked with ECN */ ++ __u32 drop_overlimit; /* Number of packets dropped due to overlimit */ ++ __u32 maxpacket; /* The largest packet seen so far in the queue */ ++}; ++ ++/* NSSTBL section */ ++ ++enum { ++ TCA_NSSTBL_UNSPEC, ++ TCA_NSSTBL_PARMS, ++ __TCA_NSSTBL_MAX ++}; ++ ++#define TCA_NSSTBL_MAX (__TCA_NSSTBL_MAX - 1) ++ ++struct tc_nsstbl_qopt { ++ __u32 burst; /* Maximum burst size */ ++ __u32 rate; /* Limiting rate of TBF */ ++ __u32 peakrate; /* Maximum rate at which TBF is allowed to send */ ++ __u32 mtu; /* Max size of packet, or minumim burst size */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSPRIO section */ ++ ++#define TCA_NSSPRIO_MAX_BANDS 256 ++ ++enum { ++ TCA_NSSPRIO_UNSPEC, ++ TCA_NSSPRIO_PARMS, ++ __TCA_NSSPRIO_MAX ++}; ++ ++#define TCA_NSSPRIO_MAX (__TCA_NSSPRIO_MAX - 1) ++ ++struct tc_nssprio_qopt { ++ __u32 bands; /* Number of bands */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSBF section */ ++ ++enum { ++ TCA_NSSBF_UNSPEC, ++ TCA_NSSBF_CLASS_PARMS, ++ TCA_NSSBF_QDISC_PARMS, ++ __TCA_NSSBF_MAX ++}; ++ ++#define TCA_NSSBF_MAX (__TCA_NSSBF_MAX - 1) ++ ++struct tc_nssbf_class_qopt { ++ __u32 burst; /* Maximum burst size */ ++ __u32 rate; /* Allowed bandwidth for this class */ ++ __u32 mtu; /* MTU of the associated interface */ ++ __u32 quantum; /* Quantum allocation for DRR */ ++}; ++ ++struct tc_nssbf_qopt { ++ __u16 defcls; /* Default class value */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSWRR section */ ++ ++enum { ++ TCA_NSSWRR_UNSPEC, ++ TCA_NSSWRR_CLASS_PARMS, ++ TCA_NSSWRR_QDISC_PARMS, ++ __TCA_NSSWRR_MAX ++}; ++ ++#define TCA_NSSWRR_MAX (__TCA_NSSWRR_MAX - 1) ++ ++struct tc_nsswrr_class_qopt { ++ __u32 quantum; /* Weight associated to this class */ ++}; ++ ++struct tc_nsswrr_qopt { ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSWFQ section */ ++ ++enum { ++ TCA_NSSWFQ_UNSPEC, ++ TCA_NSSWFQ_CLASS_PARMS, ++ TCA_NSSWFQ_QDISC_PARMS, ++ __TCA_NSSWFQ_MAX ++}; ++ ++#define TCA_NSSWFQ_MAX (__TCA_NSSWFQ_MAX - 1) ++ ++struct tc_nsswfq_class_qopt { ++ __u32 quantum; /* Weight associated to this class */ ++}; ++ ++struct tc_nsswfq_qopt { ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSHTB section */ ++ ++enum { ++ TCA_NSSHTB_UNSPEC, ++ TCA_NSSHTB_CLASS_PARMS, ++ TCA_NSSHTB_QDISC_PARMS, ++ __TCA_NSSHTB_MAX ++}; ++ ++#define TCA_NSSHTB_MAX (__TCA_NSSHTB_MAX - 1) ++ ++struct tc_nsshtb_class_qopt { ++ __u32 burst; /* Allowed burst size */ ++ __u32 rate; /* Allowed bandwidth for this class */ ++ __u32 cburst; /* Maximum burst size */ ++ __u32 crate; /* Maximum bandwidth for this class */ ++ __u32 quantum; /* Quantum allocation for DRR */ ++ __u32 priority; /* Priority value associated with this class */ ++ __u32 overhead; /* Overhead in bytes per packet */ ++}; ++ ++struct tc_nsshtb_qopt { ++ __u32 r2q; /* Rate to quantum ratio */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSBLACKHOLE section */ ++ ++enum { ++ TCA_NSSBLACKHOLE_UNSPEC, ++ TCA_NSSBLACKHOLE_PARMS, ++ __TCA_NSSBLACKHOLE_MAX ++}; ++ ++#define TCA_NSSBLACKHOLE_MAX (__TCA_NSSBLACKHOLE_MAX - 1) ++ ++struct tc_nssblackhole_qopt { ++ __u8 set_default; /* Sets qdisc to be the default qdisc for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++/* QCA NSS Clients Support - End */ + #endif +--- a/net/sched/sch_api.c ++++ b/net/sched/sch_api.c +@@ -314,6 +314,7 @@ struct Qdisc *qdisc_lookup(struct net_de + out: + return q; + } ++EXPORT_SYMBOL(qdisc_lookup); + + struct Qdisc *qdisc_lookup_rcu(struct net_device *dev, u32 handle) + { +@@ -2389,4 +2390,26 @@ static int __init pktsched_init(void) + return 0; + } + ++/* QCA NSS Qdisc Support - Start */ ++bool tcf_destroy(struct tcf_proto *tp, bool force) ++{ ++ tp->ops->destroy(tp, force, NULL); ++ module_put(tp->ops->owner); ++ kfree_rcu(tp, rcu); ++ ++ return true; ++} ++ ++void tcf_destroy_chain(struct tcf_proto __rcu **fl) ++{ ++ struct tcf_proto *tp; ++ ++ while ((tp = rtnl_dereference(*fl)) != NULL) { ++ RCU_INIT_POINTER(*fl, tp->next); ++ tcf_destroy(tp, true); ++ } ++} ++EXPORT_SYMBOL(tcf_destroy_chain); ++/* QCA NSS Qdisc Support - End */ ++ + subsys_initcall(pktsched_init); +--- a/net/sched/sch_generic.c ++++ b/net/sched/sch_generic.c +@@ -1069,6 +1069,7 @@ static void __qdisc_destroy(struct Qdisc + + call_rcu(&qdisc->rcu, qdisc_free_cb); + } ++EXPORT_SYMBOL(qdisc_destroy); + + void qdisc_destroy(struct Qdisc *qdisc) + { +--- a/include/net/sch_generic.h ++++ b/include/net/sch_generic.h +@@ -94,6 +94,7 @@ struct Qdisc { + #define TCQ_F_INVISIBLE 0x80 /* invisible by default in dump */ + #define TCQ_F_NOLOCK 0x100 /* qdisc does not require locking */ + #define TCQ_F_OFFLOADED 0x200 /* qdisc is offloaded to HW */ ++#define TCQ_F_NSS 0x1000 /* NSS qdisc flag. */ + u32 limit; + const struct Qdisc_ops *ops; + struct qdisc_size_table __rcu *stab; +@@ -751,6 +752,42 @@ static inline bool skb_skip_tc_classify( + return false; + } + ++/* QCA NSS Qdisc Support - Start */ ++/* ++ * Set skb classify bit field. ++ */ ++static inline void skb_set_tc_classify_offload(struct sk_buff *skb) ++{ ++#ifdef CONFIG_NET_CLS_ACT ++ skb->tc_skip_classify_offload = 1; ++#endif ++} ++ ++/* ++ * Clear skb classify bit field. ++ */ ++static inline void skb_clear_tc_classify_offload(struct sk_buff *skb) ++{ ++#ifdef CONFIG_NET_CLS_ACT ++ skb->tc_skip_classify_offload = 0; ++#endif ++} ++ ++/* ++ * Skip skb processing if sent from ifb dev. ++ */ ++static inline bool skb_skip_tc_classify_offload(struct sk_buff *skb) ++{ ++#ifdef CONFIG_NET_CLS_ACT ++ if (skb->tc_skip_classify_offload) { ++ skb_clear_tc_classify_offload(skb); ++ return true; ++ } ++#endif ++ return false; ++} ++/* QCA NSS Qdisc Support - End */ ++ + /* Reset all TX qdiscs greater than index of a device. */ + static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i) + { +@@ -1323,4 +1360,9 @@ static inline void qdisc_synchronize(con + msleep(1); + } + ++/* QCA NSS Qdisc Support - Start */ ++void qdisc_destroy(struct Qdisc *qdisc); ++void tcf_destroy_chain(struct tcf_proto __rcu **fl); ++/* QCA NSS Qdisc Support - End */ ++ + #endif +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -764,6 +764,7 @@ typedef unsigned char *sk_buff_data_t; + * @offload_fwd_mark: Packet was L2-forwarded in hardware + * @offload_l3_fwd_mark: Packet was L3-forwarded in hardware + * @tc_skip_classify: do not classify packet. set by IFB device ++ * @tc_skip_classify_offload: do not classify packet set by offload IFB device + * @tc_at_ingress: used within tc_classify to distinguish in/egress + * @redirected: packet was redirected by packet classifier + * @from_ingress: packet was redirected from the ingress path +@@ -945,6 +946,9 @@ struct sk_buff { + __u8 tc_at_ingress:1; /* See TC_AT_INGRESS_MASK */ + __u8 tc_skip_classify:1; + #endif ++#ifdef CONFIG_NET_CLS_ACT ++ __u8 tc_skip_classify_offload:1; /* QCA NSS Qdisc Support */ ++#endif + __u8 remcsum_offload:1; + __u8 csum_complete_sw:1; + __u8 csum_level:2; diff --git a/target/linux/qualcommax/patches-6.6/0603-2-qca-nss-clients-add-l2tp-support.patch b/target/linux/qualcommax/patches-6.6/0603-2-qca-nss-clients-add-l2tp-support.patch new file mode 100644 index 00000000000000..7fa9184df25155 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0603-2-qca-nss-clients-add-l2tp-support.patch @@ -0,0 +1,46 @@ +--- a/net/l2tp/l2tp_core.c ++++ b/net/l2tp/l2tp_core.c +@@ -398,6 +398,31 @@ err_tlock: + } + EXPORT_SYMBOL_GPL(l2tp_session_register); + ++void l2tp_stats_update(struct l2tp_tunnel *tunnel, ++ struct l2tp_session *session, ++ struct l2tp_stats *stats) ++{ ++ atomic_long_add(atomic_long_read(&stats->rx_packets), ++ &tunnel->stats.rx_packets); ++ atomic_long_add(atomic_long_read(&stats->rx_bytes), ++ &tunnel->stats.rx_bytes); ++ atomic_long_add(atomic_long_read(&stats->tx_packets), ++ &tunnel->stats.tx_packets); ++ atomic_long_add(atomic_long_read(&stats->tx_bytes), ++ &tunnel->stats.tx_bytes); ++ ++ atomic_long_add(atomic_long_read(&stats->rx_packets), ++ &session->stats.rx_packets); ++ atomic_long_add(atomic_long_read(&stats->rx_bytes), ++ &session->stats.rx_bytes); ++ atomic_long_add(atomic_long_read(&stats->tx_packets), ++ &session->stats.tx_packets); ++ atomic_long_add(atomic_long_read(&stats->tx_bytes), ++ &session->stats.tx_bytes); ++} ++EXPORT_SYMBOL_GPL(l2tp_stats_update); ++ ++ + /***************************************************************************** + * Receive data handling + *****************************************************************************/ +--- a/net/l2tp/l2tp_core.h ++++ b/net/l2tp/l2tp_core.h +@@ -232,6 +232,9 @@ struct l2tp_session *l2tp_session_get_nt + struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net, + const char *ifname); + ++void l2tp_stats_update(struct l2tp_tunnel *tunnel, struct l2tp_session *session, ++ struct l2tp_stats *stats); ++ + /* Tunnel and session lifetime management. + * Creation of a new instance is a two-step process: create, then register. + * Destruction is triggered using the *_delete functions, and completes asynchronously. diff --git a/target/linux/qualcommax/patches-6.6/0603-3-qca-nss-clients-add-PPTP-support.patch b/target/linux/qualcommax/patches-6.6/0603-3-qca-nss-clients-add-PPTP-support.patch new file mode 100644 index 00000000000000..5fb9917bc9067e --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0603-3-qca-nss-clients-add-PPTP-support.patch @@ -0,0 +1,478 @@ +--- a/include/linux/if_pppox.h ++++ b/include/linux/if_pppox.h +@@ -36,6 +36,7 @@ struct pptp_opt { + u32 ack_sent, ack_recv; + u32 seq_sent, seq_recv; + int ppp_flags; ++ bool pptp_offload_mode; + }; + #include + +@@ -100,8 +101,40 @@ struct pppoe_channel_ops { + int (*get_addressing)(struct ppp_channel *, struct pppoe_opt *); + }; + ++/* PPTP client callback */ ++typedef int (*pptp_gre_seq_offload_callback_t)(struct sk_buff *skb, ++ struct net_device *pptp_dev); ++ + /* Return PPPoE channel specific addressing information */ + extern int pppoe_channel_addressing_get(struct ppp_channel *chan, + struct pppoe_opt *addressing); + ++/* Lookup PPTP session info and return PPTP session using sip, dip and local call id */ ++extern int pptp_session_find_by_src_callid(struct pptp_opt *opt, __be16 src_call_id, ++ __be32 daddr, __be32 saddr); ++ ++/* Lookup PPTP session info and return PPTP session using dip and peer call id */ ++extern int pptp_session_find(struct pptp_opt *opt, __be16 peer_call_id, ++ __be32 peer_ip_addr); ++ ++/* Return PPTP session information given the channel */ ++extern void pptp_channel_addressing_get(struct pptp_opt *opt, ++ struct ppp_channel *chan); ++ ++/* Enable the PPTP session offload flag */ ++extern int pptp_session_enable_offload_mode(__be16 peer_call_id, ++ __be32 peer_ip_addr); ++ ++/* Disable the PPTP session offload flag */ ++extern int pptp_session_disable_offload_mode(__be16 peer_call_id, ++ __be32 peer_ip_addr); ++ ++/* Register the PPTP GRE packets sequence number offload callback */ ++extern int ++pptp_register_gre_seq_offload_callback(pptp_gre_seq_offload_callback_t ++ pptp_client_cb); ++ ++/* Unregister the PPTP GRE packets sequence number offload callback */ ++extern void pptp_unregister_gre_seq_offload_callback(void); ++ + #endif /* !(__LINUX_IF_PPPOX_H) */ +--- a/drivers/net/ppp/ppp_generic.c ++++ b/drivers/net/ppp/ppp_generic.c +@@ -2973,6 +2973,20 @@ char *ppp_dev_name(struct ppp_channel *c + return name; + } + ++/* Return the PPP net device index */ ++int ppp_dev_index(struct ppp_channel *chan) ++{ ++ struct channel *pch = chan->ppp; ++ int ifindex = 0; ++ ++ if (pch) { ++ read_lock_bh(&pch->upl); ++ if (pch->ppp && pch->ppp->dev) ++ ifindex = pch->ppp->dev->ifindex; ++ read_unlock_bh(&pch->upl); ++ } ++ return ifindex; ++} + + /* + * Disconnect a channel from the generic layer. +@@ -3681,6 +3695,28 @@ void ppp_update_stats(struct net_device + ppp_recv_unlock(ppp); + } + ++/* Returns true if Compression is enabled on PPP device ++ */ ++bool ppp_is_cp_enabled(struct net_device *dev) ++{ ++ struct ppp *ppp; ++ bool flag = false; ++ ++ if (!dev) ++ return false; ++ ++ if (dev->type != ARPHRD_PPP) ++ return false; ++ ++ ppp = netdev_priv(dev); ++ ppp_lock(ppp); ++ flag = !!(ppp->xstate & SC_COMP_RUN) || !!(ppp->rstate & SC_DECOMP_RUN); ++ ppp_unlock(ppp); ++ ++ return flag; ++} ++EXPORT_SYMBOL(ppp_is_cp_enabled); ++ + /* Returns >0 if the device is a multilink PPP netdevice, 0 if not or < 0 if + * the device is not PPP. + */ +@@ -3872,6 +3908,7 @@ EXPORT_SYMBOL(ppp_unregister_channel); + EXPORT_SYMBOL(ppp_channel_index); + EXPORT_SYMBOL(ppp_unit_number); + EXPORT_SYMBOL(ppp_dev_name); ++EXPORT_SYMBOL(ppp_dev_index); + EXPORT_SYMBOL(ppp_input); + EXPORT_SYMBOL(ppp_input_error); + EXPORT_SYMBOL(ppp_output_wakeup); +--- a/include/linux/ppp_channel.h ++++ b/include/linux/ppp_channel.h +@@ -84,6 +84,9 @@ extern void ppp_unregister_channel(struc + /* Get the channel number for a channel */ + extern int ppp_channel_index(struct ppp_channel *); + ++/* Get the device index associated with a channel, or 0, if none */ ++extern int ppp_dev_index(struct ppp_channel *); ++ + /* Get the unit number associated with a channel, or -1 if none */ + extern int ppp_unit_number(struct ppp_channel *); + +@@ -116,6 +119,7 @@ extern int ppp_hold_channels(struct net_ + /* Test if ppp xmit lock is locked */ + extern bool ppp_is_xmit_locked(struct net_device *dev); + ++bool ppp_is_cp_enabled(struct net_device *dev); + /* Test if the ppp device is a multi-link ppp device */ + extern int ppp_is_multilink(struct net_device *dev); + +--- a/drivers/net/ppp/pptp.c ++++ b/drivers/net/ppp/pptp.c +@@ -50,6 +50,8 @@ static struct proto pptp_sk_proto __read + static const struct ppp_channel_ops pptp_chan_ops; + static const struct proto_ops pptp_ops; + ++static pptp_gre_seq_offload_callback_t __rcu pptp_gre_offload_xmit_cb; ++ + static struct pppox_sock *lookup_chan(u16 call_id, __be32 s_addr) + { + struct pppox_sock *sock; +@@ -91,6 +93,79 @@ static int lookup_chan_dst(u16 call_id, + return i < MAX_CALLID; + } + ++/* Search a pptp session based on local call id, local and remote ip address */ ++static int lookup_session_src(struct pptp_opt *opt, u16 call_id, __be32 daddr, __be32 saddr) ++{ ++ struct pppox_sock *sock; ++ int i = 1; ++ ++ rcu_read_lock(); ++ for_each_set_bit_from(i, callid_bitmap, MAX_CALLID) { ++ sock = rcu_dereference(callid_sock[i]); ++ if (!sock) ++ continue; ++ ++ if (sock->proto.pptp.src_addr.call_id == call_id && ++ sock->proto.pptp.dst_addr.sin_addr.s_addr == daddr && ++ sock->proto.pptp.src_addr.sin_addr.s_addr == saddr) { ++ sock_hold(sk_pppox(sock)); ++ memcpy(opt, &sock->proto.pptp, sizeof(struct pptp_opt)); ++ sock_put(sk_pppox(sock)); ++ rcu_read_unlock(); ++ return 0; ++ } ++ } ++ rcu_read_unlock(); ++ return -EINVAL; ++} ++ ++/* Search a pptp session based on peer call id and peer ip address */ ++static int lookup_session_dst(struct pptp_opt *opt, u16 call_id, __be32 d_addr) ++{ ++ struct pppox_sock *sock; ++ int i = 1; ++ ++ rcu_read_lock(); ++ for_each_set_bit_from(i, callid_bitmap, MAX_CALLID) { ++ sock = rcu_dereference(callid_sock[i]); ++ if (!sock) ++ continue; ++ ++ if (sock->proto.pptp.dst_addr.call_id == call_id && ++ sock->proto.pptp.dst_addr.sin_addr.s_addr == d_addr) { ++ sock_hold(sk_pppox(sock)); ++ memcpy(opt, &sock->proto.pptp, sizeof(struct pptp_opt)); ++ sock_put(sk_pppox(sock)); ++ rcu_read_unlock(); ++ return 0; ++ } ++ } ++ rcu_read_unlock(); ++ return -EINVAL; ++} ++ ++/* If offload mode set then this function sends all packets to ++ * offload module instead of network stack ++ */ ++static int pptp_client_skb_xmit(struct sk_buff *skb, ++ struct net_device *pptp_dev) ++{ ++ pptp_gre_seq_offload_callback_t pptp_gre_offload_cb_f; ++ int ret; ++ ++ rcu_read_lock(); ++ pptp_gre_offload_cb_f = rcu_dereference(pptp_gre_offload_xmit_cb); ++ ++ if (!pptp_gre_offload_cb_f) { ++ rcu_read_unlock(); ++ return -1; ++ } ++ ++ ret = pptp_gre_offload_cb_f(skb, pptp_dev); ++ rcu_read_unlock(); ++ return ret; ++} ++ + static int add_chan(struct pppox_sock *sock, + struct pptp_addr *sa) + { +@@ -136,7 +211,7 @@ static struct rtable *pptp_route_output( + struct net *net; + + net = sock_net(sk); +- flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark, 0, ++ flowi4_init_output(fl4, 0, sk->sk_mark, 0, + RT_SCOPE_UNIVERSE, IPPROTO_GRE, 0, + po->proto.pptp.dst_addr.sin_addr.s_addr, + po->proto.pptp.src_addr.sin_addr.s_addr, +@@ -163,8 +238,11 @@ static int pptp_xmit(struct ppp_channel + + struct rtable *rt; + struct net_device *tdev; ++ struct net_device *pptp_dev; + struct iphdr *iph; + int max_headroom; ++ int pptp_ifindex; ++ int ret; + + if (sk_pppox(po)->sk_state & PPPOX_DEAD) + goto tx_error; +@@ -258,7 +336,32 @@ static int pptp_xmit(struct ppp_channel + ip_select_ident(net, skb, NULL); + ip_send_check(iph); + +- ip_local_out(net, skb->sk, skb); ++ pptp_ifindex = ppp_dev_index(chan); ++ ++ /* set incoming interface as the ppp interface */ ++ if (skb->skb_iif) ++ skb->skb_iif = pptp_ifindex; ++ ++ /* If the PPTP GRE seq number offload module is not enabled yet ++ * then sends all PPTP GRE packets through linux network stack ++ */ ++ if (!opt->pptp_offload_mode) { ++ ip_local_out(net, skb->sk, skb); ++ return 1; ++ } ++ ++ pptp_dev = dev_get_by_index(&init_net, pptp_ifindex); ++ if (!pptp_dev) ++ goto tx_error; ++ ++ /* If PPTP offload module is enabled then forward all PPTP GRE ++ * packets to PPTP GRE offload module ++ */ ++ ret = pptp_client_skb_xmit(skb, pptp_dev); ++ dev_put(pptp_dev); ++ if (ret < 0) ++ goto tx_error; ++ + return 1; + + tx_error: +@@ -314,6 +417,13 @@ static int pptp_rcv_core(struct sock *sk + goto drop; + + payload = skb->data + headersize; ++ ++ /* If offload is enabled, we expect the offload module ++ * to handle PPTP GRE sequence number checks ++ */ ++ if (opt->pptp_offload_mode) ++ goto allow_packet; ++ + /* check for expected sequence number */ + if (seq < opt->seq_recv + 1 || WRAPPED(opt->seq_recv, seq)) { + if ((payload[0] == PPP_ALLSTATIONS) && (payload[1] == PPP_UI) && +@@ -371,6 +481,7 @@ static int pptp_rcv(struct sk_buff *skb) + if (po) { + skb_dst_drop(skb); + nf_reset_ct(skb); ++ skb->skb_iif = ppp_dev_index(&po->chan); + return sk_receive_skb(sk_pppox(po), skb, 0); + } + drop: +@@ -473,7 +584,7 @@ static int pptp_connect(struct socket *s + + opt->dst_addr = sp->sa_addr.pptp; + sk->sk_state |= PPPOX_CONNECTED; +- ++ opt->pptp_offload_mode = false; + end: + release_sock(sk); + return error; +@@ -603,9 +714,169 @@ static int pptp_ppp_ioctl(struct ppp_cha + return err; + } + ++/* pptp_channel_addressing_get() ++ * Return PPTP channel specific addressing information. ++ */ ++void pptp_channel_addressing_get(struct pptp_opt *opt, struct ppp_channel *chan) ++{ ++ struct sock *sk; ++ struct pppox_sock *po; ++ ++ if (!opt) ++ return; ++ ++ sk = (struct sock *)chan->private; ++ if (!sk) ++ return; ++ ++ sock_hold(sk); ++ ++ /* This is very unlikely, but check the socket is connected state */ ++ if (unlikely(sock_flag(sk, SOCK_DEAD) || ++ !(sk->sk_state & PPPOX_CONNECTED))) { ++ sock_put(sk); ++ return; ++ } ++ ++ po = pppox_sk(sk); ++ memcpy(opt, &po->proto.pptp, sizeof(struct pptp_opt)); ++ sock_put(sk); ++} ++EXPORT_SYMBOL(pptp_channel_addressing_get); ++ ++/* pptp_session_find() ++ * Search and return a PPTP session info based on peer callid and IP ++ * address. The function accepts the parameters in network byte order. ++ */ ++int pptp_session_find(struct pptp_opt *opt, __be16 peer_call_id, ++ __be32 peer_ip_addr) ++{ ++ if (!opt) ++ return -EINVAL; ++ ++ return lookup_session_dst(opt, ntohs(peer_call_id), peer_ip_addr); ++} ++EXPORT_SYMBOL(pptp_session_find); ++ ++/* pptp_session_find_by_src_callid() ++ * Search and return a PPTP session info based on src callid and IP ++ * address. The function accepts the parameters in network byte order. ++ */ ++int pptp_session_find_by_src_callid(struct pptp_opt *opt, __be16 src_call_id, ++ __be32 daddr, __be32 saddr) ++{ ++ if (!opt) ++ return -EINVAL; ++ ++ return lookup_session_src(opt, ntohs(src_call_id), daddr, saddr); ++} ++EXPORT_SYMBOL(pptp_session_find_by_src_callid); ++ ++ /* Function to change the offload mode true/false for a PPTP session */ ++static int pptp_set_offload_mode(bool accel_mode, ++ __be16 peer_call_id, __be32 peer_ip_addr) ++{ ++ struct pppox_sock *sock; ++ int i = 1; ++ ++ rcu_read_lock(); ++ for_each_set_bit_from(i, callid_bitmap, MAX_CALLID) { ++ sock = rcu_dereference(callid_sock[i]); ++ if (!sock) ++ continue; ++ ++ if (sock->proto.pptp.dst_addr.call_id == peer_call_id && ++ sock->proto.pptp.dst_addr.sin_addr.s_addr == peer_ip_addr) { ++ sock_hold(sk_pppox(sock)); ++ sock->proto.pptp.pptp_offload_mode = accel_mode; ++ sock_put(sk_pppox(sock)); ++ rcu_read_unlock(); ++ return 0; ++ } ++ } ++ rcu_read_unlock(); ++ return -EINVAL; ++} ++ ++/* Enable the PPTP session offload flag */ ++int pptp_session_enable_offload_mode(__be16 peer_call_id, __be32 peer_ip_addr) ++{ ++ return pptp_set_offload_mode(true, peer_call_id, peer_ip_addr); ++} ++EXPORT_SYMBOL(pptp_session_enable_offload_mode); ++ ++/* Disable the PPTP session offload flag */ ++int pptp_session_disable_offload_mode(__be16 peer_call_id, __be32 peer_ip_addr) ++{ ++ return pptp_set_offload_mode(false, peer_call_id, peer_ip_addr); ++} ++EXPORT_SYMBOL(pptp_session_disable_offload_mode); ++ ++/* Register the offload callback function on behalf of the module which ++ * will own the sequence and acknowledgment number updates for all ++ * PPTP GRE packets. All PPTP GRE packets are then transmitted to this ++ * module after encapsulation in order to ensure the correct seq/ack ++ * fields are set in the packets before transmission. This is required ++ * when PPTP flows are offloaded to acceleration engines, in-order to ++ * ensure consistency in sequence and ack numbers between PPTP control ++ * (PPP LCP) and data packets ++ */ ++int pptp_register_gre_seq_offload_callback(pptp_gre_seq_offload_callback_t ++ pptp_gre_offload_cb) ++{ ++ pptp_gre_seq_offload_callback_t pptp_gre_offload_cb_f; ++ ++ rcu_read_lock(); ++ pptp_gre_offload_cb_f = rcu_dereference(pptp_gre_offload_xmit_cb); ++ ++ if (pptp_gre_offload_cb_f) { ++ rcu_read_unlock(); ++ return -1; ++ } ++ ++ rcu_assign_pointer(pptp_gre_offload_xmit_cb, pptp_gre_offload_cb); ++ rcu_read_unlock(); ++ return 0; ++} ++EXPORT_SYMBOL(pptp_register_gre_seq_offload_callback); ++ ++/* Unregister the PPTP GRE packets sequence number offload callback */ ++void pptp_unregister_gre_seq_offload_callback(void) ++{ ++ rcu_assign_pointer(pptp_gre_offload_xmit_cb, NULL); ++} ++EXPORT_SYMBOL(pptp_unregister_gre_seq_offload_callback); ++ ++/* pptp_hold_chan() */ ++static void pptp_hold_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_hold(sk); ++} ++ ++/* pptp_release_chan() */ ++static void pptp_release_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_put(sk); ++} ++ ++/* pptp_get_channel_protocol() ++ * Return the protocol type of the PPTP over PPP protocol ++ */ ++static int pptp_get_channel_protocol(struct ppp_channel *chan) ++{ ++ return PX_PROTO_PPTP; ++} ++ + static const struct ppp_channel_ops pptp_chan_ops = { + .start_xmit = pptp_xmit, + .ioctl = pptp_ppp_ioctl, ++ .get_channel_protocol = pptp_get_channel_protocol, ++ .hold = pptp_hold_chan, ++ .release = pptp_release_chan, + }; + + static struct proto pptp_sk_proto __read_mostly = { diff --git a/target/linux/qualcommax/patches-6.6/0603-4-qca-nss-clients-add-iptunnel-support.patch b/target/linux/qualcommax/patches-6.6/0603-4-qca-nss-clients-add-iptunnel-support.patch new file mode 100644 index 00000000000000..c9fc33686480ec --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0603-4-qca-nss-clients-add-iptunnel-support.patch @@ -0,0 +1,77 @@ +--- a/include/net/ip6_tunnel.h ++++ b/include/net/ip6_tunnel.h +@@ -36,6 +36,7 @@ struct __ip6_tnl_parm { + __u8 proto; /* tunnel protocol */ + __u8 encap_limit; /* encapsulation limit for tunnel */ + __u8 hop_limit; /* hop limit for tunnel */ ++ __u8 draft03; /* FMR using draft03 of map-e - QCA NSS Clients Support */ + bool collect_md; + __be32 flowinfo; /* traffic class and flowlabel for tunnel */ + __u32 flags; /* tunnel flags */ +--- a/include/net/ip_tunnels.h ++++ b/include/net/ip_tunnels.h +@@ -558,4 +558,9 @@ static inline void ip_tunnel_info_opts_s + + #endif /* CONFIG_INET */ + ++/* QCA NSS Clients Support - Start */ ++void ipip6_update_offload_stats(struct net_device *dev, void *ptr); ++void ip6_update_offload_stats(struct net_device *dev, void *ptr); ++/* QCA NSS Clients Support - End */ ++ + #endif /* __NET_IP_TUNNELS_H */ +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -2411,6 +2411,26 @@ nla_put_failure: + return -EMSGSIZE; + } + ++/* QCA NSS Client Support - Start */ ++/* ++ * Update offload stats ++ */ ++void ip6_update_offload_stats(struct net_device *dev, void *ptr) ++{ ++ struct pcpu_sw_netstats *tstats = per_cpu_ptr(dev->tstats, 0); ++ const struct pcpu_sw_netstats *offload_stats = ++ (struct pcpu_sw_netstats *)ptr; ++ ++ u64_stats_update_begin(&tstats->syncp); ++ u64_stats_add(&tstats->tx_packets, u64_stats_read(&offload_stats->tx_packets)); ++ u64_stats_add(&tstats->tx_bytes, u64_stats_read(&offload_stats->tx_bytes)); ++ u64_stats_add(&tstats->rx_packets, u64_stats_read(&offload_stats->rx_packets)); ++ u64_stats_add(&tstats->rx_bytes, u64_stats_read(&offload_stats->rx_bytes)); ++ u64_stats_update_end(&tstats->syncp); ++} ++EXPORT_SYMBOL(ip6_update_offload_stats); ++/* QCA NSS Client Support - End */ ++ + struct net *ip6_tnl_get_link_net(const struct net_device *dev) + { + struct ip6_tnl *tunnel = netdev_priv(dev); +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -1733,6 +1733,23 @@ nla_put_failure: + return -EMSGSIZE; + } + ++/* QCA NSS Clients Support - Start */ ++void ipip6_update_offload_stats(struct net_device *dev, void *ptr) ++{ ++ struct pcpu_sw_netstats *tstats = per_cpu_ptr(dev->tstats, 0); ++ const struct pcpu_sw_netstats *offload_stats = ++ (struct pcpu_sw_netstats *)ptr; ++ ++ u64_stats_update_begin(&tstats->syncp); ++ u64_stats_add(&tstats->tx_packets, u64_stats_read(&offload_stats->tx_packets)); ++ u64_stats_add(&tstats->tx_bytes, u64_stats_read(&offload_stats->tx_bytes)); ++ u64_stats_add(&tstats->rx_packets, u64_stats_read(&offload_stats->rx_packets)); ++ u64_stats_add(&tstats->rx_bytes, u64_stats_read(&offload_stats->rx_bytes)); ++ u64_stats_update_end(&tstats->syncp); ++} ++EXPORT_SYMBOL(ipip6_update_offload_stats); ++/* QCA NSS Clients Support - End */ ++ + static const struct nla_policy ipip6_policy[IFLA_IPTUN_MAX + 1] = { + [IFLA_IPTUN_LINK] = { .type = NLA_U32 }, + [IFLA_IPTUN_LOCAL] = { .type = NLA_U32 }, diff --git a/target/linux/qualcommax/patches-6.6/0603-5-qca-nss-clients-add-vxlan-support.patch b/target/linux/qualcommax/patches-6.6/0603-5-qca-nss-clients-add-vxlan-support.patch new file mode 100644 index 00000000000000..7d05fd1aff619c --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0603-5-qca-nss-clients-add-vxlan-support.patch @@ -0,0 +1,103 @@ +--- a/drivers/net/vxlan/vxlan_core.c ++++ b/drivers/net/vxlan/vxlan_core.c +@@ -29,6 +29,20 @@ + #include + #include + ++ATOMIC_NOTIFIER_HEAD(vxlan_fdb_notifier_list); ++ ++void vxlan_fdb_register_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_register(&vxlan_fdb_notifier_list, nb); ++} ++EXPORT_SYMBOL(vxlan_fdb_register_notify); ++ ++void vxlan_fdb_unregister_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_unregister(&vxlan_fdb_notifier_list, nb); ++} ++EXPORT_SYMBOL(vxlan_fdb_unregister_notify); ++ + #if IS_ENABLED(CONFIG_IPV6) + #include + #include +@@ -260,6 +274,7 @@ static void __vxlan_fdb_notify(struct vx + { + struct net *net = dev_net(vxlan->dev); + struct sk_buff *skb; ++ struct vxlan_fdb_event vfe; + int err = -ENOBUFS; + + skb = nlmsg_new(vxlan_nlmsg_size(), GFP_ATOMIC); +@@ -275,6 +290,10 @@ static void __vxlan_fdb_notify(struct vx + } + + rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); ++ vfe.dev = vxlan->dev; ++ vfe.rdst = rd; ++ ether_addr_copy(vfe.eth_addr, fdb->eth_addr); ++ atomic_notifier_call_chain(&vxlan_fdb_notifier_list, type, (void *)&vfe); + return; + errout: + if (err < 0) +@@ -441,6 +460,18 @@ static struct vxlan_fdb *vxlan_find_mac( + return f; + } + ++/* Find and update age of fdb entry corresponding to MAC. */ ++void vxlan_fdb_update_mac(struct vxlan_dev *vxlan, const u8 *mac, uint32_t vni) ++{ ++ u32 hash_index; ++ ++ hash_index = fdb_head_index(vxlan, mac, vni); ++ spin_lock_bh(&vxlan->hash_lock[hash_index]); ++ vxlan_find_mac(vxlan, mac, vni); ++ spin_unlock_bh(&vxlan->hash_lock[hash_index]); ++} ++EXPORT_SYMBOL(vxlan_fdb_update_mac); ++ + /* caller should hold vxlan->hash_lock */ + static struct vxlan_rdst *vxlan_fdb_find_rdst(struct vxlan_fdb *f, + union vxlan_addr *ip, __be16 port, +@@ -2581,6 +2612,9 @@ void vxlan_xmit_one(struct sk_buff *skb, + goto out_unlock; + } + ++ /* Reset the skb_iif to Tunnels interface index */ ++ skb->skb_iif = dev->ifindex; ++ + tos = ip_tunnel_ecn_encap(tos, old_iph, skb); + ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); + err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr), +@@ -2652,6 +2686,9 @@ void vxlan_xmit_one(struct sk_buff *skb, + if (err < 0) + goto tx_error; + ++ /* Reset the skb_iif to Tunnels interface index */ ++ skb->skb_iif = dev->ifindex; ++ + udp_tunnel6_xmit_skb(ndst, sock6->sock->sk, skb, dev, + &local_ip.sin6.sin6_addr, + &dst->sin6.sin6_addr, tos, ttl, +--- a/include/net/vxlan.h ++++ b/include/net/vxlan.h +@@ -352,6 +352,19 @@ struct vxlan_dev { + VXLAN_F_VNIFILTER | \ + VXLAN_F_LOCALBYPASS) + ++/* ++ * Application data for fdb notifier event ++ */ ++struct vxlan_fdb_event { ++ struct net_device *dev; ++ struct vxlan_rdst *rdst; ++ u8 eth_addr[ETH_ALEN]; ++}; ++ ++extern void vxlan_fdb_register_notify(struct notifier_block *nb); ++extern void vxlan_fdb_unregister_notify(struct notifier_block *nb); ++extern void vxlan_fdb_update_mac(struct vxlan_dev *vxlan, const u8 *mac, uint32_t vni); ++ + struct net_device *vxlan_dev_create(struct net *net, const char *name, + u8 name_assign_type, struct vxlan_config *conf); + diff --git a/target/linux/qualcommax/patches-6.6/0603-6-qca-nss-clients-add-l2tp-offloading-support.patch b/target/linux/qualcommax/patches-6.6/0603-6-qca-nss-clients-add-l2tp-offloading-support.patch new file mode 100644 index 00000000000000..4032eb3c227134 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0603-6-qca-nss-clients-add-l2tp-offloading-support.patch @@ -0,0 +1,368 @@ +--- a/include/linux/ppp_channel.h ++++ b/include/linux/ppp_channel.h +@@ -61,6 +61,51 @@ struct ppp_channel { + }; + + #ifdef __KERNEL__ ++/* Call this to obtain the underlying protocol of the PPP channel, ++ * e.g. PX_PROTO_OE ++ */ ++extern int ppp_channel_get_protocol(struct ppp_channel *); ++ ++/* Call this to hold a channel */ ++extern bool ppp_channel_hold(struct ppp_channel *); ++ ++/* Call this to release a hold you have upon a channel */ ++extern void ppp_channel_release(struct ppp_channel *); ++ ++/* Release hold on PPP channels */ ++extern void ppp_release_channels(struct ppp_channel *channels[], ++ unsigned int chan_sz); ++ ++/* Test if ppp xmit lock is locked */ ++extern bool ppp_is_xmit_locked(struct net_device *dev); ++ ++/* Call this get protocol version */ ++extern int ppp_channel_get_proto_version(struct ppp_channel *); ++ ++/* Get the device index associated with a channel, or 0, if none */ ++extern int ppp_dev_index(struct ppp_channel *); ++ ++/* Hold PPP channels for the PPP device */ ++extern int ppp_hold_channels(struct net_device *dev, ++ struct ppp_channel *channels[], ++ unsigned int chan_sz); ++extern int __ppp_hold_channels(struct net_device *dev, ++ struct ppp_channel *channels[], ++ unsigned int chan_sz); ++ ++/* Test if the ppp device is a multi-link ppp device */ ++extern int ppp_is_multilink(struct net_device *dev); ++extern int __ppp_is_multilink(struct net_device *dev); ++ ++/* Update statistics of the PPP net_device by incrementing related ++ * statistics field value with corresponding parameter ++ */ ++extern void ppp_update_stats(struct net_device *dev, unsigned long rx_packets, ++ unsigned long rx_bytes, unsigned long tx_packets, ++ unsigned long tx_bytes, unsigned long rx_errors, ++ unsigned long tx_errors, unsigned long rx_dropped, ++ unsigned long tx_dropped); ++ + /* Called by the channel when it can send some more data. */ + extern void ppp_output_wakeup(struct ppp_channel *); + +@@ -148,5 +193,17 @@ extern void ppp_update_stats(struct net_ + * that ppp_unregister_channel returns. + */ + ++/* QCA NSS Clients Support - Start */ ++/* PPP channel connection event types */ ++#define PPP_CHANNEL_DISCONNECT 0 ++#define PPP_CHANNEL_CONNECT 1 ++ ++/* Register the PPP channel connect notifier */ ++extern void ppp_channel_connection_register_notify(struct notifier_block *nb); ++ ++/* Unregister the PPP channel connect notifier */ ++extern void ppp_channel_connection_unregister_notify(struct notifier_block *nb); ++/* QCA NSS Clients Support - End */ ++ + #endif /* __KERNEL__ */ + #endif +--- a/include/linux/if_pppol2tp.h ++++ b/include/linux/if_pppol2tp.h +@@ -12,4 +12,30 @@ + #include + #include + ++/* QCA NSS ECM support - Start */ ++/* ++ * Holds L2TP channel info ++ */ ++struct pppol2tp_common_addr { ++ int tunnel_version; /* v2 or v3 */ ++ __u32 local_tunnel_id, remote_tunnel_id; /* tunnel id */ ++ __u32 local_session_id, remote_session_id; /* session id */ ++ struct sockaddr_in local_addr, remote_addr; /* ip address and port */ ++}; ++ ++/* ++ * L2TP channel operations ++ */ ++struct pppol2tp_channel_ops { ++ struct ppp_channel_ops ops; /* ppp channel ops */ ++}; ++ ++/* ++ * exported function which calls pppol2tp channel's get addressing ++ * function ++ */ ++extern int pppol2tp_channel_addressing_get(struct ppp_channel *, ++ struct pppol2tp_common_addr *); ++/* QCA NSS ECM support - End */ ++ + #endif +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -123,9 +123,17 @@ struct pppol2tp_session { + }; + + static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb); +- +-static const struct ppp_channel_ops pppol2tp_chan_ops = { +- .start_xmit = pppol2tp_xmit, ++static int pppol2tp_get_channel_protocol(struct ppp_channel *); ++static int pppol2tp_get_channel_protocol_ver(struct ppp_channel *); ++static void pppol2tp_hold_chan(struct ppp_channel *); ++static void pppol2tp_release_chan(struct ppp_channel *); ++ ++static const struct pppol2tp_channel_ops pppol2tp_chan_ops = { ++ .ops.start_xmit = pppol2tp_xmit, ++ .ops.get_channel_protocol = pppol2tp_get_channel_protocol, ++ .ops.get_channel_protocol_ver = pppol2tp_get_channel_protocol_ver, ++ .ops.hold = pppol2tp_hold_chan, ++ .ops.release = pppol2tp_release_chan, + }; + + static const struct proto_ops pppol2tp_ops; +@@ -373,6 +381,13 @@ static int pppol2tp_xmit(struct ppp_chan + skb->data[0] = PPP_ALLSTATIONS; + skb->data[1] = PPP_UI; + ++ /* QCA NSS ECM support - start */ ++ /* set incoming interface as the ppp interface */ ++ if ((skb->protocol == htons(ETH_P_IP)) || ++ (skb->protocol == htons(ETH_P_IPV6))) ++ skb->skb_iif = ppp_dev_index(chan); ++ /* QCA NSS ECM support - End */ ++ + local_bh_disable(); + l2tp_xmit_skb(session, skb); + local_bh_enable(); +@@ -818,7 +833,7 @@ static int pppol2tp_connect(struct socke + po->chan.hdrlen = PPPOL2TP_L2TP_HDR_SIZE_NOSEQ; + + po->chan.private = sk; +- po->chan.ops = &pppol2tp_chan_ops; ++ po->chan.ops = (struct ppp_channel_ops *)&pppol2tp_chan_ops.ops; + po->chan.mtu = pppol2tp_tunnel_mtu(tunnel); + + error = ppp_register_net_channel(sock_net(sk), &po->chan); +@@ -1732,6 +1747,109 @@ static void __exit pppol2tp_exit(void) + unregister_pernet_device(&pppol2tp_net_ops); + } + ++/* QCA NSS ECM support - Start */ ++/* pppol2tp_hold_chan() */ ++static void pppol2tp_hold_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_hold(sk); ++} ++ ++/* pppol2tp_release_chan() */ ++static void pppol2tp_release_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_put(sk); ++} ++ ++/* pppol2tp_get_channel_protocol() ++ * Return the protocol type of the L2TP over PPP protocol ++ */ ++static int pppol2tp_get_channel_protocol(struct ppp_channel *chan) ++{ ++ return PX_PROTO_OL2TP; ++} ++ ++/* pppol2tp_get_channel_protocol_ver() ++ * Return the protocol version of the L2TP over PPP protocol ++ */ ++static int pppol2tp_get_channel_protocol_ver(struct ppp_channel *chan) ++{ ++ struct sock *sk; ++ struct l2tp_session *session; ++ struct l2tp_tunnel *tunnel; ++ int version = 0; ++ ++ if (chan && chan->private) ++ sk = (struct sock *)chan->private; ++ else ++ return -1; ++ ++ /* Get session and tunnel contexts from the socket */ ++ session = pppol2tp_sock_to_session(sk); ++ if (!session) ++ return -1; ++ ++ tunnel = session->tunnel; ++ if (!tunnel) { ++ sock_put(sk); ++ return -1; ++ } ++ ++ version = tunnel->version; ++ ++ sock_put(sk); ++ ++ return version; ++} ++ ++/* pppol2tp_get_addressing() */ ++static int pppol2tp_get_addressing(struct ppp_channel *chan, ++ struct pppol2tp_common_addr *addr) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ struct l2tp_session *session; ++ struct l2tp_tunnel *tunnel; ++ struct inet_sock *isk = NULL; ++ int err = -ENXIO; ++ ++ /* Get session and tunnel contexts from the socket */ ++ session = pppol2tp_sock_to_session(sk); ++ if (!session) ++ return err; ++ ++ tunnel = session->tunnel; ++ if (!tunnel) { ++ sock_put(sk); ++ return err; ++ } ++ isk = inet_sk(tunnel->sock); ++ ++ addr->local_tunnel_id = tunnel->tunnel_id; ++ addr->remote_tunnel_id = tunnel->peer_tunnel_id; ++ addr->local_session_id = session->session_id; ++ addr->remote_session_id = session->peer_session_id; ++ ++ addr->local_addr.sin_port = isk->inet_sport; ++ addr->remote_addr.sin_port = isk->inet_dport; ++ addr->local_addr.sin_addr.s_addr = isk->inet_saddr; ++ addr->remote_addr.sin_addr.s_addr = isk->inet_daddr; ++ ++ sock_put(sk); ++ return 0; ++} ++ ++/* pppol2tp_channel_addressing_get() */ ++int pppol2tp_channel_addressing_get(struct ppp_channel *chan, ++ struct pppol2tp_common_addr *addr) ++{ ++ return pppol2tp_get_addressing(chan, addr); ++} ++EXPORT_SYMBOL(pppol2tp_channel_addressing_get); ++/* QCA NSS ECM support - End */ ++ + module_init(pppol2tp_init); + module_exit(pppol2tp_exit); + +--- a/drivers/net/ppp/ppp_generic.c ++++ b/drivers/net/ppp/ppp_generic.c +@@ -3743,6 +3743,32 @@ int ppp_is_multilink(struct net_device * + } + EXPORT_SYMBOL(ppp_is_multilink); + ++/* __ppp_is_multilink() ++ * Returns >0 if the device is a multilink PPP netdevice, 0 if not or < 0 ++ * if the device is not PPP. Caller should acquire ppp_lock before calling ++ * this function ++ */ ++int __ppp_is_multilink(struct net_device *dev) ++{ ++ struct ppp *ppp; ++ unsigned int flags; ++ ++ if (!dev) ++ return -1; ++ ++ if (dev->type != ARPHRD_PPP) ++ return -1; ++ ++ ppp = netdev_priv(dev); ++ flags = ppp->flags; ++ ++ if (flags & SC_MULTILINK) ++ return 1; ++ ++ return 0; ++} ++EXPORT_SYMBOL(__ppp_is_multilink); ++ + /* ppp_channel_get_protocol() + * Call this to obtain the underlying protocol of the PPP channel, + * e.g. PX_PROTO_OE +@@ -3881,6 +3907,59 @@ int ppp_hold_channels(struct net_device + } + EXPORT_SYMBOL(ppp_hold_channels); + ++/* __ppp_hold_channels() ++ * Returns the PPP channels of the PPP device, storing each one into ++ * channels[]. ++ * ++ * channels[] has chan_sz elements. ++ * This function returns the number of channels stored, up to chan_sz. ++ * It will return < 0 if the device is not PPP. ++ * ++ * You MUST release the channels using ppp_release_channels(). ++ */ ++int __ppp_hold_channels(struct net_device *dev, struct ppp_channel *channels[], ++ unsigned int chan_sz) ++{ ++ struct ppp *ppp; ++ int c; ++ struct channel *pch; ++ ++ if (!dev) ++ return -1; ++ ++ if (dev->type != ARPHRD_PPP) ++ return -1; ++ ++ ppp = netdev_priv(dev); ++ ++ c = 0; ++ list_for_each_entry(pch, &ppp->channels, clist) { ++ struct ppp_channel *chan; ++ ++ if (!pch->chan) { ++ /* Channel is going / gone away */ ++ continue; ++ } ++ ++ if (c == chan_sz) { ++ /* No space to record channel */ ++ return c; ++ } ++ ++ /* Hold the channel, if supported */ ++ chan = pch->chan; ++ if (!chan->ops->hold) ++ continue; ++ ++ chan->ops->hold(chan); ++ ++ /* Record the channel */ ++ channels[c++] = chan; ++ } ++ return c; ++} ++EXPORT_SYMBOL(__ppp_hold_channels); ++ + /* ppp_release_channels() + * Releases channels + */ +--- a/net/l2tp/l2tp_core.h ++++ b/net/l2tp/l2tp_core.h +@@ -235,6 +235,9 @@ struct l2tp_session *l2tp_session_get_by + void l2tp_stats_update(struct l2tp_tunnel *tunnel, struct l2tp_session *session, + struct l2tp_stats *stats); + ++void l2tp_stats_update(struct l2tp_tunnel *tunnel, struct l2tp_session *session, ++ struct l2tp_stats *stats); ++ + /* Tunnel and session lifetime management. + * Creation of a new instance is a two-step process: create, then register. + * Destruction is triggered using the *_delete functions, and completes asynchronously. diff --git a/target/linux/qualcommax/patches-6.6/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch b/target/linux/qualcommax/patches-6.6/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch new file mode 100644 index 00000000000000..e4ed49ea4c21fb --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch @@ -0,0 +1,22 @@ +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -2417,7 +2417,7 @@ nla_put_failure: + */ + void ip6_update_offload_stats(struct net_device *dev, void *ptr) + { +- struct pcpu_sw_netstats *tstats = per_cpu_ptr(dev->tstats, 0); ++ struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats); + const struct pcpu_sw_netstats *offload_stats = + (struct pcpu_sw_netstats *)ptr; + +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -1736,7 +1736,7 @@ nla_put_failure: + /* QCA NSS Clients Support - Start */ + void ipip6_update_offload_stats(struct net_device *dev, void *ptr) + { +- struct pcpu_sw_netstats *tstats = per_cpu_ptr(dev->tstats, 0); ++ struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats); + const struct pcpu_sw_netstats *offload_stats = + (struct pcpu_sw_netstats *)ptr; + diff --git a/target/linux/qualcommax/patches-6.6/0603-8-qca-nss-clients-add-tls-mgr-support.patch b/target/linux/qualcommax/patches-6.6/0603-8-qca-nss-clients-add-tls-mgr-support.patch new file mode 100644 index 00000000000000..0499e237f6be88 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0603-8-qca-nss-clients-add-tls-mgr-support.patch @@ -0,0 +1,24 @@ +--- /dev/null ++++ b/include/uapi/linux/tlshdr.h +@@ -0,0 +1,21 @@ ++#ifndef _UAPI_LINUX_TLSHDR_H ++#define _UAPI_LINUX_TLSHDR_H ++ ++#include ++ ++struct tlshdr { ++ __u8 type; ++ __be16 version; ++ __be16 len; ++} __attribute__((packed)); ++ ++#define TLSHDR_REC_TYPE_CCS 20 /* TLS packet is change cipher specification */ ++#define TLSHDR_REC_TYPE_ALERT 21 /* TLS packet is Alert */ ++#define TLSHDR_REC_TYPE_HANDSHAKE 22 /* TLS packet is Handshake */ ++#define TLSHDR_REC_TYPE_DATA 23 /* TLS packet is Application data */ ++ ++#define TLSHDR_VERSION_1_1 0x0302 /* TLS Header Version(tls 1.1) */ ++#define TLSHDR_VERSION_1_2 0x0303 /* TLS Header Version(tls 1.2) */ ++#define TLSHDR_VERSION_1_3 0x0304 /* TLS Header Version(tls 1.3) */ ++ ++#endif /* _UAPI_LINUX_TLSHDR_H */ diff --git a/target/linux/qualcommax/patches-6.6/0604-1-qca-add-mcs-support.patch b/target/linux/qualcommax/patches-6.6/0604-1-qca-add-mcs-support.patch new file mode 100644 index 00000000000000..edf21700c3e94c --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0604-1-qca-add-mcs-support.patch @@ -0,0 +1,876 @@ +--- a/include/linux/if_bridge.h ++++ b/include/linux/if_bridge.h +@@ -258,4 +258,17 @@ extern br_get_dst_hook_t __rcu *br_get_d + extern struct net_device *br_fdb_bridge_dev_get_and_hold(struct net_bridge *br); + /* QCA NSS bridge-mgr support - End */ + ++/* QCA qca-mcs support - Start */ ++typedef struct net_bridge_port *br_get_dst_hook_t(const struct net_bridge_port *src, ++ struct sk_buff **skb); ++extern br_get_dst_hook_t __rcu *br_get_dst_hook; ++ ++typedef int (br_multicast_handle_hook_t)(const struct net_bridge_port *src, ++ struct sk_buff *skb); ++extern br_multicast_handle_hook_t __rcu *br_multicast_handle_hook; ++ ++typedef void (br_notify_hook_t)(int group, int event, const void *ptr); ++extern br_notify_hook_t __rcu *br_notify_hook; ++/* QCA qca-mcs support - End */ ++ + #endif +--- a/net/bridge/br_fdb.c ++++ b/net/bridge/br_fdb.c +@@ -239,6 +239,8 @@ static void fdb_notify(struct net_bridge + kfree_skb(skb); + goto errout; + } ++ ++ __br_notify(RTNLGRP_NEIGH, type, fdb); /* QCA qca-mcs support */ + rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); + return; + errout: +@@ -305,6 +307,7 @@ struct net_bridge_fdb_entry *br_fdb_find + { + return fdb_find_rcu(&br->fdb_hash_tbl, addr, vid); + } ++EXPORT_SYMBOL_GPL(br_fdb_find_rcu); /* QCA qca-mcs support */ + + /* When a static FDB entry is added, the mac address from the entry is + * added to the bridge private HW address list and all required ports +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -906,6 +906,7 @@ void br_manage_promisc(struct net_bridge + int nbp_backup_change(struct net_bridge_port *p, struct net_device *backup_dev); + + /* br_input.c */ ++int br_pass_frame_up(struct sk_buff *skb); /* QCA qca-mcs support */ + int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb); + rx_handler_func_t *br_get_rx_handler(const struct net_device *dev); + +@@ -2268,4 +2269,14 @@ struct nd_msg *br_is_nd_neigh_msg(struct + bool br_is_neigh_suppress_enabled(const struct net_bridge_port *p, u16 vid); + #define __br_get(__hook, __default, __args ...) \ + (__hook ? (__hook(__args)) : (__default)) /* QCA NSS ECM support */ ++ ++/* QCA qca-mcs support - Start */ ++static inline void __br_notify(int group, int type, const void *data) ++{ ++ br_notify_hook_t *notify_hook = rcu_dereference(br_notify_hook); ++ ++ if (notify_hook) ++ notify_hook(group, type, data); ++} ++/* QCA qca-mcs support - End */ + #endif +--- a/net/bridge/br_netlink.c ++++ b/net/bridge/br_netlink.c +@@ -656,6 +656,7 @@ void br_info_notify(int event, const str + kfree_skb(skb); + goto errout; + } ++ __br_notify(RTNLGRP_LINK, event, port); /* QCA qca-mcs support */ + rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC); + return; + errout: +--- a/net/bridge/br.c ++++ b/net/bridge/br.c +@@ -472,6 +472,12 @@ static void __exit br_deinit(void) + br_fdb_fini(); + } + ++/* QCA qca-mcs support - Start */ ++/* Hook for bridge event notifications */ ++br_notify_hook_t __rcu *br_notify_hook __read_mostly; ++EXPORT_SYMBOL_GPL(br_notify_hook); ++/* QCA qca-mcs support - End */ ++ + module_init(br_init) + module_exit(br_deinit) + MODULE_LICENSE("GPL"); +--- a/net/bridge/br_device.c ++++ b/net/bridge/br_device.c +@@ -83,6 +83,13 @@ netdev_tx_t br_dev_xmit(struct sk_buff * + if (is_broadcast_ether_addr(dest)) { + br_flood(br, skb, BR_PKT_BROADCAST, false, true, vid); + } else if (is_multicast_ether_addr(dest)) { ++ /* QCA qca-mcs support - Start */ ++ br_multicast_handle_hook_t *multicast_handle_hook = ++ rcu_dereference(br_multicast_handle_hook); ++ if (!__br_get(multicast_handle_hook, true, NULL, skb)) ++ goto out; ++ /* QCA qca-mcs support - End */ ++ + if (unlikely(netpoll_tx_running(dev))) { + br_flood(br, skb, BR_PKT_MULTICAST, false, true, vid); + goto out; +--- a/net/bridge/br_input.c ++++ b/net/bridge/br_input.c +@@ -30,7 +30,17 @@ br_netif_receive_skb(struct net *net, st + return netif_receive_skb(skb); + } + +-static int br_pass_frame_up(struct sk_buff *skb) ++/* QCA qca-mcs support - Start */ ++/* Hook for external Multicast handler */ ++br_multicast_handle_hook_t __rcu *br_multicast_handle_hook __read_mostly; ++EXPORT_SYMBOL_GPL(br_multicast_handle_hook); ++ ++/* Hook for external forwarding logic */ ++br_get_dst_hook_t __rcu *br_get_dst_hook __read_mostly; ++EXPORT_SYMBOL_GPL(br_get_dst_hook); ++/* QCA qca-mcs support - End */ ++ ++int br_pass_frame_up(struct sk_buff *skb) + { + struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev; + struct net_bridge *br = netdev_priv(brdev); +@@ -69,6 +79,7 @@ static int br_pass_frame_up(struct sk_bu + dev_net(indev), NULL, skb, indev, NULL, + br_netif_receive_skb); + } ++EXPORT_SYMBOL_GPL(br_pass_frame_up); /* QCA qca-mcs support */ + + /* note: already called with rcu_read_lock */ + int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb) +@@ -82,6 +93,11 @@ int br_handle_frame_finish(struct net *n + struct net_bridge_mcast *brmctx; + struct net_bridge_vlan *vlan; + struct net_bridge *br; ++ /* QCA qca-mcs support - Start */ ++ br_multicast_handle_hook_t *multicast_handle_hook; ++ struct net_bridge_port *pdst = NULL; ++ br_get_dst_hook_t *get_dst_hook = rcu_dereference(br_get_dst_hook); ++ /* QCA qca-mcs support - End */ + u16 vid = 0; + u8 state; + +@@ -175,6 +191,12 @@ int br_handle_frame_finish(struct net *n + + switch (pkt_type) { + case BR_PKT_MULTICAST: ++ /* QCA qca-mcs support - Start */ ++ multicast_handle_hook = rcu_dereference(br_multicast_handle_hook); ++ if (!__br_get(multicast_handle_hook, true, p, skb)) ++ goto out; ++ /* QCA qca-mcs support - End */ ++ + mdst = br_mdb_get(brmctx, skb, vid); + if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) && + br_multicast_querier_exists(brmctx, eth_hdr(skb), mdst)) { +@@ -190,8 +212,15 @@ int br_handle_frame_finish(struct net *n + } + break; + case BR_PKT_UNICAST: +- dst = br_fdb_find_rcu(br, eth_hdr(skb)->h_dest, vid); +- break; ++ /* QCA qca-mcs support - Start */ ++ pdst = __br_get(get_dst_hook, NULL, p, &skb); ++ if (pdst) { ++ if (!skb) ++ goto out; ++ } else { ++ /* QCA qca-mcs support - End */ ++ dst = br_fdb_find_rcu(br, eth_hdr(skb)->h_dest, vid); ++ } + default: + break; + } +@@ -206,6 +235,13 @@ int br_handle_frame_finish(struct net *n + dst->used = now; + br_forward(dst->dst, skb, local_rcv, false); + } else { ++ /* QCA qca-mcs support - Start */ ++ if (pdst) { ++ br_forward(pdst, skb, local_rcv, false); ++ goto out; ++ } ++ /* QCA qca-mcs support - End */ ++ + if (!mcast_hit) + br_flood(br, skb, pkt_type, local_rcv, false, vid); + else +--- a/include/linux/mroute.h ++++ b/include/linux/mroute.h +@@ -92,4 +92,44 @@ struct rtmsg; + int ipmr_get_route(struct net *net, struct sk_buff *skb, + __be32 saddr, __be32 daddr, + struct rtmsg *rtm, u32 portid); ++ ++/* QCA ECM qca-mcs support - Start */ ++#define IPMR_MFC_EVENT_UPDATE 1 ++#define IPMR_MFC_EVENT_DELETE 2 ++ ++/* ++ * Callback to registered modules in the event of updates to a multicast group ++ */ ++typedef void (*ipmr_mfc_event_offload_callback_t)(__be32 origin, __be32 group, ++ u32 max_dest_dev, ++ u32 dest_dev_idx[], ++ u8 op); ++ ++/* ++ * Register the callback used to inform offload modules when updates occur to ++ * MFC. The callback is registered by offload modules ++ */ ++extern bool ipmr_register_mfc_event_offload_callback( ++ ipmr_mfc_event_offload_callback_t mfc_offload_cb); ++ ++/* ++ * De-Register the callback used to inform offload modules when updates occur ++ * to MFC ++ */ ++extern void ipmr_unregister_mfc_event_offload_callback(void); ++ ++/* ++ * Find the destination interface list, given a multicast group and source ++ */ ++extern int ipmr_find_mfc_entry(struct net *net, __be32 origin, __be32 group, ++ u32 max_dst_cnt, u32 dest_dev[]); ++ ++/* ++ * Out-of-band multicast statistics update for flows that are offloaded from ++ * Linux ++ */ ++extern int ipmr_mfc_stats_update(struct net *net, __be32 origin, __be32 group, ++ u64 pkts_in, u64 bytes_in, ++ u64 pkts_out, u64 bytes_out); ++/* QCA ECM qca-mcs support - End */ + #endif +--- a/include/linux/mroute6.h ++++ b/include/linux/mroute6.h +@@ -137,4 +137,47 @@ static inline int ip6mr_sk_ioctl(struct + return 1; + } + #endif ++ ++/* QCA qca-mcs support - Start */ ++#define IP6MR_MFC_EVENT_UPDATE 1 ++#define IP6MR_MFC_EVENT_DELETE 2 ++ ++/* ++ * Callback to registered modules in the event of updates to a multicast group ++ */ ++typedef void (*ip6mr_mfc_event_offload_callback_t)(struct in6_addr *origin, ++ struct in6_addr *group, ++ u32 max_dest_dev, ++ u32 dest_dev_idx[], ++ uint8_t op); ++ ++/* ++ * Register the callback used to inform offload modules when updates occur ++ * to MFC. The callback is registered by offload modules ++ */ ++extern bool ip6mr_register_mfc_event_offload_callback( ++ ip6mr_mfc_event_offload_callback_t mfc_offload_cb); ++ ++/* ++ * De-Register the callback used to inform offload modules when updates occur ++ * to MFC ++ */ ++extern void ip6mr_unregister_mfc_event_offload_callback(void); ++ ++/* ++ * Find the destination interface list given a multicast group and source ++ */ ++extern int ip6mr_find_mfc_entry(struct net *net, struct in6_addr *origin, ++ struct in6_addr *group, u32 max_dst_cnt, ++ u32 dest_dev[]); ++ ++/* ++ * Out-of-band multicast statistics update for flows that are offloaded from ++ * Linux ++ */ ++extern int ip6mr_mfc_stats_update(struct net *net, struct in6_addr *origin, ++ struct in6_addr *group, uint64_t pkts_in, ++ uint64_t bytes_in, uint64_t pkts_out, ++ uint64_t bytes_out); ++/* QCA qca-mcs support - End */ + #endif +--- a/net/ipv4/ipmr.c ++++ b/net/ipv4/ipmr.c +@@ -89,6 +89,9 @@ static struct net_device *vif_dev_read(c + /* Special spinlock for queue of unresolved entries */ + static DEFINE_SPINLOCK(mfc_unres_lock); + ++/* spinlock for offload */ ++static DEFINE_SPINLOCK(lock); /* QCA ECM qca-mcs support */ ++ + /* We return to original Alan's scheme. Hash table of resolved + * entries is changed only in process context and protected + * with weak lock mrt_lock. Queue of unresolved entries is protected +@@ -112,6 +115,9 @@ static void mroute_netlink_event(struct + static void igmpmsg_netlink_event(const struct mr_table *mrt, struct sk_buff *pkt); + static void mroute_clean_tables(struct mr_table *mrt, int flags); + static void ipmr_expire_process(struct timer_list *t); ++static struct mfc_cache *ipmr_cache_find(struct mr_table *mrt, __be32 origin, ++ __be32 mcastgrp); ++static ipmr_mfc_event_offload_callback_t __rcu ipmr_mfc_event_offload_callback; /* QCA ECM qca-mcs support */ + + #ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES + #define ipmr_for_each_table(mrt, net) \ +@@ -223,6 +229,80 @@ static int ipmr_rule_fill(struct fib_rul + return 0; + } + ++/* QCA ECM qca-mcs support - Start */ ++/* ipmr_sync_entry_update() ++ * Call the registered offload callback to report an update to a multicast ++ * route entry. The callback receives the list of destination interfaces and ++ * the interface count ++ */ ++static void ipmr_sync_entry_update(struct mr_table *mrt, ++ struct mfc_cache *cache) ++{ ++ int vifi, dest_if_count = 0; ++ u32 dest_dev[MAXVIFS]; ++ __be32 origin; ++ __be32 group; ++ ipmr_mfc_event_offload_callback_t offload_update_cb_f; ++ ++ memset(dest_dev, 0, sizeof(dest_dev)); ++ ++ origin = cache->mfc_origin; ++ group = cache->mfc_mcastgrp; ++ ++ spin_lock(&mrt_lock); ++ for (vifi = 0; vifi < cache->_c.mfc_un.res.maxvif; vifi++) { ++ if (!((cache->_c.mfc_un.res.ttls[vifi] > 0) && ++ (cache->_c.mfc_un.res.ttls[vifi] < 255))) { ++ continue; ++ } ++ if (dest_if_count == MAXVIFS) { ++ spin_unlock(&mrt_lock); ++ return; ++ } ++ ++ if (!VIF_EXISTS(mrt, vifi)) { ++ spin_unlock(&mrt_lock); ++ return; ++ } ++ dest_dev[dest_if_count] = mrt->vif_table[vifi].dev->ifindex; ++ dest_if_count++; ++ } ++ spin_unlock(&mrt_lock); ++ ++ rcu_read_lock(); ++ offload_update_cb_f = rcu_dereference(ipmr_mfc_event_offload_callback); ++ ++ if (!offload_update_cb_f) { ++ rcu_read_unlock(); ++ return; ++ } ++ ++ offload_update_cb_f(group, origin, dest_if_count, dest_dev, ++ IPMR_MFC_EVENT_UPDATE); ++ rcu_read_unlock(); ++} ++ ++/* ipmr_sync_entry_delete() ++ * Call the registered offload callback to inform of a multicast route entry ++ * delete event ++ */ ++static void ipmr_sync_entry_delete(u32 origin, u32 group) ++{ ++ ipmr_mfc_event_offload_callback_t offload_update_cb_f; ++ ++ rcu_read_lock(); ++ offload_update_cb_f = rcu_dereference(ipmr_mfc_event_offload_callback); ++ ++ if (!offload_update_cb_f) { ++ rcu_read_unlock(); ++ return; ++ } ++ ++ offload_update_cb_f(group, origin, 0, NULL, IPMR_MFC_EVENT_DELETE); ++ rcu_read_unlock(); ++} ++/* QCA ECM qca-mcs support - End */ ++ + static const struct fib_rules_ops __net_initconst ipmr_rules_ops_template = { + .family = RTNL_FAMILY_IPMR, + .rule_size = sizeof(struct ipmr_rule), +@@ -236,6 +316,156 @@ static const struct fib_rules_ops __net_ + .owner = THIS_MODULE, + }; + ++/* QCA ECM qca-mcs support - Start */ ++/* ipmr_register_mfc_event_offload_callback() ++ * Register the IPv4 Multicast update offload callback with IPMR ++ */ ++bool ipmr_register_mfc_event_offload_callback( ++ ipmr_mfc_event_offload_callback_t mfc_offload_cb) ++{ ++ ipmr_mfc_event_offload_callback_t offload_update_cb_f; ++ ++ rcu_read_lock(); ++ offload_update_cb_f = rcu_dereference(ipmr_mfc_event_offload_callback); ++ ++ if (offload_update_cb_f) { ++ rcu_read_unlock(); ++ return false; ++ } ++ rcu_read_unlock(); ++ ++ spin_lock(&lock); ++ rcu_assign_pointer(ipmr_mfc_event_offload_callback, mfc_offload_cb); ++ spin_unlock(&lock); ++ synchronize_rcu(); ++ return true; ++} ++EXPORT_SYMBOL(ipmr_register_mfc_event_offload_callback); ++ ++/* ipmr_unregister_mfc_event_offload_callback() ++ * De-register the IPv4 Multicast update offload callback with IPMR ++ */ ++void ipmr_unregister_mfc_event_offload_callback(void) ++{ ++ spin_lock(&lock); ++ rcu_assign_pointer(ipmr_mfc_event_offload_callback, NULL); ++ spin_unlock(&lock); ++ synchronize_rcu(); ++} ++EXPORT_SYMBOL(ipmr_unregister_mfc_event_offload_callback); ++ ++/* ipmr_find_mfc_entry() ++ * Returns destination interface list for a particular multicast flow, and ++ * the number of interfaces in the list ++ */ ++int ipmr_find_mfc_entry(struct net *net, __be32 origin, __be32 group, ++ u32 max_dest_cnt, u32 dest_dev[]) ++{ ++ int vifi, dest_if_count = 0; ++ struct mr_table *mrt; ++ struct mfc_cache *cache; ++ ++ mrt = ipmr_get_table(net, RT_TABLE_DEFAULT); ++ if (!mrt) ++ return -ENOENT; ++ ++ rcu_read_lock(); ++ cache = ipmr_cache_find(mrt, origin, group); ++ if (!cache) { ++ rcu_read_unlock(); ++ return -ENOENT; ++ } ++ ++ spin_lock(&mrt_lock); ++ for (vifi = 0; vifi < cache->_c.mfc_un.res.maxvif; vifi++) { ++ if (!((cache->_c.mfc_un.res.ttls[vifi] > 0) && ++ (cache->_c.mfc_un.res.ttls[vifi] < 255))) { ++ continue; ++ } ++ ++ /* We have another valid destination interface entry. Check if ++ * the number of the destination interfaces for the route is ++ * exceeding the size of the array given to us ++ */ ++ if (dest_if_count == max_dest_cnt) { ++ spin_unlock(&mrt_lock); ++ rcu_read_unlock(); ++ return -EINVAL; ++ } ++ ++ if (!VIF_EXISTS(mrt, vifi)) { ++ spin_unlock(&mrt_lock); ++ rcu_read_unlock(); ++ return -EINVAL; ++ } ++ ++ dest_dev[dest_if_count] = mrt->vif_table[vifi].dev->ifindex; ++ dest_if_count++; ++ } ++ spin_unlock(&mrt_lock); ++ rcu_read_unlock(); ++ ++ return dest_if_count; ++} ++EXPORT_SYMBOL(ipmr_find_mfc_entry); ++ ++/* ipmr_mfc_stats_update() ++ * Update the MFC/VIF statistics for offloaded flows ++ */ ++int ipmr_mfc_stats_update(struct net *net, __be32 origin, __be32 group, ++ u64 pkts_in, u64 bytes_in, ++ u64 pkts_out, u64 bytes_out) ++{ ++ int vif, vifi; ++ struct mr_table *mrt; ++ struct mfc_cache *cache; ++ ++ mrt = ipmr_get_table(net, RT_TABLE_DEFAULT); ++ if (!mrt) ++ return -ENOENT; ++ ++ rcu_read_lock(); ++ cache = ipmr_cache_find(mrt, origin, group); ++ if (!cache) { ++ rcu_read_unlock(); ++ return -ENOENT; ++ } ++ ++ vif = cache->_c.mfc_parent; ++ ++ spin_lock(&mrt_lock); ++ if (!VIF_EXISTS(mrt, vif)) { ++ spin_unlock(&mrt_lock); ++ rcu_read_unlock(); ++ return -EINVAL; ++ } ++ ++ mrt->vif_table[vif].pkt_in += pkts_in; ++ mrt->vif_table[vif].bytes_in += bytes_in; ++ cache->_c.mfc_un.res.pkt += pkts_out; ++ cache->_c.mfc_un.res.bytes += bytes_out; ++ ++ for (vifi = cache->_c.mfc_un.res.minvif; ++ vifi < cache->_c.mfc_un.res.maxvif; vifi++) { ++ if ((cache->_c.mfc_un.res.ttls[vifi] > 0) && ++ (cache->_c.mfc_un.res.ttls[vifi] < 255)) { ++ if (!VIF_EXISTS(mrt, vifi)) { ++ spin_unlock(&mrt_lock); ++ rcu_read_unlock(); ++ return -EINVAL; ++ } ++ mrt->vif_table[vifi].pkt_out += pkts_out; ++ mrt->vif_table[vifi].bytes_out += bytes_out; ++ } ++ } ++ spin_unlock(&mrt_lock); ++ rcu_read_unlock(); ++ ++ return 0; ++} ++EXPORT_SYMBOL(ipmr_mfc_stats_update); ++/* QCA ECM qca-mcs support - End */ ++ + static int __net_init ipmr_rules_init(struct net *net) + { + struct fib_rules_ops *ops; +@@ -1191,6 +1421,10 @@ static int ipmr_mfc_delete(struct mr_tab + call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, c, mrt->id); + mroute_netlink_event(mrt, c, RTM_DELROUTE); + mr_cache_put(&c->_c); ++ /* QCA ECM qca-mcs support - Start */ ++ /* Inform offload modules of the delete event */ ++ ipmr_sync_entry_delete(c->mfc_origin, c->mfc_mcastgrp); ++ /* QCA ECM qca-mcs support - End */ + + return 0; + } +@@ -1221,6 +1455,10 @@ static int ipmr_mfc_add(struct net *net, + call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_REPLACE, c, + mrt->id); + mroute_netlink_event(mrt, c, RTM_NEWROUTE); ++ /* QCA ECM qca-mcs support - Start */ ++ /* Inform offload modules of the update event */ ++ ipmr_sync_entry_update(mrt, c); ++ /* QCA ECM qca-mcs support - End */ + return 0; + } + +--- a/net/ipv6/ip6mr.c ++++ b/net/ipv6/ip6mr.c +@@ -74,6 +74,9 @@ static struct net_device *vif_dev_read(c + /* Special spinlock for queue of unresolved entries */ + static DEFINE_SPINLOCK(mfc_unres_lock); + ++/* Spinlock for offload */ ++static DEFINE_SPINLOCK(lock); /* QCA qca-mcs support */ ++ + /* We return to original Alan's scheme. Hash table of resolved + entries is changed only in process context and protected + with weak lock mrt_lock. Queue of unresolved entries is protected +@@ -101,6 +104,13 @@ static int ip6mr_rtm_dumproute(struct sk + struct netlink_callback *cb); + static void mroute_clean_tables(struct mr_table *mrt, int flags); + static void ipmr_expire_process(struct timer_list *t); ++/* QCA qca-mcs support - Start */ ++static struct mfc6_cache *ip6mr_cache_find(struct mr_table *mrt, ++ const struct in6_addr *origin, ++ const struct in6_addr *mcastgrp); ++static ip6mr_mfc_event_offload_callback_t __rcu ++ ip6mr_mfc_event_offload_callback; ++/* QCA qca-mcs support - End */ + + #ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES + #define ip6mr_for_each_table(mrt, net) \ +@@ -375,6 +385,84 @@ static struct mfc6_cache_cmp_arg ip6mr_m + .mf6c_mcastgrp = IN6ADDR_ANY_INIT, + }; + ++/* QCA qca-mcs support - Start */ ++/* ip6mr_sync_entry_update() ++ * Call the registered offload callback to report an update to a multicast ++ * route entry. The callback receives the list of destination interfaces and ++ * the interface count ++ */ ++static void ip6mr_sync_entry_update(struct mr_table *mrt, ++ struct mfc6_cache *cache) ++{ ++ int vifi, dest_if_count = 0; ++ u32 dest_dev[MAXMIFS]; ++ struct in6_addr mc_origin, mc_group; ++ ip6mr_mfc_event_offload_callback_t offload_update_cb_f; ++ ++ memset(dest_dev, 0, sizeof(dest_dev)); ++ ++ spin_lock(&mrt_lock); ++ ++ for (vifi = 0; vifi < cache->_c.mfc_un.res.maxvif; vifi++) { ++ if (!((cache->_c.mfc_un.res.ttls[vifi] > 0) && ++ (cache->_c.mfc_un.res.ttls[vifi] < 255))) { ++ continue; ++ } ++ ++ if (dest_if_count == MAXMIFS) { ++ spin_unlock(&mrt_lock); ++ return; ++ } ++ ++ if (!VIF_EXISTS(mrt, vifi)) { ++ spin_unlock(&mrt_lock); ++ return; ++ } ++ ++ dest_dev[dest_if_count] = mrt->vif_table[vifi].dev->ifindex; ++ dest_if_count++; ++ } ++ ++ memcpy(&mc_origin, &cache->mf6c_origin, sizeof(struct in6_addr)); ++ memcpy(&mc_group, &cache->mf6c_mcastgrp, sizeof(struct in6_addr)); ++ spin_unlock(&mrt_lock); ++ ++ rcu_read_lock(); ++ offload_update_cb_f = rcu_dereference(ip6mr_mfc_event_offload_callback); ++ ++ if (!offload_update_cb_f) { ++ rcu_read_unlock(); ++ return; ++ } ++ ++ offload_update_cb_f(&mc_group, &mc_origin, dest_if_count, dest_dev, ++ IP6MR_MFC_EVENT_UPDATE); ++ rcu_read_unlock(); ++} ++ ++/* ip6mr_sync_entry_delete() ++ * Call the registered offload callback to inform of a multicast route entry ++ * delete event ++ */ ++static void ip6mr_sync_entry_delete(struct in6_addr *mc_origin, ++ struct in6_addr *mc_group) ++{ ++ ip6mr_mfc_event_offload_callback_t offload_update_cb_f; ++ ++ rcu_read_lock(); ++ offload_update_cb_f = rcu_dereference(ip6mr_mfc_event_offload_callback); ++ ++ if (!offload_update_cb_f) { ++ rcu_read_unlock(); ++ return; ++ } ++ ++ offload_update_cb_f(mc_group, mc_origin, 0, NULL, ++ IP6MR_MFC_EVENT_DELETE); ++ rcu_read_unlock(); ++} ++/* QCA qca-mcs support - End */ ++ + static struct mr_table_ops ip6mr_mr_table_ops = { + .rht_params = &ip6mr_rht_params, + .cmparg_any = &ip6mr_mr_table_ops_cmparg_any, +@@ -697,6 +785,151 @@ static int call_ip6mr_mfc_entry_notifier + &mfc->_c, tb_id, &net->ipv6.ipmr_seq); + } + ++/* QCA qca-mcs support - Start */ ++/* ip6mr_register_mfc_event_offload_callback() ++ * Register the IPv6 multicast update callback for offload modules ++ */ ++bool ip6mr_register_mfc_event_offload_callback( ++ ip6mr_mfc_event_offload_callback_t mfc_offload_cb) ++{ ++ ip6mr_mfc_event_offload_callback_t offload_update_cb_f; ++ ++ rcu_read_lock(); ++ offload_update_cb_f = rcu_dereference(ip6mr_mfc_event_offload_callback); ++ ++ if (offload_update_cb_f) { ++ rcu_read_unlock(); ++ return false; ++ } ++ rcu_read_unlock(); ++ ++ spin_lock(&lock); ++ rcu_assign_pointer(ip6mr_mfc_event_offload_callback, mfc_offload_cb); ++ spin_unlock(&lock); ++ synchronize_rcu(); ++ return true; ++} ++EXPORT_SYMBOL(ip6mr_register_mfc_event_offload_callback); ++ ++/* ip6mr_unregister_mfc_event_offload_callback() ++ * De-register the IPv6 multicast update callback for offload modules ++ */ ++void ip6mr_unregister_mfc_event_offload_callback(void) ++{ ++ spin_lock(&lock); ++ rcu_assign_pointer(ip6mr_mfc_event_offload_callback, NULL); ++ spin_unlock(&lock); ++ synchronize_rcu(); ++} ++EXPORT_SYMBOL(ip6mr_unregister_mfc_event_offload_callback); ++ ++/* ip6mr_find_mfc_entry() ++ * Return the destination interface list for a particular multicast flow, and ++ * the number of interfaces in the list ++ */ ++int ip6mr_find_mfc_entry(struct net *net, struct in6_addr *origin, ++ struct in6_addr *group, u32 max_dest_cnt, ++ u32 dest_dev[]) ++{ ++ int vifi, dest_if_count = 0; ++ struct mr_table *mrt; ++ struct mfc6_cache *cache; ++ ++ mrt = ip6mr_get_table(net, RT6_TABLE_DFLT); ++ if (!mrt) ++ return -ENOENT; ++ ++ spin_lock(&mrt_lock); ++ cache = ip6mr_cache_find(mrt, origin, group); ++ if (!cache) { ++ spin_unlock(&mrt_lock); ++ return -ENOENT; ++ } ++ ++ for (vifi = 0; vifi < cache->_c.mfc_un.res.maxvif; vifi++) { ++ if (!((cache->_c.mfc_un.res.ttls[vifi] > 0) && ++ (cache->_c.mfc_un.res.ttls[vifi] < 255))) { ++ continue; ++ } ++ ++ /* We have another valid destination interface entry. Check if ++ * the number of the destination interfaces for the route is ++ * exceeding the size of the array given to us ++ */ ++ if (dest_if_count == max_dest_cnt) { ++ spin_unlock(&mrt_lock); ++ return -EINVAL; ++ } ++ ++ if (!VIF_EXISTS(mrt, vifi)) { ++ spin_unlock(&mrt_lock); ++ return -EINVAL; ++ } ++ ++ dest_dev[dest_if_count] = mrt->vif_table[vifi].dev->ifindex; ++ dest_if_count++; ++ } ++ spin_unlock(&mrt_lock); ++ ++ return dest_if_count; ++} ++EXPORT_SYMBOL(ip6mr_find_mfc_entry); ++ ++/* ip6mr_mfc_stats_update() ++ * Update the MFC/VIF statistics for offloaded flows ++ */ ++int ip6mr_mfc_stats_update(struct net *net, struct in6_addr *origin, ++ struct in6_addr *group, u64 pkts_in, ++ u64 bytes_in, uint64_t pkts_out, ++ u64 bytes_out) ++{ ++ int vif, vifi; ++ struct mr_table *mrt; ++ struct mfc6_cache *cache; ++ ++ mrt = ip6mr_get_table(net, RT6_TABLE_DFLT); ++ ++ if (!mrt) ++ return -ENOENT; ++ ++ spin_lock(&mrt_lock); ++ cache = ip6mr_cache_find(mrt, origin, group); ++ if (!cache) { ++ spin_unlock(&mrt_lock); ++ return -ENOENT; ++ } ++ ++ vif = cache->_c.mfc_parent; ++ ++ if (!VIF_EXISTS(mrt, vif)) { ++ spin_unlock(&mrt_lock); ++ return -EINVAL; ++ } ++ ++ mrt->vif_table[vif].pkt_in += pkts_in; ++ mrt->vif_table[vif].bytes_in += bytes_in; ++ cache->_c.mfc_un.res.pkt += pkts_out; ++ cache->_c.mfc_un.res.bytes += bytes_out; ++ ++ for (vifi = cache->_c.mfc_un.res.minvif; ++ vifi < cache->_c.mfc_un.res.maxvif; vifi++) { ++ if ((cache->_c.mfc_un.res.ttls[vifi] > 0) && ++ (cache->_c.mfc_un.res.ttls[vifi] < 255)) { ++ if (!VIF_EXISTS(mrt, vifi)) { ++ spin_unlock(&mrt_lock); ++ return -EINVAL; ++ } ++ mrt->vif_table[vifi].pkt_out += pkts_out; ++ mrt->vif_table[vifi].bytes_out += bytes_out; ++ } ++ } ++ ++ spin_unlock(&mrt_lock); ++ return 0; ++} ++EXPORT_SYMBOL(ip6mr_mfc_stats_update); ++/* QCA qca-mcs support - End */ ++ + /* Delete a VIF entry */ + static int mif6_delete(struct mr_table *mrt, int vifi, int notify, + struct list_head *head) +@@ -1221,6 +1454,7 @@ static int ip6mr_mfc_delete(struct mr_ta + int parent) + { + struct mfc6_cache *c; ++ struct in6_addr mc_origin, mc_group; /* QCA qca-mcs support */ + + /* The entries are added/deleted only under RTNL */ + rcu_read_lock(); +@@ -1229,6 +1463,11 @@ static int ip6mr_mfc_delete(struct mr_ta + rcu_read_unlock(); + if (!c) + return -ENOENT; ++ ++ /* QCA qca-mcs support - Start */ ++ memcpy(&mc_origin, &c->mf6c_origin, sizeof(struct in6_addr)); ++ memcpy(&mc_group, &c->mf6c_mcastgrp, sizeof(struct in6_addr)); ++ /* QCA qca-mcs support - End */ + rhltable_remove(&mrt->mfc_hash, &c->_c.mnode, ip6mr_rht_params); + list_del_rcu(&c->_c.list); + +@@ -1236,6 +1475,11 @@ static int ip6mr_mfc_delete(struct mr_ta + FIB_EVENT_ENTRY_DEL, c, mrt->id); + mr6_netlink_event(mrt, c, RTM_DELROUTE); + mr_cache_put(&c->_c); ++ /* QCA qca-mcs support - Start */ ++ /* Inform offload modules of the delete event */ ++ ip6mr_sync_entry_delete(&mc_origin, &mc_group); ++ /* QCA qca-mcs support - End */ ++ + return 0; + } + +@@ -1457,6 +1701,10 @@ static int ip6mr_mfc_add(struct net *net + call_ip6mr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_REPLACE, + c, mrt->id); + mr6_netlink_event(mrt, c, RTM_NEWROUTE); ++ /* QCA qca-mcs support - Start */ ++ /* Inform offload modules of the update event */ ++ ip6mr_sync_entry_update(mrt, c); ++ /* QCA qca-mcs support - End */ + return 0; + } + diff --git a/target/linux/qualcommax/patches-6.6/0605-1-qca-nss-cfi-support.patch b/target/linux/qualcommax/patches-6.6/0605-1-qca-nss-cfi-support.patch new file mode 100644 index 00000000000000..f6a439ba5306a6 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0605-1-qca-nss-cfi-support.patch @@ -0,0 +1,111 @@ +--- a/crypto/authenc.c ++++ b/crypto/authenc.c +@@ -415,6 +415,8 @@ static int crypto_authenc_create(struct + enc->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME) + goto err_free_inst; + ++ inst->alg.base.cra_flags |= (auth_base->cra_flags | ++ enc->base.cra_flags) & CRYPTO_ALG_NOSUPP_SG; + inst->alg.base.cra_priority = enc->base.cra_priority * 10 + + auth_base->cra_priority; + inst->alg.base.cra_blocksize = enc->base.cra_blocksize; +--- a/include/linux/crypto.h ++++ b/include/linux/crypto.h +@@ -86,6 +86,11 @@ + #define CRYPTO_NOLOAD 0x00008000 + + /* ++ * Set this flag if algorithm does not support SG list transforms ++ */ ++#define CRYPTO_ALG_NOSUPP_SG 0x0000c000 ++ ++/* + * The algorithm may allocate memory during request processing, i.e. during + * encryption, decryption, or hashing. Users can request an algorithm with this + * flag unset if they can't handle memory allocation failures. +--- a/net/ipv4/esp4.c ++++ b/net/ipv4/esp4.c +@@ -658,6 +658,7 @@ static int esp_output(struct xfrm_state + struct ip_esp_hdr *esph; + struct crypto_aead *aead; + struct esp_info esp; ++ bool nosupp_sg; + + esp.inplace = true; + +@@ -669,6 +670,11 @@ static int esp_output(struct xfrm_state + aead = x->data; + alen = crypto_aead_authsize(aead); + ++ nosupp_sg = crypto_tfm_alg_type(&aead->base) & CRYPTO_ALG_NOSUPP_SG; ++ if (nosupp_sg && skb_linearize(skb)) { ++ return -ENOMEM; ++ } ++ + esp.tfclen = 0; + if (x->tfcpad) { + struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb); +@@ -890,6 +896,7 @@ static int esp_input(struct xfrm_state * + u8 *iv; + struct scatterlist *sg; + int err = -EINVAL; ++ bool nosupp_sg; + + if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr) + ivlen)) + goto out; +@@ -897,6 +904,12 @@ static int esp_input(struct xfrm_state * + if (elen <= 0) + goto out; + ++ nosupp_sg = crypto_tfm_alg_type(&aead->base) & CRYPTO_ALG_NOSUPP_SG; ++ if (nosupp_sg && skb_linearize(skb)) { ++ err = -ENOMEM; ++ goto out; ++ } ++ + assoclen = sizeof(struct ip_esp_hdr); + seqhilen = 0; + +--- a/net/ipv6/esp6.c ++++ b/net/ipv6/esp6.c +@@ -696,6 +696,7 @@ static int esp6_output(struct xfrm_state + struct ip_esp_hdr *esph; + struct crypto_aead *aead; + struct esp_info esp; ++ bool nosupp_sg; + + esp.inplace = true; + +@@ -707,6 +708,11 @@ static int esp6_output(struct xfrm_state + aead = x->data; + alen = crypto_aead_authsize(aead); + ++ nosupp_sg = crypto_tfm_alg_type(&aead->base) & CRYPTO_ALG_NOSUPP_SG; ++ if (nosupp_sg && skb_linearize(skb)) { ++ return -ENOMEM; ++ } ++ + esp.tfclen = 0; + if (x->tfcpad) { + struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb); +@@ -934,6 +940,7 @@ static int esp6_input(struct xfrm_state + __be32 *seqhi; + u8 *iv; + struct scatterlist *sg; ++ bool nosupp_sg; + + if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr) + ivlen)) { + ret = -EINVAL; +@@ -945,6 +952,12 @@ static int esp6_input(struct xfrm_state + goto out; + } + ++ nosupp_sg = crypto_tfm_alg_type(&aead->base) & CRYPTO_ALG_NOSUPP_SG; ++ if (nosupp_sg && skb_linearize(skb)) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ + assoclen = sizeof(struct ip_esp_hdr); + seqhilen = 0; + diff --git a/target/linux/qualcommax/patches-6.6/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch b/target/linux/qualcommax/patches-6.6/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch new file mode 100644 index 00000000000000..4b9ee21f2f8545 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch @@ -0,0 +1,10 @@ +--- a/net/netfilter/nf_conntrack_ecache.c ++++ b/net/netfilter/nf_conntrack_ecache.c +@@ -266,7 +266,6 @@ void nf_conntrack_register_notifier(stru + mutex_lock(&nf_ct_ecache_mutex); + notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb, + lockdep_is_held(&nf_ct_ecache_mutex)); +- WARN_ON_ONCE(notify); + rcu_assign_pointer(net->ct.nf_conntrack_event_cb, new); + mutex_unlock(&nf_ct_ecache_mutex); + } diff --git a/target/linux/qualcommax/patches-6.6/9990-1-qca-skb_recycler-support.patch b/target/linux/qualcommax/patches-6.6/9990-1-qca-skb_recycler-support.patch new file mode 100644 index 00000000000000..886bc92fe2e26a --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/9990-1-qca-skb_recycler-support.patch @@ -0,0 +1,396 @@ +diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h +index 624d4a3..5aa8808 100644 +--- a/include/linux/cpuhotplug.h ++++ b/include/linux/cpuhotplug.h +@@ -94,6 +94,7 @@ enum cpuhp_state { + CPUHP_RADIX_DEAD, + CPUHP_PAGE_ALLOC, + CPUHP_NET_DEV_DEAD, ++ CPUHP_SKB_RECYCLER_DEAD, + CPUHP_PCI_XGENE_DEAD, + CPUHP_IOMMU_IOVA_DEAD, + CPUHP_LUSTRE_CFS_DEAD, +diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h +index 83cced8..b6ee509 100644 +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -1065,6 +1065,10 @@ struct sk_buff { + /* only useable after checking ->active_extensions != 0 */ + struct skb_ext *extensions; + #endif ++ ++#ifdef CONFIG_DEBUG_OBJECTS_SKBUFF ++ void *free_addr; ++#endif + }; + + /* if you move pkt_type around you also must adapt those constants */ +@@ -1250,7 +1254,7 @@ static inline void kfree_skb_list(struct sk_buff *segs) + kfree_skb_list_reason(segs, SKB_DROP_REASON_NOT_SPECIFIED); + } + +-#ifdef CONFIG_TRACEPOINTS ++#ifdef CONFIG_SKB_RECYCLER + void consume_skb(struct sk_buff *skb); + #else + static inline void consume_skb(struct sk_buff *skb) +@@ -1262,6 +1266,9 @@ static inline void consume_skb(struct sk_buff *skb) + void __consume_stateless_skb(struct sk_buff *skb); + void __kfree_skb(struct sk_buff *skb); + extern struct kmem_cache *skbuff_cache; ++extern void kfree_skbmem(struct sk_buff *skb); ++extern void skb_release_data(struct sk_buff *skb, enum skb_drop_reason reason, ++ bool napi_safe); + + void kfree_skb_partial(struct sk_buff *skb, bool head_stolen); + bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from, +diff --git a/net/Kconfig b/net/Kconfig +index 61eac93..e0c8bf0 100644 +--- a/net/Kconfig ++++ b/net/Kconfig +@@ -369,6 +369,27 @@ config NET_FLOW_LIMIT + with many clients some protection against DoS by a single (spoofed) + flow that greatly exceeds average workload. + ++config SKB_RECYCLER ++ bool "Generic skb recycling" ++ default y ++ help ++ SKB_RECYCLER is used to implement RX-to-RX skb recycling. ++ This config enables the recycling scheme for bridging and ++ routing workloads. It can reduce skbuff freeing or ++ reallocation overhead. ++ ++config SKB_RECYCLER_MULTI_CPU ++ bool "Cross-CPU recycling for CPU-locked workloads" ++ depends on SMP && SKB_RECYCLER ++ default n ++ ++config ALLOC_SKB_PAGE_FRAG_DISABLE ++ bool "Disable page fragment based skbuff payload allocations" ++ depends on !SKB_RECYCLER ++ default n ++ help ++ Disable page fragment based allocations for skbuff payloads. ++ + menu "Network testing" + + config NET_PKTGEN +diff --git a/net/core/Makefile b/net/core/Makefile +index 5c9fc1f..e90878c 100644 +--- a/net/core/Makefile ++++ b/net/core/Makefile +@@ -41,3 +41,4 @@ obj-$(CONFIG_NET_SOCK_MSG) += skmsg.o + obj-$(CONFIG_BPF_SYSCALL) += sock_map.o + obj-$(CONFIG_BPF_SYSCALL) += bpf_sk_storage.o + obj-$(CONFIG_OF) += of_net.o ++obj-$(CONFIG_SKB_RECYCLER) += skbuff_recycle.o +diff --git a/net/core/dev.c b/net/core/dev.c +index 85a1038..c6994ab 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -6016,10 +6016,16 @@ static int process_backlog(struct napi_struct *napi, int quota) + + napi->weight = READ_ONCE(dev_rx_weight); + while (again) { +- struct sk_buff *skb; ++ struct sk_buff *skb, *next_skb; + + while ((skb = __skb_dequeue(&sd->process_queue))) { + rcu_read_lock(); ++ ++ next_skb = skb_peek(&sd->process_queue); ++ if (likely(next_skb)) { ++ prefetch(next_skb->data); ++ } ++ + __netif_receive_skb(skb); + rcu_read_unlock(); + input_queue_head_incr(sd); +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index bcfa460..eaf8bcb 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -87,6 +87,31 @@ + + #include "dev.h" + #include "sock_destructor.h" ++#include "skbuff_recycle.h" ++ ++struct kmem_cache *skb_data_cache; ++/* ++ * For low memory profile, NSS_SKB_FIXED_SIZE_2K is enabled and ++ * CONFIG_SKB_RECYCLER is disabled. For premium and enterprise profile ++ * CONFIG_SKB_RECYCLER is enabled and NSS_SKB_FIXED_SIZE_2K is disabled. ++ * Irrespective of NSS_SKB_FIXED_SIZE_2K enabled/disabled, the ++ * CONFIG_SKB_RECYCLER and __LP64__ determines the value of SKB_DATA_CACHE_SIZE ++ */ ++#if defined(CONFIG_SKB_RECYCLER) ++/* ++ * 2688 for 64bit arch, 2624 for 32bit arch ++ */ ++#define SKB_DATA_CACHE_SIZE (SKB_DATA_ALIGN(SKB_RECYCLE_SIZE + NET_SKB_PAD) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) ++#else ++/* ++ * 2368 for 64bit arch, 2176 for 32bit arch ++ */ ++#if defined(__LP64__) ++#define SKB_DATA_CACHE_SIZE ((SKB_DATA_ALIGN(1984 + NET_SKB_PAD)) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) ++#else ++#define SKB_DATA_CACHE_SIZE ((SKB_DATA_ALIGN(1856 + NET_SKB_PAD)) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) ++#endif ++#endif + + struct kmem_cache *skbuff_cache __ro_after_init; + static struct kmem_cache *skbuff_fclone_cache __ro_after_init; +@@ -551,21 +576,20 @@ static void *kmalloc_reserve(unsigned int *size, gfp_t flags, int node, + bool *pfmemalloc) + { + bool ret_pfmemalloc = false; +- size_t obj_size; ++ unsigned int obj_size = *size; + void *obj; + + obj_size = SKB_HEAD_ALIGN(*size); +- if (obj_size <= SKB_SMALL_HEAD_CACHE_SIZE && +- !(flags & KMALLOC_NOT_NORMAL_BITS)) { +- obj = kmem_cache_alloc_node(skb_small_head_cache, +- flags | __GFP_NOMEMALLOC | __GFP_NOWARN, +- node); +- *size = SKB_SMALL_HEAD_CACHE_SIZE; ++ if (obj_size > SZ_2K && obj_size <= SKB_DATA_CACHE_SIZE) { ++ obj = kmem_cache_alloc_node(skb_data_cache, ++ flags | __GFP_NOMEMALLOC | __GFP_NOWARN, ++ node); ++ *size = SKB_DATA_CACHE_SIZE; + if (obj || !(gfp_pfmemalloc_allowed(flags))) + goto out; + /* Try again but now we are using pfmemalloc reserves */ + ret_pfmemalloc = true; +- obj = kmem_cache_alloc_node(skb_small_head_cache, flags, node); ++ obj = kmem_cache_alloc_node(skb_data_cache, flags, node); + goto out; + } + +@@ -648,10 +671,12 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, + * aligned memory blocks, unless SLUB/SLAB debug is enabled. + * Both skb->head and skb_shared_info are cache line aligned. + */ ++ size = SKB_DATA_ALIGN(size); ++ size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + data = kmalloc_reserve(&size, gfp_mask, node, &pfmemalloc); + if (unlikely(!data)) + goto nodata; +- /* kmalloc_size_roundup() might give us more room than requested. ++ /* kmalloc_reserve(size) might give us more room than requested. + * Put skb_shared_info exactly at the end of allocated zone, + * to allow max possible filling before reallocation. + */ +@@ -686,7 +711,7 @@ EXPORT_SYMBOL(__alloc_skb); + /** + * __netdev_alloc_skb - allocate an skbuff for rx on a specific device + * @dev: network device to receive on +- * @len: length to allocate ++ * @length: length to allocate + * @gfp_mask: get_free_pages mask, passed to alloc_skb + * + * Allocate a new &sk_buff and assign it a usage count of one. The +@@ -696,29 +721,53 @@ EXPORT_SYMBOL(__alloc_skb); + * + * %NULL is returned if there is no free memory. + */ +-struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int len, +- gfp_t gfp_mask) ++struct sk_buff *__netdev_alloc_skb(struct net_device *dev, ++ unsigned int length, gfp_t gfp_mask) + { +- struct page_frag_cache *nc; + struct sk_buff *skb; ++ unsigned int len = length; ++ ++#ifdef CONFIG_SKB_RECYCLER ++ skb = skb_recycler_alloc(dev, length); ++ if (likely(skb)) ++ return skb; ++ ++ len = SKB_RECYCLE_SIZE; ++ if (unlikely(length > SKB_RECYCLE_SIZE)) ++ len = length; ++ ++ skb = __alloc_skb(len + NET_SKB_PAD, gfp_mask, ++ SKB_ALLOC_RX, NUMA_NO_NODE); ++ if (!skb) ++ goto skb_fail; ++ goto skb_success; ++#else ++ struct page_frag_cache *nc; + bool pfmemalloc; ++ bool page_frag_alloc_enable = true; + void *data; + + len += NET_SKB_PAD; + ++ ++#ifdef CONFIG_ALLOC_SKB_PAGE_FRAG_DISABLE ++ page_frag_alloc_enable = false; ++#endif + /* If requested length is either too small or too big, + * we use kmalloc() for skb->head allocation. + */ + if (len <= SKB_WITH_OVERHEAD(1024) || + len > SKB_WITH_OVERHEAD(PAGE_SIZE) || +- (gfp_mask & (__GFP_DIRECT_RECLAIM | GFP_DMA))) { ++ (gfp_mask & (__GFP_DIRECT_RECLAIM | GFP_DMA)) || ++ !page_frag_alloc_enable) { + skb = __alloc_skb(len, gfp_mask, SKB_ALLOC_RX, NUMA_NO_NODE); + if (!skb) + goto skb_fail; + goto skb_success; + } + +- len = SKB_HEAD_ALIGN(len); ++ len += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); ++ len = SKB_DATA_ALIGN(len); + + if (sk_memalloc_socks()) + gfp_mask |= __GFP_MEMALLOC; +@@ -747,6 +796,7 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int len, + if (pfmemalloc) + skb->pfmemalloc = 1; + skb->head_frag = 1; ++#endif + + skb_success: + skb_reserve(skb, NET_SKB_PAD); +@@ -817,7 +867,8 @@ struct sk_buff *__napi_alloc_skb(struct napi_struct *napi, unsigned int len, + data = page_frag_alloc_1k(&nc->page_small, gfp_mask); + pfmemalloc = NAPI_SMALL_PAGE_PFMEMALLOC(nc->page_small); + } else { +- len = SKB_HEAD_ALIGN(len); ++ len += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); ++ len = SKB_DATA_ALIGN(len); + + data = page_frag_alloc(&nc->page, len, gfp_mask); + pfmemalloc = nc->page.pfmemalloc; +@@ -975,7 +1026,7 @@ static void skb_free_head(struct sk_buff *skb, bool napi_safe) + } + } + +-static void skb_release_data(struct sk_buff *skb, enum skb_drop_reason reason, ++void skb_release_data(struct sk_buff *skb, enum skb_drop_reason reason, + bool napi_safe) + { + struct skb_shared_info *shinfo = skb_shinfo(skb); +@@ -1018,7 +1069,7 @@ static void skb_release_data(struct sk_buff *skb, enum skb_drop_reason reason, + /* + * Free an skbuff by memory without cleaning the state. + */ +-static void kfree_skbmem(struct sk_buff *skb) ++void kfree_skbmem(struct sk_buff *skb) + { + struct sk_buff_fclones *fclones; + +@@ -1282,7 +1333,6 @@ void skb_tx_error(struct sk_buff *skb) + } + EXPORT_SYMBOL(skb_tx_error); + +-#ifdef CONFIG_TRACEPOINTS + /** + * consume_skb - free an skbuff + * @skb: buffer to free +@@ -1291,13 +1341,48 @@ EXPORT_SYMBOL(skb_tx_error); + * Functions identically to kfree_skb, but kfree_skb assumes that the frame + * is being dropped after a failure and notes that + */ ++#ifdef CONFIG_SKB_RECYCLER + void consume_skb(struct sk_buff *skb) + { + if (!skb_unref(skb)) + return; ++ prefetch(&skb->destructor); ++ ++ /*Tian: Not sure if we need to continue using this since ++ * since unref does the work in 5.4 ++ */ ++ ++ /* ++ if (likely(atomic_read(&skb->users) == 1)) ++ smp_rmb(); ++ else if (likely(!atomic_dec_and_test(&skb->users))) ++ return; ++ */ + ++ /* If possible we'd like to recycle any skb rather than just free it, ++ * but in order to do that we need to release any head state too. ++ * We don't want to do this later because we'll be in a pre-emption ++ * disabled state. ++ */ ++ skb_release_head_state(skb); ++ ++ /* Can we recycle this skb? If we can then it will be much faster ++ * for us to recycle this one later than to allocate a new one ++ * from scratch. ++ */ ++ if (likely(skb->head) && likely(skb_recycler_consume(skb))) ++ return; ++ ++#ifdef CONFIG_TRACEPOINTS + trace_consume_skb(skb, __builtin_return_address(0)); +- __kfree_skb(skb); ++#endif ++ /* We're not recycling so now we need to do the rest of what we would ++ * have done in __kfree_skb (above and beyond the skb_release_head_state ++ * that we already did). ++ */ ++ if (likely(skb->head)) ++ skb_release_data(skb, SKB_CONSUMED, false); ++ kfree_skbmem(skb); + } + EXPORT_SYMBOL(consume_skb); + #endif +@@ -2107,6 +2192,8 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, + if (skb_pfmemalloc(skb)) + gfp_mask |= __GFP_MEMALLOC; + ++ size = SKB_DATA_ALIGN(size); ++ size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + data = kmalloc_reserve(&size, gfp_mask, NUMA_NO_NODE, NULL); + if (!data) + goto nodata; +@@ -4854,6 +4941,10 @@ static void skb_extensions_init(void) {} + + void __init skb_init(void) + { ++ skb_data_cache = kmem_cache_create_usercopy("skb_data_cache", ++ SKB_DATA_CACHE_SIZE, ++ 0, SLAB_PANIC, 0, SKB_DATA_CACHE_SIZE, ++ NULL); + skbuff_cache = kmem_cache_create_usercopy("skbuff_head_cache", + sizeof(struct sk_buff), + 0, +@@ -4879,6 +4970,7 @@ void __init skb_init(void) + SKB_SMALL_HEAD_HEADROOM, + NULL); + skb_extensions_init(); ++ skb_recycler_init(); + } + + static int +@@ -6382,6 +6474,8 @@ static int pskb_carve_inside_header(struct sk_buff *skb, const u32 off, + if (skb_pfmemalloc(skb)) + gfp_mask |= __GFP_MEMALLOC; + ++ size = SKB_DATA_ALIGN(size); ++ size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + data = kmalloc_reserve(&size, gfp_mask, NUMA_NO_NODE, NULL); + if (!data) + return -ENOMEM; +@@ -6498,6 +6592,8 @@ static int pskb_carve_inside_nonlinear(struct sk_buff *skb, const u32 off, + if (skb_pfmemalloc(skb)) + gfp_mask |= __GFP_MEMALLOC; + ++ size = SKB_DATA_ALIGN(size); ++ size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + data = kmalloc_reserve(&size, gfp_mask, NUMA_NO_NODE, NULL); + if (!data) + return -ENOMEM; diff --git a/target/linux/qualcommax/patches-6.6/9999-revert-crypto-api-disallow-identical-driver-names.patch b/target/linux/qualcommax/patches-6.6/9999-revert-crypto-api-disallow-identical-driver-names.patch new file mode 100644 index 00000000000000..3f7f58dfee5af2 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/9999-revert-crypto-api-disallow-identical-driver-names.patch @@ -0,0 +1,10 @@ +--- a/crypto/algapi.c ++++ b/crypto/algapi.c +@@ -341,7 +341,6 @@ __crypto_register_alg(struct crypto_alg + } + + if (!strcmp(q->cra_driver_name, alg->cra_name) || +- !strcmp(q->cra_driver_name, alg->cra_driver_name) || + !strcmp(q->cra_name, alg->cra_driver_name)) + goto err; + } diff --git a/target/linux/qualcommax/patches-6.6/9999-silence-UBI-NAND-warnings.patch b/target/linux/qualcommax/patches-6.6/9999-silence-UBI-NAND-warnings.patch new file mode 100644 index 00000000000000..646e683dc8df70 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/9999-silence-UBI-NAND-warnings.patch @@ -0,0 +1,13 @@ +--- a/drivers/mtd/mtdblock.c ++++ b/drivers/mtd/mtdblock.c +@@ -261,10 +261,6 @@ static int mtdblock_open(struct mtd_blkt + return 0; + } + +- if (mtd_type_is_nand(mbd->mtd)) +- pr_warn_ratelimited("%s: MTD device '%s' is NAND, please consider using UBI block devices instead.\n", +- mbd->tr->name, mbd->mtd->name); +- + /* OK, it's not open. Create cache info for it */ + mtdblk->count = 1; + mutex_init(&mtdblk->cache_mutex); From dfb497e68ea918501db81ab66c083a5807b11275 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 24 Mar 2024 23:20:41 -0400 Subject: [PATCH 216/225] ath11k_nss: set pbuf to 'auto' Since SKB recycler was merged into main nss-wifi branch, it is not necessary to manually tinker with pbuf script. Memory is now properly managed between NSS driver allocating/deallocating SKBs. For optimal wifi performance, especially upload, it is advised to leave the script to 'auto'. Users who use sysupgrade should manually set the uci config '/etc/config/pbuf' as it will not overwrite existing configuration. --- package/kernel/mac80211/files/pbuf.uci | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/kernel/mac80211/files/pbuf.uci b/package/kernel/mac80211/files/pbuf.uci index 2b277e11f02f4d..4e01048e9bee0e 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' From c4a0ad99ea3a29228be31ceb56e3abe5f7238557 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Sun, 24 Mar 2024 23:37:32 -0400 Subject: [PATCH 217/225] cryptodev-linux: Add hooks for QCA NSS --- package/kernel/cryptodev-linux/Makefile | 11 ++- .../patches/0005-add-qca-nss.patch | 99 +++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 package/kernel/cryptodev-linux/patches/0005-add-qca-nss.patch diff --git a/package/kernel/cryptodev-linux/Makefile b/package/kernel/cryptodev-linux/Makefile index ea1bd241617b7d..6fc511133f9439 100644 --- a/package/kernel/cryptodev-linux/Makefile +++ b/package/kernel/cryptodev-linux/Makefile @@ -40,13 +40,22 @@ define KernelPackage/cryptodev/description hardware ciphers by user-space applications. endef +ifneq ($(CONFIG_PACKAGE_kmod-crypto-qce),) +EXTRA_CFLAGS+=-DQCA +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-crypto),) +EXTRA_CFLAGS+=-DQCANSS +endif + define Build/Configure endef define Build/Compile $(MAKE) -C $(PKG_BUILD_DIR) \ $(KERNEL_MAKE_FLAGS) \ - KERNEL_DIR="$(LINUX_DIR)" + KERNEL_DIR="$(LINUX_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" endef define Build/InstallDev diff --git a/package/kernel/cryptodev-linux/patches/0005-add-qca-nss.patch b/package/kernel/cryptodev-linux/patches/0005-add-qca-nss.patch new file mode 100644 index 00000000000000..4f467a18773467 --- /dev/null +++ b/package/kernel/cryptodev-linux/patches/0005-add-qca-nss.patch @@ -0,0 +1,99 @@ +--- a/ioctl.c ++++ b/ioctl.c +@@ -829,29 +829,37 @@ static inline void tfm_info_to_alg_info( + "%s", crypto_tfm_alg_driver_name(tfm)); + } + +-#ifndef CRYPTO_ALG_KERN_DRIVER_ONLY ++#if defined(QCANSS) || defined(QCA) || defined(MT7621) || defined(MT7622) || defined(LANTIQ) || defined(BCM675X) || defined(BCM49XX) || defined(MT798X) + static unsigned int is_known_accelerated(struct crypto_tfm *tfm) + { + const char *name = crypto_tfm_alg_driver_name(tfm); + + if (name == NULL) +- return 1; /* assume accelerated */ ++ return 0; + + /* look for known crypto engine names */ +- if (strstr(name, "-talitos") || +- !strncmp(name, "mv-", 3) || +- !strncmp(name, "atmel-", 6) || +- strstr(name, "geode") || +- strstr(name, "hifn") || +- strstr(name, "-ixp4xx") || +- strstr(name, "-omap") || +- strstr(name, "-picoxcell") || +- strstr(name, "-s5p") || +- strstr(name, "-ppc4xx") || +- strstr(name, "-caam") || +- strstr(name, "-n2")) ++#if defined(QCANSS) ++ if (!strncmp(name, "nss-", 4)) + return 1; +- ++#elif defined(QCA) ++ if (!strncmp(name, "qcrypto", 7)) ++ return 1; ++#elif defined(MT7621) ++ if (strstr(name, "eip93")) ++ return 1; ++#elif defined(MT7622) ++ if (strstr(name, "mtk")) ++ return 1; ++#elif defined(MT798X) ++ if (strstr(name, "safexcel-")) ++ return 1; ++#elif defined(LANTIQ) ++ if (strstr(name, "ltq-crypto")) ++ return 1; ++#elif defined(BCM675X) || defined(BCM49XX) ++ if (strstr(name, "-iproc")) ++ return 1; ++#endif + return 0; + } + #endif +@@ -876,22 +884,22 @@ static int get_session_info(struct fcryp + else + tfm = crypto_aead_tfm(ses_ptr->cdata.async.as); + tfm_info_to_alg_info(&siop->cipher_info, tfm); +-#ifdef CRYPTO_ALG_KERN_DRIVER_ONLY +- if (tfm->__crt_alg->cra_flags & CRYPTO_ALG_KERN_DRIVER_ONLY) ++#if defined(QCANSS) || defined(QCA) || defined(MT7621) || defined(MT7622) || defined(LANTIQ) || defined(BCM675X) || defined(BCM49XX) || defined(MT798X) ++ if (is_known_accelerated(tfm)) + siop->flags |= SIOP_FLAG_KERNEL_DRIVER_ONLY; + #else +- if (is_known_accelerated(tfm)) ++ if (tfm->__crt_alg->cra_flags & CRYPTO_ALG_KERN_DRIVER_ONLY) + siop->flags |= SIOP_FLAG_KERNEL_DRIVER_ONLY; + #endif + } + if (ses_ptr->hdata.init) { + tfm = crypto_ahash_tfm(ses_ptr->hdata.async.s); + tfm_info_to_alg_info(&siop->hash_info, tfm); +-#ifdef CRYPTO_ALG_KERN_DRIVER_ONLY +- if (tfm->__crt_alg->cra_flags & CRYPTO_ALG_KERN_DRIVER_ONLY) ++#if defined(QCANSS) || defined(QCA) || defined(MT7621) || defined(MT7622) || defined(LANTIQ) || defined(BCM675X) || defined(BCM49XX) || defined(MT798X) ++ if (is_known_accelerated(tfm)) + siop->flags |= SIOP_FLAG_KERNEL_DRIVER_ONLY; + #else +- if (is_known_accelerated(tfm)) ++ if (tfm->__crt_alg->cra_flags & CRYPTO_ALG_KERN_DRIVER_ONLY) + siop->flags |= SIOP_FLAG_KERNEL_DRIVER_ONLY; + #endif + } +--- a/main.c ++++ b/main.c +@@ -168,6 +168,12 @@ __crypto_run_zc(struct csession *ses_ptr + struct crypt_op *cop = &kcop->cop; + int ret = 0; + ++#if defined(QCANSS) ++//openssl bug!!! ++ if (unlikely(cop->src != cop->dst)) { ++ return __crypto_run_std(ses_ptr, cop); ++ } ++#endif + ret = get_userbuf(ses_ptr, cop->src, cop->len, cop->dst, cop->len, + kcop->task, kcop->mm, &src_sg, &dst_sg); + if (unlikely(ret)) { From 600f76174b15e2a90d14b54f4c3a5d1d7f0b2993 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 25 Mar 2024 00:07:45 -0400 Subject: [PATCH 218/225] feeds: NSS: point to 6.x branch This will now be the default NSS branch, and will cover both kernel 6.1 and 6.6 related changes going forward. qualcommax: NSS: fix up 'nss_region' --- feeds.conf.default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feeds.conf.default b/feeds.conf.default index 4527c3215a827e..68c55d271c0819 100644 --- a/feeds.conf.default +++ b/feeds.conf.default @@ -2,7 +2,7 @@ src-git packages https://git.openwrt.org/feed/packages.git src-git luci https://git.openwrt.org/project/luci.git src-git routing https://git.openwrt.org/feed/routing.git src-git telephony https://git.openwrt.org/feed/telephony.git -src-git nss_packages https://github.com/qosmio/nss-packages.git;NSS-12.4-K6.1 +src-git nss_packages https://github.com/qosmio/nss-packages.git;NSS-12.4-K6.x src-git sqm_scripts_nss https://github.com/qosmio/sqm-scripts-nss.git #src-git video https://github.com/openwrt/video.git #src-git targets https://github.com/openwrt/targets.git From 2be68497cffcaa522b8b754c251b018aff84e87a Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 25 Mar 2024 13:31:04 -0400 Subject: [PATCH 219/225] ath11k_nss: refresh and fixup patches, increment release version --- package/kernel/mac80211/Makefile | 8 +- ...91-ath11k-add-mgmt-and-data-ack-rssi.patch | 2 +- .../199-003-ath11k-add-nss-support.patch | 4 +- ...-ath11k-Add-support-for-dynamic-vlan.patch | 2 +- ...pport-for-WDS-offload-in-NSS-offload.patch | 28 ++--- ...-dynamic-VLAN-support-in-NSS-offload.patch | 36 +++--- ...ow-fast-rx-by-bypassing-stats-update.patch | 2 +- .../nss/ath11k/244-ath11k-dp-tx-perf.patch | 4 +- .../patches/nss/ath11k/270-iphone-issue.patch | 2 +- .../300-ath11k-nss-mesh-offload-support.patch | 8 +- ...lookup-failure-in-mgmt-tx-completion.patch | 2 +- ...30-ath11k-sync-wds_ast_entry-updates.patch | 4 +- ...TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch | 2 +- ...rt-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch | 2 +- ...-fix-clear-peer-keys-during-disassoc.patch | 4 +- ...ix-mutex-dead-lock-and-q6-dump-crash.patch | 4 +- ...agement-frames-to-firmware-before-wa.patch | 7 +- ...oid-memset-of-ppdu-info-for-next-skb.patch | 6 +- ...a_map_single-to-virt_to_phys-in-rx-r.patch | 4 +- ...11k-remove-invalid-peer-create-logic.patch | 4 +- ...th11k-rename-ath11k_start_vdev_delay.patch | 6 +- ...ation-of-ath11k_mac_start_vdev_delay.patch | 8 +- ...ailure-due-to-unexpected-peer-delete.patch | 14 +-- ...k-make-debugfs-sta-htt-stats-modular.patch | 6 +- ...11k-Disable-rx_header-tlv-for-2K-SKB.patch | 52 ++++----- ...d-ampdu-id-in-802.11-radiotap-header.patch | 6 +- ...999-336-0001-ath11k-idr-optimization.patch | 10 +- .../999-336-0002-ath11k-Use-idr_replace.patch | 22 ++-- ...k-skb_headroom-before-using-skb_push.patch | 6 +- .../subsys/007-fix_compilation_issue.patch | 10 +- ...-when-using-encapsulation-offloading.patch | 2 +- .../199-001-mac80211-add-nss-support.patch | 26 ++--- ...t-callback-when-hwencap-enable-in-st.patch | 2 +- ...03-mac80211-ath11k-fw-dynamic-muedca.patch | 4 +- ...-ath11k-Add-support-for-dynamic-vlan.patch | 4 +- ...07-mac80211-add-nss-redirect-support.patch | 6 +- ...N-iftype-support-on-NSS-offload-case.patch | 6 +- ...-dynamic-VLAN-support-on-NSS-offload.patch | 6 +- .../nss/subsys/245-compilation_fix.patch | 106 +++--------------- .../300-ath11k-nss-mesh-offload-support.patch | 34 +++--- ...TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch | 4 +- ...-0005-mac80211-simple-tx-for-AP-mode.patch | 4 +- ...mac80211-fix-unconditional-sta-usage.patch | 4 +- ...unused-RX_FLAGS-from-mac80211_rx_fla.patch | 4 +- ...ncapsulation-of-EAPOL-frames-if-OFFL.patch | 24 ++-- ...fix-RCU-stall-in-mesh-fast-xmit-path.patch | 2 +- ...id-last_rate-for-rx_bitrate-from-cpu.patch | 12 +- ...se-HW-checksum-offload-only-for-ethm.patch | 4 +- ...1-Add-mac-hw-flag-to-avoid-queue-skb.patch | 24 ++-- ...x-memory-corruption-during-mesh-beac.patch | 2 +- 50 files changed, 237 insertions(+), 318 deletions(-) diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 6b36819f75cc4d..cf9c743eb3d198 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 PKG_VERSION:=6.6.15 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_LICENSE:=GPL-2.0-only PKG_LICENSE_FILES:=COPYING @@ -433,9 +433,9 @@ 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 + $(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 diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 22cdb4dccb4d5d..466dacd1006768 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -9579,6 +9579,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); diff --git a/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch b/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch index 2234cb6bc4cc1d..e30b5d761d3378 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch @@ -747,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, -@@ -9529,7 +9637,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); @@ -757,7 +757,7 @@ Signed-off-by: Sriram R } ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; -@@ -9644,6 +9753,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; diff --git a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Add-support-for-dynamic-vlan.patch b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Add-support-for-dynamic-vlan.patch index 54a6d1528422db..a765d1a292c60c 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Add-support-for-dynamic-vlan.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Add-support-for-dynamic-vlan.patch @@ -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 -@@ -9770,6 +9770,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/nss/ath11k/235-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 index 729ee80199b9a2..1730beea85dfc0 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/235-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 @@ -43,7 +43,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 -@@ -4744,6 +4744,11 @@ static void ath11k_sta_rc_update_wk(stru +@@ -4739,6 +4739,11 @@ static void ath11k_sta_rc_update_wk(stru arvif = arsta->arvif; ar = arvif->ar; @@ -55,7 +55,7 @@ Signed-off-by: Sathishkumar Muruganandam if (WARN_ON(ath11k_mac_vif_chan(arvif->vif, &def))) return; -@@ -4915,17 +4920,28 @@ err_rc_bw_changed: +@@ -4910,17 +4915,28 @@ err_rc_bw_changed: static void ath11k_sta_set_4addr_wk(struct work_struct *wk) { struct ath11k *ar; @@ -86,7 +86,7 @@ Signed-off-by: Sathishkumar Muruganandam "setting USE_4ADDR for peer %pM\n", sta->addr); ret = ath11k_wmi_set_peer_param(ar, sta->addr, -@@ -4933,8 +4949,93 @@ static void ath11k_sta_set_4addr_wk(stru +@@ -4928,8 +4944,93 @@ static void ath11k_sta_set_4addr_wk(stru WMI_PEER_USE_4ADDR, 1); if (ret) @@ -181,7 +181,7 @@ Signed-off-by: Sathishkumar Muruganandam } static int ath11k_mac_inc_num_stations(struct ath11k_vif *arvif, -@@ -5264,9 +5365,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; @@ -214,7 +214,7 @@ Signed-off-by: Sathishkumar Muruganandam ieee80211_queue_work(ar->hw, &arsta->set_4addr_wk); arsta->use_4addr_set = true; } -@@ -6646,6 +6770,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; @@ -224,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 && -@@ -6866,7 +6993,8 @@ static int ath11k_mac_op_add_interface(s +@@ -6861,7 +6988,8 @@ static int ath11k_mac_op_add_interface(s goto err; } @@ -234,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; -@@ -6886,6 +7014,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); @@ -263,7 +263,7 @@ Signed-off-by: Sathishkumar Muruganandam INIT_DELAYED_WORK(&arvif->connection_loss_work, ath11k_mac_vif_sta_connection_loss_work); -@@ -6915,6 +7065,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; @@ -271,7 +271,7 @@ Signed-off-by: Sathishkumar Muruganandam break; case NL80211_IFTYPE_MONITOR: arvif->vdev_type = WMI_VDEV_TYPE_MONITOR; -@@ -7137,13 +7288,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; @@ -304,7 +304,7 @@ Signed-off-by: Sathishkumar Muruganandam ath11k_dbg(ab, ATH11K_DBG_MAC, "remove interface (vdev %d)\n", arvif->vdev_id); -@@ -7160,6 +7328,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); @@ -319,7 +319,7 @@ Signed-off-by: Sathishkumar Muruganandam } ret = ath11k_mac_vdev_delete(ar, arvif); -@@ -7203,8 +7379,7 @@ err_vdev_del: +@@ -7198,8 +7374,7 @@ err_vdev_del: ath11k_debugfs_remove_interface(arvif); @@ -329,7 +329,7 @@ Signed-off-by: Sathishkumar Muruganandam mutex_unlock(&ar->conf_mutex); } -@@ -7264,16 +7439,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; @@ -349,7 +349,7 @@ Signed-off-by: Sathishkumar Muruganandam break; case IEEE80211_AMPDU_TX_START: case IEEE80211_AMPDU_TX_STOP_CONT: -@@ -8796,6 +8972,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; @@ -357,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); -@@ -8852,7 +9029,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); diff --git a/package/kernel/mac80211/patches/nss/ath11k/236-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 index 80b8a5fc67d7ea..750fd2b239d548 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/236-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 @@ -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 -@@ -351,6 +351,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; -@@ -723,6 +727,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; -@@ -4172,6 +4203,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; -@@ -4261,15 +4295,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; -@@ -4287,17 +4346,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. */ -@@ -4342,6 +4422,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); -@@ -4364,6 +4512,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) { -@@ -4373,18 +4542,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); } @@ -354,7 +354,7 @@ Signed-off-by: Sathishkumar Muruganandam switch (key->cipher) { case WLAN_CIPHER_SUITE_TKIP: -@@ -5191,6 +5365,33 @@ static u32 ath11k_mac_ieee80211_sta_bw_t +@@ -5186,6 +5360,33 @@ static u32 ath11k_mac_ieee80211_sta_bw_t return bw; } @@ -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, -@@ -5300,6 +5501,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) { -@@ -7018,7 +7247,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; -@@ -7031,6 +7260,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; } -@@ -7055,6 +7285,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: -@@ -7095,7 +7339,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++; -@@ -7254,7 +7498,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 } } -@@ -7265,6 +7509,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); -@@ -7362,6 +7608,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, -@@ -9960,8 +10207,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; diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 61077309338ffb..d25e43ec0b3998 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -328,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 -@@ -5532,6 +5532,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/nss/ath11k/244-ath11k-dp-tx-perf.patch b/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch index 1c9a6ebd1d41ac..c4042611d3d9ea 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch @@ -430,7 +430,7 @@ Signed-off-by: P Praneesh --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6669,12 +6669,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); @@ -454,7 +454,7 @@ Signed-off-by: P Praneesh ieee80211_free_txskb(ar->hw, skb); return; } -@@ -7622,7 +7632,7 @@ err_vdev_del: +@@ -7617,7 +7627,7 @@ err_vdev_del: idr_for_each(&ar->txmgmt_idr, ath11k_mac_vif_txmgmt_idr_remove, vif); diff --git a/package/kernel/mac80211/patches/nss/ath11k/270-iphone-issue.patch b/package/kernel/mac80211/patches/nss/ath11k/270-iphone-issue.patch index 4260d0e5337451..717c11bdfe39e1 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/270-iphone-issue.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/270-iphone-issue.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6267,6 +6267,8 @@ static int ath11k_mac_copy_he_cap(struct +@@ -6262,6 +6262,8 @@ static int ath11k_mac_copy_he_cap(struct memcpy(he_cap_elem->phy_cap_info, band_cap->he_cap_phy_info, sizeof(he_cap_elem->phy_cap_info)); 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 index b31809f689548b..30848b8f6164ac 100644 --- 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 @@ -1238,7 +1238,7 @@ Signed-off-by: Vasanthakumar Thiagarajan --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -3474,6 +3474,18 @@ static void ath11k_mac_op_nss_bss_info_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); } @@ -1257,7 +1257,7 @@ Signed-off-by: Vasanthakumar Thiagarajan mutex_unlock(&ar->conf_mutex); } -@@ -9714,6 +9726,28 @@ err_fallback: +@@ -9709,6 +9721,28 @@ err_fallback: return 0; } @@ -1286,7 +1286,7 @@ Signed-off-by: Vasanthakumar Thiagarajan static const struct ieee80211_ops ath11k_ops = { .tx = ath11k_mac_op_tx, .wake_tx_queue = ieee80211_handle_wake_tx_queue, -@@ -9771,6 +9805,9 @@ static const struct ieee80211_ops ath11k +@@ -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, @@ -1296,7 +1296,7 @@ Signed-off-by: Vasanthakumar Thiagarajan }; static void ath11k_mac_update_ch_list(struct ath11k *ar, -@@ -10231,6 +10268,8 @@ static int __ath11k_mac_register(struct +@@ -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); 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 index cb4fba0a2ffdcd..6edfd5f9208e97 100644 --- 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 @@ -23,7 +23,7 @@ Signed-off-by: Rameshkumar Sundaram --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -7643,8 +7643,10 @@ err_vdev_del: +@@ -7638,8 +7638,10 @@ err_vdev_del: kfree(arvif->vlan_keyid_map); ath11k_peer_cleanup(ar, arvif->vdev_id); diff --git a/package/kernel/mac80211/patches/nss/ath11k/330-ath11k-sync-wds_ast_entry-updates.patch b/package/kernel/mac80211/patches/nss/ath11k/330-ath11k-sync-wds_ast_entry-updates.patch index 361c9064148acd..01ccc6003fc0cf 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -2212,6 +2212,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); -@@ -2225,6 +2226,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); diff --git a/package/kernel/mac80211/patches/nss/ath11k/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 index 3c3e436c75ce41..8e018e619f12f8 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 @@ -58,7 +58,7 @@ Signed-off-by: Venkateswara Naralasetty 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 -@@ -10154,6 +10154,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/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 index dbd8dd904c022d..9a3c95a9df3c40 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -1838,6 +1838,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/nss/ath11k/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 index 15a8afde61ef4f..4c7fefbba155d7 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/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 -@@ -4899,12 +4899,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; } -@@ -5495,6 +5489,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/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 index 1f66f72a4a4851..ceeb15c8cbea65 100644 --- 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 @@ -36,7 +36,7 @@ Signed-off-by: Rajat Soni --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -8001,7 +8001,9 @@ static int ath11k_mac_op_start(struct ie +@@ -6786,7 +6786,9 @@ static int ath11k_mac_op_start(struct ie break; case ATH11K_STATE_RESTARTING: ar->state = ATH11K_STATE_RESTARTED; @@ -48,7 +48,7 @@ Signed-off-by: Rajat Soni case ATH11K_STATE_WEDGED: --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c -@@ -2960,6 +2960,8 @@ static int ath11k_qmi_assign_target_mem_ +@@ -2061,6 +2061,8 @@ static int ath11k_qmi_assign_target_mem_ if (!ab->qmi.target_mem[idx].iaddr) return -EIO; 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 index 7d413afec97b3d..90982924fe29f7 100644 --- 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 @@ -25,11 +25,9 @@ Signed-off-by: Hari Chandrakanthan drivers/net/wireless/ath/ath11k/mac.c | 2 ++ 1 file changed, 2 insertions(+) -diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c -index 28c9908ef816..dbdb7aa5c498 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -10266,6 +10266,8 @@ static int ath11k_mac_flush_tx_complete(struct ath11k *ar) +@@ -8464,6 +8464,8 @@ static int ath11k_mac_flush_tx_complete( ret = -ETIMEDOUT; } @@ -38,6 +36,3 @@ index 28c9908ef816..dbdb7aa5c498 100644 time_left = wait_event_timeout(ar->txmgmt_empty_waitq, (atomic_read(&ar->num_pending_mgmt_tx) == 0), ATH11K_FLUSH_TIMEOUT); --- -2.7.4 - diff --git a/package/kernel/mac80211/patches/nss/ath11k/457-wifi-ath11k-Avoid-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 index c23b6cb3c858b4..21a92296da38a1 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/457-wifi-ath11k-Avoid-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 -@@ -6090,7 +6090,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))) { -@@ -6108,7 +6110,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,7 +67,7 @@ Signed-off-by: Yuvasree Sivasankaran ppdu_info->peer_id = HAL_INVALID_PEERID; hal_status = ath11k_hal_rx_parse_mon_status(ab, ppdu_info, skb); -@@ -6136,6 +6137,7 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -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); 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 index fe767b6a33de2a..06cee635f3e79b 100644 --- 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 @@ -40,7 +40,7 @@ Signed-off-by: Balamurugan Selvarajan --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -427,9 +427,9 @@ int ath11k_dp_rxbufs_replenish(struct at +@@ -392,9 +392,9 @@ int ath11k_dp_rxbufs_replenish(struct at skb->data); } @@ -53,7 +53,7 @@ Signed-off-by: Balamurugan Selvarajan if (dma_mapping_error(ab->dev, paddr)) goto fail_free_skb; -@@ -465,8 +465,8 @@ fail_idr_remove: +@@ -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: 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 index b471fb326a5b48..4d8f9f28e3a1e3 100644 --- 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 @@ -26,7 +26,7 @@ Acked-by: Jeff Johnson --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -8221,7 +8221,6 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -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; @@ -34,7 +34,7 @@ Acked-by: Jeff Johnson mutex_lock(&ar->conf_mutex); -@@ -8244,21 +8243,6 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -8241,21 +8240,6 @@ ath11k_mac_op_assign_vif_chanctx(struct goto out; } 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 index 2fb2cdfd429b11..7d04e371edd5fa 100644 --- 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 @@ -19,7 +19,7 @@ Acked-by: Jeff Johnson --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -261,8 +261,8 @@ static const u32 ath11k_smps_map[] = { +@@ -256,8 +256,8 @@ static const u32 ath11k_smps_map[] = { [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE, }; @@ -30,7 +30,7 @@ Acked-by: Jeff Johnson enum nl80211_he_ru_alloc ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc(u16 ru_phy) { -@@ -5319,7 +5319,7 @@ static int ath11k_mac_station_add(struct +@@ -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) { @@ -39,7 +39,7 @@ Acked-by: Jeff Johnson if (ret) { ath11k_warn(ab, "failed to delay vdev start: %d\n", ret); goto free_tx_stats; -@@ -8164,8 +8164,8 @@ unlock: +@@ -8161,8 +8161,8 @@ unlock: mutex_unlock(&ar->conf_mutex); } 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 index 4d83d0f0ed9029..f928d851a678d7 100644 --- 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 @@ -18,7 +18,7 @@ Acked-by: Jeff Johnson --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -261,9 +261,6 @@ static const u32 ath11k_smps_map[] = { +@@ -256,9 +256,6 @@ static const u32 ath11k_smps_map[] = { [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE, }; @@ -28,7 +28,7 @@ Acked-by: Jeff Johnson enum nl80211_he_ru_alloc ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc(u16 ru_phy) { enum nl80211_he_ru_alloc ret; -@@ -5249,100 +5246,6 @@ static void ath11k_mac_dec_num_stations( +@@ -5244,100 +5241,6 @@ static void ath11k_mac_dec_num_stations( ar->num_stations--; } @@ -129,7 +129,7 @@ Acked-by: Jeff Johnson static u32 ath11k_mac_ieee80211_sta_bw_to_wmi(struct ath11k *ar, struct ieee80211_sta *sta) { -@@ -5398,187 +5301,6 @@ static int ath11k_mac_cfg_dyn_vlan(struc +@@ -5393,187 +5296,6 @@ static int ath11k_mac_cfg_dyn_vlan(struc return ret; } @@ -317,7 +317,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) -@@ -9739,6 +9461,281 @@ ath11k_mac_op_config_mesh_offload_path(s +@@ -9738,6 +9460,281 @@ ath11k_mac_op_config_mesh_offload_path(s } #endif 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 index d1b462519c91e8..010825fd16656e 100644 --- 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 @@ -52,7 +52,7 @@ Acked-by: Jeff Johnson --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -7933,6 +7933,30 @@ static int ath11k_mac_start_vdev_delay(s +@@ -7930,6 +7930,30 @@ static int ath11k_mac_start_vdev_delay(s return 0; } @@ -83,7 +83,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -@@ -7977,15 +8001,17 @@ ath11k_mac_op_assign_vif_chanctx(struct +@@ -7974,15 +7998,17 @@ ath11k_mac_op_assign_vif_chanctx(struct goto out; } @@ -109,7 +109,7 @@ Acked-by: Jeff Johnson if (arvif->vdev_type != WMI_VDEV_TYPE_MONITOR && test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags)) { -@@ -8025,8 +8051,6 @@ ath11k_mac_op_unassign_vif_chanctx(struc +@@ -8022,8 +8048,6 @@ ath11k_mac_op_unassign_vif_chanctx(struc "chanctx unassign ptr %p vdev_id %i\n", ctx, arvif->vdev_id); @@ -118,7 +118,7 @@ Acked-by: Jeff Johnson if (ab->hw_params.vdev_start_delay && arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { spin_lock_bh(&ab->base_lock); -@@ -8050,24 +8074,13 @@ ath11k_mac_op_unassign_vif_chanctx(struc +@@ -8047,24 +8071,13 @@ ath11k_mac_op_unassign_vif_chanctx(struc return; } @@ -149,7 +149,7 @@ Acked-by: Jeff Johnson } if (ab->hw_params.vdev_start_delay && -@@ -9555,6 +9568,46 @@ exit: +@@ -9554,6 +9567,46 @@ exit: return ret; } @@ -196,7 +196,7 @@ Acked-by: Jeff Johnson static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, -@@ -9590,31 +9643,15 @@ static int ath11k_mac_op_sta_state(struc +@@ -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)) { @@ -233,7 +233,7 @@ Acked-by: Jeff Johnson 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); -@@ -9625,12 +9662,6 @@ static int ath11k_mac_op_sta_state(struc +@@ -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); 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 index 2362820dc9e838..4276e64cc30364 100644 --- 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 @@ -153,7 +153,7 @@ #include "hw.h" #include "peer.h" #include "mac.h" -@@ -551,7 +553,9 @@ static void ath11k_dp_tx_cache_peer_stat +@@ -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; @@ -163,7 +163,7 @@ enum hal_tx_rate_stats_pkt_type pkt_type; enum hal_tx_rate_stats_sgi sgi; enum hal_tx_rate_stats_bw bw; -@@ -640,8 +644,10 @@ void ath11k_dp_tx_update_txcompl(struct +@@ -639,8 +643,10 @@ void ath11k_dp_tx_update_txcompl(struct ath11k_mac_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones); } @@ -176,7 +176,7 @@ spin_unlock_bh(&ab->base_lock); --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -9812,7 +9812,7 @@ static const struct ieee80211_ops ath11k +@@ -9811,7 +9811,7 @@ static const struct ieee80211_ops ath11k .set_wakeup = ath11k_wow_op_set_wakeup, #endif diff --git a/package/kernel/mac80211/patches/nss/ath11k/999-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 index 85562dc463a211..322698f0ea8d84 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/999-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 @@ -49,7 +49,7 @@ Signed-off-by: Ramya Gnanasekar * |-------------------------------------------------------------------| * | rsvd2 | ring_buffer_size | * |-------------------------------------------------------------------| -@@ -686,6 +691,14 @@ enum htt_stats_internal_ppdu_frametype { +@@ -686,6 +687,14 @@ enum htt_stats_internal_ppdu_frametype { * |-------------------------------------------------------------------| * | tlv_filter_in_flags | * |-------------------------------------------------------------------| @@ -64,7 +64,7 @@ Signed-off-by: Ramya Gnanasekar * Where: * PS = pkt_swap * SS = status_swap -@@ -699,7 +712,10 @@ enum htt_stats_internal_ppdu_frametype { +@@ -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 @@ -76,7 +76,7 @@ Signed-off-by: Ramya Gnanasekar * dword1 - b'0:16 - ring_buffer_size: size of buffers referenced by rx ring, * in byte units. * Valid only for HW_TO_SW_RING and SW_TO_HW_RING -@@ -728,6 +744,42 @@ enum htt_stats_internal_ppdu_frametype { +@@ -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 @@ -119,7 +119,7 @@ Signed-off-by: Ramya Gnanasekar */ #define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) -@@ -735,8 +787,16 @@ enum htt_stats_internal_ppdu_frametype { +@@ -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) @@ -136,7 +136,7 @@ Signed-off-by: Ramya Gnanasekar enum htt_rx_filter_tlv_flags { HTT_RX_FILTER_TLV_FLAGS_MPDU_START = BIT(0), -@@ -1040,6 +1100,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) @@ -151,7 +151,7 @@ Signed-off-by: Ramya Gnanasekar struct htt_rx_ring_selection_cfg_cmd { u32 info0; u32 info1; -@@ -1048,6 +1116,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; @@ -162,7 +162,7 @@ Signed-off-by: Ramya Gnanasekar } __packed; struct htt_rx_ring_tlv_filter { -@@ -1056,6 +1128,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 */ @@ -228,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); -@@ -2387,6 +2422,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; } @@ -278,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, -@@ -2400,7 +2478,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; @@ -288,7 +288,7 @@ Signed-off-by: Ramya Gnanasekar /* copy SA & DA and pull decapped header */ hdr = (struct ieee80211_hdr *)msdu->data; -@@ -2409,7 +2488,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)); @@ -297,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 */ -@@ -2439,16 +2518,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); @@ -326,7 +326,7 @@ Signed-off-by: Ramya Gnanasekar memcpy(skb_push(msdu, IEEE80211_QOS_CTL_LEN), &qos_ctl, IEEE80211_QOS_CTL_LEN); -@@ -2564,6 +2650,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; @@ -347,7 +347,7 @@ Signed-off-by: Ramya Gnanasekar rfc1042 = ath11k_dp_rx_h_find_rfc1042(ar, msdu, enctype); if (WARN_ON_ONCE(!rfc1042)) -@@ -2592,6 +2692,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); @@ -355,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 */ -@@ -2610,6 +2711,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; @@ -363,7 +363,7 @@ Signed-off-by: Ramya Gnanasekar /* Delivered decapped frame: * [amsdu header] <-- replaced with 802.11 hdr -@@ -2623,6 +2725,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); @@ -375,7 +375,7 @@ Signed-off-by: Ramya Gnanasekar hdr = (struct ieee80211_hdr *)first_hdr; hdr_len = ieee80211_hdrlen(hdr->frame_control); -@@ -3097,6 +3204,20 @@ static int ath11k_dp_rx_process_msdu(str +@@ -3098,6 +3205,20 @@ static int ath11k_dp_rx_process_msdu(str goto free_out; } @@ -396,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); -@@ -3109,8 +3230,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); @@ -408,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; -@@ -4069,6 +4191,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); @@ -416,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; -@@ -4349,8 +4472,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) { @@ -426,7 +426,7 @@ Signed-off-by: Ramya Gnanasekar u8 *ehdr; u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; -@@ -4580,8 +4703,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); @@ -438,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); -@@ -5206,6 +5330,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); } @@ -486,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; -@@ -5299,6 +5464,12 @@ config_refill_ring: +@@ -5300,6 +5465,12 @@ config_refill_ring: } } @@ -501,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 -@@ -1264,6 +1264,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)); @@ -510,7 +510,7 @@ Signed-off-by: Ramya Gnanasekar cmd->info1 = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE, rx_buf_size); -@@ -1273,6 +1275,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; @@ -537,7 +537,7 @@ Signed-off-by: Ramya Gnanasekar ret = ath11k_htc_send(&ab->htc, ab->dp.eid, skb); if (ret) goto err_free; -@@ -1351,6 +1373,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; @@ -933,7 +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 -@@ -6455,6 +6455,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); } 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 index 1f554ae95ccc69..12a035bf4e5790 100644 --- 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 @@ -25,7 +25,7 @@ Signed-off-by: P Praneesh --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -5994,6 +5994,7 @@ static void ath11k_update_radiotap(struc +@@ -5995,6 +5995,7 @@ static void ath11k_update_radiotap(struc { struct ieee80211_supported_band *sband; u8 *ptr = NULL; @@ -33,7 +33,7 @@ Signed-off-by: P Praneesh rxs->flag |= RX_FLAG_MACTIME_START; rxs->signal = ppduinfo->rssi_comb + ATH11K_DEFAULT_NOISE_FLOOR; -@@ -6001,6 +6002,11 @@ static void ath11k_update_radiotap(struc +@@ -6002,6 +6003,11 @@ static void ath11k_update_radiotap(struc if (ppduinfo->nss) rxs->nss = ppduinfo->nss; @@ -128,7 +128,7 @@ Signed-off-by: P Praneesh struct hal_rx_rxpcu_classification_overview { --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h -@@ -306,6 +306,7 @@ struct ath11k_hw_ops { +@@ -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); 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 index 499f720caba8cb..ef01c639a266b4 100644 --- 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 @@ -28,7 +28,7 @@ Signed-off-by: Tamizh Chelvam } --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -3336,18 +3336,16 @@ try_again: +@@ -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); @@ -50,7 +50,7 @@ Signed-off-by: Tamizh Chelvam dma_unmap_single(ab->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu), DMA_FROM_DEVICE); -@@ -4574,17 +4572,14 @@ ath11k_dp_process_rx_err_buf(struct ath1 +@@ -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); @@ -70,7 +70,7 @@ Signed-off-by: Tamizh Chelvam rxcb = ATH11K_SKB_RXCB(msdu); dma_unmap_single(ar->ab->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu), -@@ -5005,18 +5000,16 @@ int ath11k_dp_rx_process_wbm_err(struct +@@ -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); @@ -92,7 +92,7 @@ Signed-off-by: Tamizh Chelvam dma_unmap_single(ab->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu), DMA_FROM_DEVICE); -@@ -5131,16 +5124,14 @@ int ath11k_dp_process_rxdma_err(struct a +@@ -5209,16 +5202,14 @@ int ath11k_dp_process_rxdma_err(struct a msdu_cookies[i]); spin_lock_bh(&rx_ring->idr_lock); @@ -111,7 +111,7 @@ Signed-off-by: Tamizh Chelvam rxcb = ATH11K_SKB_RXCB(skb); dma_unmap_single(ab->dev, rxcb->paddr, -@@ -6399,16 +6390,14 @@ ath11k_dp_rx_full_mon_mpdu_pop(struct at +@@ -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); 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 index c5134fca93a867..974de141070d63 100644 --- 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 @@ -114,7 +114,7 @@ Signed-off-by: Tamizh Chelvam return 0; } -@@ -3346,11 +3365,14 @@ int ath11k_dp_process_rx(struct ath11k_b +@@ -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; @@ -130,7 +130,7 @@ Signed-off-by: Tamizh Chelvam srng = &ab->hal.srng_list[dp->reo_dst_ring[ring_id].ring_id]; -@@ -3385,8 +3407,15 @@ try_again: +@@ -3384,8 +3406,15 @@ try_again: ar = ab->pdevs[mac_id].ar; rx_ring = &ar->dp.rx_refill_buf_ring; @@ -147,7 +147,7 @@ Signed-off-by: Tamizh Chelvam spin_unlock_bh(&rx_ring->idr_lock); if (unlikely(!msdu)) { ath11k_warn(ab, "frame rx with invalid buf_id %d\n", -@@ -3464,9 +3493,12 @@ try_again: +@@ -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], @@ -161,7 +161,7 @@ Signed-off-by: Tamizh Chelvam return total_msdu_reaped; } -@@ -4831,7 +4864,7 @@ exit: +@@ -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], @@ -170,7 +170,7 @@ Signed-off-by: Tamizh Chelvam } return tot_n_bufs_reaped; -@@ -5047,14 +5080,17 @@ int ath11k_dp_rx_process_wbm_err(struct +@@ -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; @@ -189,7 +189,7 @@ Signed-off-by: Tamizh Chelvam srng = &ab->hal.srng_list[dp->rx_rel_ring.ring_id]; -@@ -5077,9 +5112,15 @@ int ath11k_dp_rx_process_wbm_err(struct +@@ -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; @@ -206,7 +206,7 @@ Signed-off-by: Tamizh Chelvam spin_unlock_bh(&rx_ring->idr_lock); if (!msdu) { ath11k_warn(ab, "frame rx with invalid buf_id %d pdev %d\n", -@@ -5124,7 +5165,7 @@ int ath11k_dp_rx_process_wbm_err(struct +@@ -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], @@ -215,7 +215,7 @@ Signed-off-by: Tamizh Chelvam } rcu_read_lock(); -@@ -5151,6 +5187,8 @@ int ath11k_dp_rx_process_wbm_err(struct +@@ -5145,6 +5186,8 @@ int ath11k_dp_rx_process_wbm_err(struct } rcu_read_unlock(); done: @@ -224,7 +224,7 @@ Signed-off-by: Tamizh Chelvam return total_num_buffs_reaped; } -@@ -5238,7 +5276,7 @@ int ath11k_dp_process_rxdma_err(struct a +@@ -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, @@ -233,7 +233,7 @@ Signed-off-by: Tamizh Chelvam return budget - quota; } -@@ -6184,12 +6222,12 @@ static void ath11k_dp_rx_mon_dest_proces +@@ -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, @@ -248,7 +248,7 @@ Signed-off-by: Tamizh Chelvam } } -@@ -6701,7 +6739,7 @@ next_entry: +@@ -6697,7 +6740,7 @@ next_entry: ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, &dp->rxdma_mon_buf_ring, rx_bufs_used, diff --git a/package/kernel/mac80211/patches/nss/ath11k/999-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 index b58b13eebe1d40..988717c1dbc257 100644 --- a/package/kernel/mac80211/patches/nss/ath11k/999-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 @@ -217,7 +217,7 @@ Signed-off-by: Tamizh Chelvam Raja memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); } -@@ -2890,7 +2954,7 @@ static void ath11k_dp_rx_h_mpdu(struct a +@@ -2889,7 +2953,7 @@ static void ath11k_dp_rx_h_mpdu(struct a struct ieee80211_rx_status *rx_status, bool *fast_rx) { @@ -226,7 +226,7 @@ Signed-off-by: Tamizh Chelvam Raja enum hal_encrypt_type enctype; bool is_decrypted = false; struct ath11k_skb_rxcb *rxcb; -@@ -3123,10 +3187,16 @@ static void ath11k_dp_rx_deliver_msdu(st +@@ -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; @@ -243,7 +243,7 @@ Signed-off-by: Tamizh Chelvam Raja he = skb_push(msdu, sizeof(known)); memcpy(he, &known, sizeof(known)); status->flag |= RX_FLAG_RADIOTAP_HE; -@@ -3182,6 +3252,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; diff --git a/package/kernel/mac80211/patches/nss/subsys/007-fix_compilation_issue.patch b/package/kernel/mac80211/patches/nss/subsys/007-fix_compilation_issue.patch index d89cfbe51cb8ab..7a9b58411d0e1c 100644 --- a/package/kernel/mac80211/patches/nss/subsys/007-fix_compilation_issue.patch +++ b/package/kernel/mac80211/patches/nss/subsys/007-fix_compilation_issue.patch @@ -50,7 +50,7 @@ } --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -4780,7 +4780,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); @@ -72,7 +72,7 @@ sdata->debugfs.subdir_stations = debugfs_create_dir("stations", --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c -@@ -1410,18 +1410,6 @@ static void __sta_info_destroy_part2(str +@@ -1414,18 +1414,6 @@ static void __sta_info_destroy_part2(str WARN_ON_ONCE(ret); } @@ -93,7 +93,7 @@ --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -19472,7 +19472,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); @@ -102,7 +102,7 @@ enum nl80211_commands cmd, u8 count, u64 color_bitmap) { -@@ -19486,7 +19486,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); @@ -111,7 +111,7 @@ if (!msg) return -ENOMEM; -@@ -19509,7 +19509,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/nss/subsys/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 index a5da9e91eae835..86b2f2169bb79f 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -4688,8 +4688,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/nss/subsys/199-001-mac80211-add-nss-support.patch b/package/kernel/mac80211/patches/nss/subsys/199-001-mac80211-add-nss-support.patch index fc8fec0660f352..ecdf4d15c0c896 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 }; /** -@@ -1408,7 +1424,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 -@@ -1416,7 +1432,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) -@@ -1989,6 +2005,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 -@@ -2680,6 +2706,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 { -@@ -2737,6 +2765,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 -@@ -3749,6 +3778,10 @@ struct ieee80211_prep_tx_info { +@@ -3751,6 +3780,10 @@ struct ieee80211_prep_tx_info { * non-MLO connections. * The callback can sleep. * @@ -116,7 +116,7 @@ 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. -@@ -4300,7 +4333,9 @@ struct ieee80211_ops { +@@ -4302,7 +4335,9 @@ struct ieee80211_ops { struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, u64 changed); @@ -127,7 +127,7 @@ Signed-off-by: Sriram R 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, -@@ -4605,7 +4640,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); @@ -225,7 +225,7 @@ Signed-off-by: Sriram R return -EINVAL; --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c -@@ -2370,6 +2370,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; @@ -272,7 +272,7 @@ Signed-off-by: Sriram R info_id = ieee80211_store_ack_skb(local, skb, &info_flags, cookie); -@@ -4641,13 +4655,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 -@@ -2679,7 +2679,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)) -@@ -2729,6 +2729,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); } -@@ -2757,6 +2759,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); diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index fffe171334c9a4..01740e29803580 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -6215,7 +6215,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 index bd9c1c024b1e5d..d4410bd712f669 100644 --- 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 @@ -49,7 +49,7 @@ Signed-off-by: Muna Sinada #endif /* __NET_CFG80211_H */ --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -7361,6 +7361,20 @@ u32 ieee80211_calc_rx_airtime(struct iee +@@ -7363,6 +7363,20 @@ u32 ieee80211_calc_rx_airtime(struct iee int len); /** @@ -158,7 +158,7 @@ Signed-off-by: Muna Sinada #undef TRACE_INCLUDE_PATH --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -20199,6 +20199,42 @@ nla_put_failure: +@@ -20211,6 +20211,42 @@ nla_put_failure: } EXPORT_SYMBOL(cfg80211_update_owe_info_event); diff --git a/package/kernel/mac80211/patches/nss/subsys/207-ath11k-Add-support-for-dynamic-vlan.patch b/package/kernel/mac80211/patches/nss/subsys/207-ath11k-Add-support-for-dynamic-vlan.patch index 15d796071fa077..5ae1ba64bba9d5 100644 --- a/package/kernel/mac80211/patches/nss/subsys/207-ath11k-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, -@@ -4270,6 +4273,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); -@@ -4291,6 +4296,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/nss/subsys/207-mac80211-add-nss-redirect-support.patch b/package/kernel/mac80211/patches/nss/subsys/207-mac80211-add-nss-redirect-support.patch index a4895803b38ba0..38d737dc37d96a 100644 --- a/package/kernel/mac80211/patches/nss/subsys/207-mac80211-add-nss-redirect-support.patch +++ b/package/kernel/mac80211/patches/nss/subsys/207-mac80211-add-nss-redirect-support.patch @@ -209,7 +209,7 @@ Signed-off-by: Sowmiya Sree Elavalagan --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4503,6 +4503,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 -@@ -4516,6 +4545,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; -@@ -4702,6 +4735,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/nss/subsys/235-001-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 index 55e2fff1560fb8..3d543d714122dd 100644 --- a/package/kernel/mac80211/patches/nss/subsys/235-001-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 -@@ -5098,6 +5098,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); @@ -137,7 +137,7 @@ Signed-off-by: Sathishkumar Muruganandam { --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4297,8 +4297,13 @@ void __ieee80211_subif_start_xmit(struct +@@ -4298,8 +4298,13 @@ void __ieee80211_subif_start_xmit(struct sta = NULL; if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { @@ -153,7 +153,7 @@ Signed-off-by: Sathishkumar Muruganandam if (ap_sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED && !is_multicast_ether_addr(skb->data)) { if (sta) -@@ -4688,7 +4693,8 @@ static void ieee80211_8023_xmit(struct i +@@ -4689,7 +4694,8 @@ static void ieee80211_8023_xmit(struct i info->hw_queue = sdata->vif.hw_queue[queue]; diff --git a/package/kernel/mac80211/patches/nss/subsys/236-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 index 803ee900bfdcc1..542ab4e6a93831 100644 --- a/package/kernel/mac80211/patches/nss/subsys/236-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 -@@ -2086,6 +2086,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) -@@ -2105,6 +2107,7 @@ struct ieee80211_key_conf { +@@ -2107,6 +2109,7 @@ struct ieee80211_key_conf { u8 hw_key_idx; s8 keyidx; u16 flags; @@ -102,7 +102,7 @@ Signed-off-by: Sathishkumar Muruganandam key->conf.cipher = cipher; --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4649,16 +4649,25 @@ static void ieee80211_8023_xmit(struct i +@@ -4650,16 +4650,25 @@ static void ieee80211_8023_xmit(struct i struct ieee80211_key *key, struct sk_buff *skb) { struct ieee80211_tx_info *info; diff --git a/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch b/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch index 46b716419a7cd8..0e92c0f1332b7d 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -4678,19 +4678,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)); -@@ -4747,7 +4749,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 -@@ -4765,9 +4767,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]); -@@ -4778,6 +4784,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,47 +98,18 @@ Signed-off-by: Gautham Kumar Senthilkumaran ieee80211_8023_xmit(sdata, dev, sta, key, skb); goto out; -@@ -6284,13 +6291,7 @@ start_xmit: +@@ -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); -- -- memset(tmp, 0, len); -- return tmp; --} +- /* 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); - - 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/nss/subsys/300-ath11k-nss-mesh-offload-support.patch b/package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch index 55ad36baf69aa4..e1b46836c6b4c5 100644 --- a/package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch +++ b/package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch @@ -78,7 +78,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran 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 }; -@@ -2769,6 +2789,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 -@@ -4269,6 +4290,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. -@@ -4652,6 +4675,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); -@@ -7510,4 +7539,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 -@@ -2523,6 +2523,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; -@@ -2539,8 +2540,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)) { -@@ -2554,8 +2558,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)) -@@ -2590,8 +2598,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. -@@ -2633,6 +2645,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); @@ -379,7 +379,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran #endif /* __MAC80211_DRIVER_OPS */ --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h -@@ -315,6 +315,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); -@@ -356,6 +360,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); @@ -1221,7 +1221,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran info->ack_frame_id = info_id; info->band = band; -@@ -4274,6 +4284,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; @@ -1229,7 +1229,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran struct ieee80211_sub_if_data *ap_sdata; if (unlikely(!ieee80211_sdata_running(sdata) || skb->len < ETH_HLEN)) { -@@ -4350,9 +4361,15 @@ void __ieee80211_subif_start_xmit(struct +@@ -4351,9 +4362,15 @@ void __ieee80211_subif_start_xmit(struct goto out; } diff --git a/package/kernel/mac80211/patches/nss/subsys/335-0003-ath11k-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 index f78d7ce6e09304..0704e8fcf7da86 100644 --- a/package/kernel/mac80211/patches/nss/subsys/335-0003-ath11k-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 -@@ -2731,6 +2731,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 { -@@ -2790,6 +2792,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, diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index 63373b7751f9eb..314bcbe549af97 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -4761,6 +4761,67 @@ out_free: +@@ -4762,6 +4762,67 @@ out_free: kfree_skb(skb); } @@ -82,7 +82,7 @@ Signed-off-by: Aloka Dixit netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, struct net_device *dev) { -@@ -4800,6 +4861,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/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch b/package/kernel/mac80211/patches/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch index 0cb2a1e95244e3..c8d719006d170f 100644 --- a/package/kernel/mac80211/patches/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch +++ b/package/kernel/mac80211/patches/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch @@ -33,7 +33,7 @@ Signed-off-by: Tamizh Chelvam --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4695,7 +4695,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4696,7 +4696,7 @@ static void ieee80211_8023_xmit(struct i ieee80211_aggr_check(sdata, sta, skb); @@ -42,7 +42,7 @@ Signed-off-by: Tamizh Chelvam tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); if (tid_tx) { -@@ -4746,7 +4746,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4747,7 +4747,7 @@ static void ieee80211_8023_xmit(struct i &info->flags, NULL); dev_sw_netstats_tx_add(dev, skbs, len); diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index 2cb2ebe6f58f76..55380f59d3826c 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -1405,8 +1405,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 -@@ -1478,22 +1476,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), diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index a947728fc661f1..13977ab665862e 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 @@ -44,7 +44,7 @@ Signed-off-by: Aaradhana Sahu /* misc utils */ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, -@@ -4319,7 +4320,7 @@ void __ieee80211_subif_start_xmit(struct +@@ -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]); @@ -53,7 +53,7 @@ Signed-off-by: Aaradhana Sahu rcu_read_unlock(); return; } -@@ -4365,7 +4366,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]); @@ -62,7 +62,7 @@ Signed-off-by: Aaradhana Sahu } else { dev_sw_netstats_tx_add(dev, 1, skb->len); ieee80211_xmit(sdata, sta, skb); -@@ -4663,7 +4664,8 @@ 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, @@ -72,7 +72,7 @@ Signed-off-by: Aaradhana Sahu { struct ieee80211_tx_info *info; struct ethhdr *ehdr = (struct ethhdr *)skb->data; -@@ -4719,6 +4721,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4720,6 +4722,7 @@ static void ieee80211_8023_xmit(struct i info = IEEE80211_SKB_CB(skb); memset(info, 0, sizeof(*info)); @@ -80,7 +80,7 @@ Signed-off-by: Aaradhana Sahu info->hw_queue = sdata->vif.hw_queue[queue]; if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && -@@ -4739,11 +4742,12 @@ static void ieee80211_8023_xmit(struct i +@@ -4740,11 +4743,12 @@ static void ieee80211_8023_xmit(struct i memcpy(IEEE80211_SKB_CB(seg), info, sizeof(*info)); } @@ -96,7 +96,7 @@ Signed-off-by: Aaradhana Sahu dev_sw_netstats_tx_add(dev, skbs, len); if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD) && sta) { -@@ -4763,7 +4767,8 @@ out_free: +@@ -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, @@ -106,7 +106,7 @@ Signed-off-by: Aaradhana Sahu { struct ieee80211_tx_info *info; struct ieee80211_local *local = sdata->local; -@@ -4772,6 +4777,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; @@ -116,7 +116,7 @@ Signed-off-by: Aaradhana Sahu /* * If the skb is shared we need to obtain our own copy. -@@ -4783,11 +4791,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)); @@ -133,7 +133,7 @@ Signed-off-by: Aaradhana Sahu info->flags |= IEEE80211_TX_CTL_HW_80211_ENCAP; info->control.vif = &sdata->vif; -@@ -4821,14 +4831,23 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4822,14 +4832,23 @@ void ieee80211_8023_xmit_ap(struct ieee8 drv_tx(local, &control, skb); } @@ -158,7 +158,7 @@ Signed-off-by: Aaradhana Sahu #ifdef CPTCFG_MAC80211_NSS_SUPPORT ieee80211_xmit_nss_fixup(skb, dev); -@@ -4844,14 +4863,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; } @@ -176,7 +176,7 @@ Signed-off-by: Aaradhana Sahu goto skip_offload; key = rcu_dereference(sta->ptk[sta->ptk_idx]); -@@ -4862,13 +4882,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) { @@ -192,7 +192,7 @@ Signed-off-by: Aaradhana Sahu goto out; skip_offload: -@@ -6374,7 +6394,10 @@ start_xmit: +@@ -6375,7 +6395,10 @@ start_xmit: mutex_lock(&local->mtx); local_bh_disable(); diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index 7ffaf99158b90e..62916f15eddb56 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 -@@ -2350,7 +2350,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; 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 index 098767aa3f36db..ea83021014ad26 100644 --- 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 @@ -16,7 +16,7 @@ Signed-off-by: Maharaja Kennadyrajan --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c -@@ -2396,7 +2396,7 @@ void ieee80211_sta_update_pending_airtim +@@ -2385,7 +2385,7 @@ void ieee80211_sta_update_pending_airtim } static struct ieee80211_sta_rx_stats * @@ -25,7 +25,7 @@ Signed-off-by: Maharaja Kennadyrajan { struct ieee80211_sta_rx_stats *stats = &sta->deflink.rx_stats; int cpu; -@@ -2409,8 +2409,13 @@ sta_get_last_rx_stats(struct sta_info *s +@@ -2398,8 +2398,13 @@ sta_get_last_rx_stats(struct sta_info *s for_each_possible_cpu(cpu) { struct ieee80211_sta_rx_stats *cpustats; @@ -39,7 +39,7 @@ Signed-off-by: Maharaja Kennadyrajan if (time_after(cpustats->last_rx, stats->last_rx)) stats = cpustats; -@@ -2480,7 +2485,7 @@ static void sta_stats_decode_rate(struct +@@ -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) { @@ -48,16 +48,16 @@ Signed-off-by: Maharaja Kennadyrajan if (rate == STA_STATS_RATE_INVALID) return -EINVAL; -@@ -2680,7 +2685,7 @@ void sta_set_sinfo(struct sta_info *sta, +@@ -2576,7 +2581,7 @@ void sta_set_sinfo(struct sta_info *sta, + int i, ac, cpu; struct ieee80211_sta_rx_stats *last_rxstats; - struct link_sta_info *link_sta = NULL; - last_rxstats = sta_get_last_rx_stats(sta); + last_rxstats = sta_get_last_rx_stats(sta, false); sinfo->generation = sdata->local->sta_generation; -@@ -2924,7 +2929,7 @@ u32 sta_get_expected_throughput(struct s +@@ -2859,7 +2864,7 @@ u32 sta_get_expected_throughput(struct s unsigned long ieee80211_sta_last_active(struct sta_info *sta) { diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index 50466d46c37880..6be28b6ac56663 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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 @@ -58,7 +58,7 @@ Signed-off-by: Tamizh Chelvam Raja if (!skb) return true; -@@ -4343,7 +4345,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,7 +67,7 @@ Signed-off-by: Tamizh Chelvam Raja if (!skb) { len = 0; goto out; -@@ -4714,7 +4716,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4715,7 +4717,7 @@ static void ieee80211_8023_xmit(struct i } } 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 index b76692a6f9500c..c2846abf7e5961 100644 --- 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 @@ -23,7 +23,7 @@ Signed-off-by: Yuvasree Sivasankaran --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -2730,6 +2730,9 @@ struct ieee80211_txq { +@@ -2732,6 +2732,9 @@ struct ieee80211_txq { * * @IEEE80211_HW_SUPPORTS_TID_CLASS_OFFLOAD: Hardware suports tid calssification offload. * @@ -33,7 +33,7 @@ Signed-off-by: Yuvasree Sivasankaran * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays */ enum ieee80211_hw_flags { -@@ -2790,6 +2793,7 @@ 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, @@ -83,7 +83,7 @@ Signed-off-by: Yuvasree Sivasankaran return false; if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) -@@ -4328,7 +4335,8 @@ void __ieee80211_subif_start_xmit(struct +@@ -4329,7 +4336,8 @@ void __ieee80211_subif_start_xmit(struct } } @@ -93,7 +93,7 @@ Signed-off-by: Yuvasree Sivasankaran ieee80211_aggr_check(sdata, sta, skb); if (sta) { -@@ -4680,8 +4688,10 @@ static void ieee80211_8023_xmit(struct i +@@ -4681,8 +4689,10 @@ static void ieee80211_8023_xmit(struct i bool multicast; u8 tid; @@ -106,7 +106,7 @@ Signed-off-by: Yuvasree Sivasankaran multicast = is_multicast_ether_addr(ra); -@@ -6416,9 +6426,12 @@ int ieee80211_tx_control_port(struct wip +@@ -6379,9 +6389,12 @@ int ieee80211_tx_control_port(struct wip } if (!IS_ERR(sta)) { @@ -123,7 +123,7 @@ Signed-off-by: Yuvasree Sivasankaran * for MLO STA, the SA should be the AP MLD address, but --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -4525,6 +4525,9 @@ static int ieee80211_get_txq_stats(struc +@@ -4524,6 +4524,9 @@ static int ieee80211_get_txq_stats(struc struct ieee80211_sub_if_data *sdata; int ret = 0; @@ -205,7 +205,7 @@ Signed-off-by: Yuvasree Sivasankaran int i; sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp); -@@ -607,18 +609,22 @@ __sta_info_alloc(struct ieee80211_sub_if +@@ -611,18 +613,22 @@ __sta_info_alloc(struct ieee80211_sub_if sta->last_connected = ktime_get_seconds(); @@ -237,7 +237,7 @@ Signed-off-by: Yuvasree Sivasankaran } if (sta_prepare_rate_control(local, sta, gfp)) -@@ -692,7 +698,8 @@ __sta_info_alloc(struct ieee80211_sub_if +@@ -696,7 +702,8 @@ __sta_info_alloc(struct ieee80211_sub_if return sta; free_txq: @@ -247,7 +247,7 @@ Signed-off-by: Yuvasree Sivasankaran free: sta_info_free_link(&sta->deflink); #ifdef CPTCFG_MAC80211_MESH -@@ -1687,11 +1694,13 @@ void ieee80211_sta_ps_deliver_wakeup(str +@@ -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); @@ -265,7 +265,7 @@ Signed-off-by: Yuvasree Sivasankaran } skb_queue_head_init(&pending); -@@ -2106,6 +2115,9 @@ ieee80211_sta_ps_deliver_response(struct +@@ -2110,6 +2119,9 @@ ieee80211_sta_ps_deliver_response(struct * TIM recalculation. */ @@ -275,7 +275,7 @@ Signed-off-by: Yuvasree Sivasankaran for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) { if (!sta->sta.txq[tid] || !(driver_release_tids & BIT(tid)) || -@@ -2521,7 +2533,7 @@ static void sta_set_tidstats(struct sta_ +@@ -2546,7 +2558,7 @@ static void sta_set_tidstats(struct sta_ tidstats->tx_msdu_failed = sta->deflink.status_stats.msdu_failed[tid]; } @@ -284,7 +284,7 @@ Signed-off-by: Yuvasree Sivasankaran spin_lock_bh(&local->fq.lock); rcu_read_lock(); -@@ -2849,6 +2861,9 @@ unsigned long ieee80211_sta_last_active( +@@ -2874,6 +2886,9 @@ unsigned long ieee80211_sta_last_active( static void sta_update_codel_params(struct sta_info *sta, u32 thr) { diff --git a/package/kernel/mac80211/patches/nss/subsys/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 index e3d8db5815fe88..0f8289a892d4a4 100644 --- a/package/kernel/mac80211/patches/nss/subsys/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; From da57bc5f0ef9a9021c06951cc7f096180ae72215 Mon Sep 17 00:00:00 2001 From: Qosmio Date: Mon, 25 Mar 2024 18:27:34 -0400 Subject: [PATCH 220/225] qualcommax: consolidate symbols, revert built-in Symbols for crypto, ktls, netfilter are removed from from being compiled into the kernel and instead left up to the user to compile as modules, as is the case upstream. Other unused qca features were also removed as they don't apply to ipq807x/6018 and are not upstream. Common symbols between 6.1/6.6 that are required for NSS related features have been consolidated into 'config-default'. There is an average 300kb of savings in the final kernel image as well decreased compile time. qualcommax: NSS: consolidate patches and align with 6.1 Update nss-cfi to kernel 6.6 --- .../linux/qualcommax/ipq807x/config-default | 104 +++--------------- .../0600-1-qca-nss-ecm-support-CORE.patch | 10 ++ ...-IPv6-user-route-change-event-calls.patch} | 0 .../0605-1-qca-nss-cfi-support.patch | 20 +++- ..._ecache-Fix-NSS-ECM-BRK-kernel-panic.patch | 10 -- .../9990-1-qca-skb_recycler-support.patch | 12 -- 6 files changed, 41 insertions(+), 115 deletions(-) rename target/linux/qualcommax/patches-6.6/{0600-2-qca-nss-ecm-support-CORE-Fix-IPv6-user-route-change-event-calls.patch => 0600-7-qca-nss-ecm-fix-IPv6-user-route-change-event-calls.patch} (100%) delete mode 100644 target/linux/qualcommax/patches-6.6/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch diff --git a/target/linux/qualcommax/ipq807x/config-default b/target/linux/qualcommax/ipq807x/config-default index 68a750e6edb4ac..eeb86e850f04f8 100644 --- a/target/linux/qualcommax/ipq807x/config-default +++ b/target/linux/qualcommax/ipq807x/config-default @@ -1,92 +1,21 @@ CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y CONFIG_ARM_QCOM_CPUFREQ_HW=y -CONFIG_ASN1=y -CONFIG_ASN1_ENCODER=y -CONFIG_ASSOCIATIVE_ARRAY=y -CONFIG_ASYMMETRIC_KEY_TYPE=y -# CONFIG_ASYMMETRIC_TPM_KEY_SUBTYPE is not set -CONFIG_AT803X_PHY=y -CONFIG_BPFILTER=y -CONFIG_BPFILTER_UMH=m -CONFIG_CLZ_TAB=y CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y # CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set -CONFIG_CRYPTO_AES_ARM64=y -CONFIG_CRYPTO_AES_ARM64_BS=y -CONFIG_CRYPTO_AES_ARM64_CE=y -CONFIG_CRYPTO_AES_ARM64_CE_BLK=y -CONFIG_CRYPTO_AES_ARM64_CE_CCM=y -CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y -CONFIG_CRYPTO_ANSI_CPRNG=y -CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=y -CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=y -CONFIG_CRYPTO_BLAKE2B=y -CONFIG_CRYPTO_BLAKE2S=y -CONFIG_CRYPTO_CFB=y -CONFIG_CRYPTO_CHACHA20=y -CONFIG_CRYPTO_CHACHA20POLY1305=y -CONFIG_CRYPTO_CHACHA20_NEON=y -CONFIG_CRYPTO_CMAC=y -CONFIG_CRYPTO_CRCT10DIF=y -CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=y -CONFIG_CRYPTO_CRYPTD=y -CONFIG_CRYPTO_CURVE25519=y -CONFIG_CRYPTO_DH=y -CONFIG_CRYPTO_DH_RFC7919_GROUPS=y -CONFIG_CRYPTO_DRBG=y -CONFIG_CRYPTO_DRBG_HMAC=y -CONFIG_CRYPTO_DRBG_MENU=y -CONFIG_CRYPTO_ECC=y -CONFIG_CRYPTO_ECDH=y -CONFIG_CRYPTO_ECDSA=y -CONFIG_CRYPTO_ECRDSA=y -CONFIG_CRYPTO_GF128MUL=y -CONFIG_CRYPTO_GHASH_ARM64_CE=y -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_JITTERENTROPY=y -CONFIG_CRYPTO_KEYWRAP=y -CONFIG_CRYPTO_LIB_CHACHA_GENERIC=y -CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=y -CONFIG_CRYPTO_LIB_POLY1305_GENERIC=y -CONFIG_CRYPTO_LIB_SM4=y -CONFIG_CRYPTO_LRW=y -CONFIG_CRYPTO_MD4=y -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_NULL2=y -CONFIG_CRYPTO_NHPOLY1305_NEON=y -CONFIG_CRYPTO_OFB=y -CONFIG_CRYPTO_POLY1305=y -CONFIG_CRYPTO_POLY1305_NEON=y -CONFIG_CRYPTO_POLYVAL_ARM64_CE=y -CONFIG_CRYPTO_RNG_DEFAULT=y -CONFIG_CRYPTO_RSA=y -CONFIG_CRYPTO_SHA1_ARM64_CE=y -CONFIG_CRYPTO_SHA2_ARM64_CE=y -CONFIG_CRYPTO_SHA256_ARM64=y -CONFIG_CRYPTO_SHA3=y -CONFIG_CRYPTO_SHA3_ARM64=y -CONFIG_CRYPTO_SHA512=y -CONFIG_CRYPTO_SHA512_ARM64=y -CONFIG_CRYPTO_SHA512_ARM64_CE=y -CONFIG_CRYPTO_SIMD=y -CONFIG_CRYPTO_SM2=y -CONFIG_CRYPTO_SM3=y -CONFIG_CRYPTO_SM3_ARM64_CE=y -CONFIG_CRYPTO_SM3_NEON=y -CONFIG_CRYPTO_SM4_ARM64_CE=y -CONFIG_CRYPTO_SM4_ARM64_CE_BLK=y -CONFIG_CRYPTO_SM4_ARM64_NEON_BLK=y -CONFIG_CRYPTO_STREEBOG=y -CONFIG_CRYPTO_XXHASH=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_DT_IDLE_GENPD=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MSM=y +CONFIG_HZ=1000 +# CONFIG_HZ_100 is not set +CONFIG_HZ_1000=y CONFIG_IP6_NF_TARGET_MASQUERADE=y CONFIG_IP_NF_TARGET_MASQUERADE=y CONFIG_IPQ_GCC_8074=y # CONFIG_MFD_HI6421_SPMI is not set CONFIG_MFD_SPMI_PMIC=y -CONFIG_MPILIB=y # CONFIG_NVMEM_SPMI_SDAM is not set -CONFIG_OID_REGISTRY=y CONFIG_PINCTRL_IPQ8074=y CONFIG_PINCTRL_QCOM_SPMI_PMIC=y # CONFIG_PM8916_WATCHDOG is not set @@ -95,15 +24,11 @@ CONFIG_PM_GENERIC_DOMAINS_OF=y # CONFIG_POWER_RESET_QCOM_PON is not set CONFIG_QCOM_APM=y # CONFIG_QCOM_COINCELL is not set +CONFIG_QCOM_CPR=y CONFIG_QCOM_GDSC=y -# CONFIG_QCOM_IPA is not set -CONFIG_QCOM_QFPROM=y -# CONFIG_QCOM_QMI_HELPERS is not set CONFIG_QCOM_SPMI_ADC5=y # CONFIG_QCOM_SPMI_RRADC is not set CONFIG_QCOM_VADC_COMMON=y -CONFIG_QCOM_WCNSS_CTRL=y -CONFIG_QCOM_WCNSS_PIL=y CONFIG_REGMAP_SPMI=y CONFIG_REGULATOR_CPR3=y # CONFIG_REGULATOR_CPR3_NPU is not set @@ -111,16 +36,13 @@ CONFIG_REGULATOR_CPR4_APSS=y # CONFIG_REGULATOR_QCOM_LABIBB is not set CONFIG_REGULATOR_QCOM_SPMI=y # CONFIG_REGULATOR_QCOM_USB_VBUS is not set -CONFIG_RESET_QCOM_AOSS=y -CONFIG_RESET_QCOM_PDC=y CONFIG_RTC_DRV_PM8XXX=y -# CONFIG_SCHED_CLUSTER is not set -CONFIG_SCHED_CORE=y +# CONFIG_ALLOC_SKB_PAGE_FRAG_DISABLE is not set +# CONFIG_DEBUG_OBJECTS_SKBUFF is not set +CONFIG_SKB_RECYCLER=y +CONFIG_SKB_RECYCLER_MULTI_CPU=y +# CONFIG_SKB_FAST_RECYCLABLE_DEBUG_ENABLE is not set CONFIG_SPMI=y # CONFIG_SPMI_HISI3670 is not set CONFIG_SPMI_MSM_PMIC_ARB=y # CONFIG_SPMI_PMIC_CLKDIV is not set -CONFIG_TLS=y -CONFIG_TLS_DEVICE=y -# CONFIG_TLS_TOE is not set -CONFIG_XOR_BLOCKS=y diff --git a/target/linux/qualcommax/patches-6.6/0600-1-qca-nss-ecm-support-CORE.patch b/target/linux/qualcommax/patches-6.6/0600-1-qca-nss-ecm-support-CORE.patch index 21006721e11666..c49b9564044716 100644 --- a/target/linux/qualcommax/patches-6.6/0600-1-qca-nss-ecm-support-CORE.patch +++ b/target/linux/qualcommax/patches-6.6/0600-1-qca-nss-ecm-support-CORE.patch @@ -783,6 +783,16 @@ #endif /* _UAPI_LINUX_IN_H */ +--- a/net/netfilter/nf_conntrack_ecache.c ++++ b/net/netfilter/nf_conntrack_ecache.c +@@ -266,7 +266,6 @@ void nf_conntrack_register_notifier(stru + mutex_lock(&nf_ct_ecache_mutex); + notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb, + lockdep_is_held(&nf_ct_ecache_mutex)); +- WARN_ON_ONCE(notify); + rcu_assign_pointer(net->ct.nf_conntrack_event_cb, new); + mutex_unlock(&nf_ct_ecache_mutex); + } --- a/include/net/netns/conntrack.h +++ b/include/net/netns/conntrack.h @@ -26,6 +26,7 @@ struct nf_tcp_net { diff --git a/target/linux/qualcommax/patches-6.6/0600-2-qca-nss-ecm-support-CORE-Fix-IPv6-user-route-change-event-calls.patch b/target/linux/qualcommax/patches-6.6/0600-7-qca-nss-ecm-fix-IPv6-user-route-change-event-calls.patch similarity index 100% rename from target/linux/qualcommax/patches-6.6/0600-2-qca-nss-ecm-support-CORE-Fix-IPv6-user-route-change-event-calls.patch rename to target/linux/qualcommax/patches-6.6/0600-7-qca-nss-ecm-fix-IPv6-user-route-change-event-calls.patch diff --git a/target/linux/qualcommax/patches-6.6/0605-1-qca-nss-cfi-support.patch b/target/linux/qualcommax/patches-6.6/0605-1-qca-nss-cfi-support.patch index f6a439ba5306a6..a0ed16e38f242e 100644 --- a/target/linux/qualcommax/patches-6.6/0605-1-qca-nss-cfi-support.patch +++ b/target/linux/qualcommax/patches-6.6/0605-1-qca-nss-cfi-support.patch @@ -1,6 +1,6 @@ --- a/crypto/authenc.c +++ b/crypto/authenc.c -@@ -415,6 +415,8 @@ static int crypto_authenc_create(struct +@@ -417,6 +417,8 @@ static int crypto_authenc_create(struct enc->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME) goto err_free_inst; @@ -11,7 +11,7 @@ inst->alg.base.cra_blocksize = enc->base.cra_blocksize; --- a/include/linux/crypto.h +++ b/include/linux/crypto.h -@@ -86,6 +86,11 @@ +@@ -101,6 +101,11 @@ #define CRYPTO_NOLOAD 0x00008000 /* @@ -25,6 +25,14 @@ * flag unset if they can't handle memory allocation failures. --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c +@@ -3,6 +3,7 @@ + + #include + #include ++#include + #include + #include + #include @@ -658,6 +658,7 @@ static int esp_output(struct xfrm_state struct ip_esp_hdr *esph; struct crypto_aead *aead; @@ -68,6 +76,14 @@ --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c +@@ -15,6 +15,7 @@ + + #include + #include ++#include + #include + #include + #include @@ -696,6 +696,7 @@ static int esp6_output(struct xfrm_state struct ip_esp_hdr *esph; struct crypto_aead *aead; diff --git a/target/linux/qualcommax/patches-6.6/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch b/target/linux/qualcommax/patches-6.6/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch deleted file mode 100644 index 4b9ee21f2f8545..00000000000000 --- a/target/linux/qualcommax/patches-6.6/0610-netfilter-nf_conntrack_ecache-Fix-NSS-ECM-BRK-kernel-panic.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/net/netfilter/nf_conntrack_ecache.c -+++ b/net/netfilter/nf_conntrack_ecache.c -@@ -266,7 +266,6 @@ void nf_conntrack_register_notifier(stru - mutex_lock(&nf_ct_ecache_mutex); - notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb, - lockdep_is_held(&nf_ct_ecache_mutex)); -- WARN_ON_ONCE(notify); - rcu_assign_pointer(net->ct.nf_conntrack_event_cb, new); - mutex_unlock(&nf_ct_ecache_mutex); - } diff --git a/target/linux/qualcommax/patches-6.6/9990-1-qca-skb_recycler-support.patch b/target/linux/qualcommax/patches-6.6/9990-1-qca-skb_recycler-support.patch index 886bc92fe2e26a..e59b5e5398aea4 100644 --- a/target/linux/qualcommax/patches-6.6/9990-1-qca-skb_recycler-support.patch +++ b/target/linux/qualcommax/patches-6.6/9990-1-qca-skb_recycler-support.patch @@ -1,5 +1,3 @@ -diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h -index 624d4a3..5aa8808 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -94,6 +94,7 @@ enum cpuhp_state { @@ -10,8 +8,6 @@ index 624d4a3..5aa8808 100644 CPUHP_PCI_XGENE_DEAD, CPUHP_IOMMU_IOVA_DEAD, CPUHP_LUSTRE_CFS_DEAD, -diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h -index 83cced8..b6ee509 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1065,6 +1065,10 @@ struct sk_buff { @@ -44,8 +40,6 @@ index 83cced8..b6ee509 100644 void kfree_skb_partial(struct sk_buff *skb, bool head_stolen); bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from, -diff --git a/net/Kconfig b/net/Kconfig -index 61eac93..e0c8bf0 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -369,6 +369,27 @@ config NET_FLOW_LIMIT @@ -76,8 +70,6 @@ index 61eac93..e0c8bf0 100644 menu "Network testing" config NET_PKTGEN -diff --git a/net/core/Makefile b/net/core/Makefile -index 5c9fc1f..e90878c 100644 --- a/net/core/Makefile +++ b/net/core/Makefile @@ -41,3 +41,4 @@ obj-$(CONFIG_NET_SOCK_MSG) += skmsg.o @@ -85,8 +77,6 @@ index 5c9fc1f..e90878c 100644 obj-$(CONFIG_BPF_SYSCALL) += bpf_sk_storage.o obj-$(CONFIG_OF) += of_net.o +obj-$(CONFIG_SKB_RECYCLER) += skbuff_recycle.o -diff --git a/net/core/dev.c b/net/core/dev.c -index 85a1038..c6994ab 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -6016,10 +6016,16 @@ static int process_backlog(struct napi_struct *napi, int quota) @@ -107,8 +97,6 @@ index 85a1038..c6994ab 100644 __netif_receive_skb(skb); rcu_read_unlock(); input_queue_head_incr(sd); -diff --git a/net/core/skbuff.c b/net/core/skbuff.c -index bcfa460..eaf8bcb 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -87,6 +87,31 @@ From 733f9f882eedbdcc7ac0e8d41261ed9f77ab7ee6 Mon Sep 17 00:00:00 2001 From: Sean Khan Date: Sun, 31 Mar 2024 19:16:29 -0400 Subject: [PATCH 221/225] qualcommax: disable swiotlb for 64mb in saving. Disable software input output translation lookaside buffer (swiotlb) as it wastes memory on low memory platforms (512m or less) qualcommax: only disable swiotlb for platforms <= 512M Disabling swiotlb is only required for platforms with 512M or less to save 64mb. --- ...com-disable-swiotlb-for-64mb-savings.patch | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 target/linux/qualcommax/patches-6.6/9991-arm64-dts-qcom-disable-swiotlb-for-64mb-savings.patch diff --git a/target/linux/qualcommax/patches-6.6/9991-arm64-dts-qcom-disable-swiotlb-for-64mb-savings.patch b/target/linux/qualcommax/patches-6.6/9991-arm64-dts-qcom-disable-swiotlb-for-64mb-savings.patch new file mode 100644 index 00000000000000..bb610079aad154 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/9991-arm64-dts-qcom-disable-swiotlb-for-64mb-savings.patch @@ -0,0 +1,99 @@ +--- a/arch/arm64/boot/dts/qcom/ipq6010-wax214.dts ++++ b/arch/arm64/boot/dts/qcom/ipq6010-wax214.dts +@@ -25,7 +25,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " root=/dev/ubiblock0_1"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_1"; + }; + + keys { +--- a/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts ++++ b/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts +@@ -27,7 +27,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " root=/dev/ubiblock0_1"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_1"; + }; + + keys { +--- a/arch/arm64/boot/dts/qcom/ipq8070-rm2-6.dts ++++ b/arch/arm64/boot/dts/qcom/ipq8070-rm2-6.dts +@@ -32,7 +32,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " root=/dev/ubiblock0_1"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_1"; + }; + + keys { +--- a/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi +@@ -20,7 +20,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " root=/dev/ubiblock0_0"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_0"; + }; + + keys { +--- a/arch/arm64/boot/dts/qcom/ipq8071-mf269.dts ++++ b/arch/arm64/boot/dts/qcom/ipq8071-mf269.dts +@@ -24,7 +24,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " root=/dev/ubiblock0_0"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_0"; + }; + + keys { +--- a/arch/arm64/boot/dts/qcom/ipq8072-ax880.dts ++++ b/arch/arm64/boot/dts/qcom/ipq8072-ax880.dts +@@ -29,7 +29,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " root=/dev/ubiblock0_1"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_1"; + }; + + keys { +--- a/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts ++++ b/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts +@@ -27,7 +27,7 @@ + * Netgear's U-Boot adds "ubi.mtd=rootfs root=mtd:ubi_rootfs" + * That fails to create a UBI block device, so add it here. + */ +- bootargs-append = " ubi.block=0,rootfs root=/dev/ubiblock0_1"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce ubi.block=0,rootfs root=/dev/ubiblock0_1"; + }; + + keys { +--- a/arch/arm64/boot/dts/qcom/ipq8072-wpq873.dts ++++ b/arch/arm64/boot/dts/qcom/ipq8072-wpq873.dts +@@ -31,7 +31,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " root=/dev/ubiblock0_1"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_1"; + }; + + keys { +--- a/arch/arm64/boot/dts/qcom/ipq8174-mx4200.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq8174-mx4200.dtsi +@@ -29,7 +29,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs-append = " root=/dev/ubiblock0_0"; ++ bootargs-append = " coherent_pool=2M swiotlb=noforce root=/dev/ubiblock0_0"; + }; + + keys { From 507e1c98b29d3409369a7a7a97eeb4008ca24e0c Mon Sep 17 00:00:00 2001 From: Sean Khan Date: Mon, 29 Apr 2024 21:50:56 -0400 Subject: [PATCH 222/225] qualcommax: qca-mcs support for kernel >= 6.6.29 Signed-off-by: Sean Khan --- .../0604-1-qca-add-mcs-support.patch | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/target/linux/qualcommax/patches-6.6/0604-1-qca-add-mcs-support.patch b/target/linux/qualcommax/patches-6.6/0604-1-qca-add-mcs-support.patch index edf21700c3e94c..4b87366d84966a 100644 --- a/target/linux/qualcommax/patches-6.6/0604-1-qca-add-mcs-support.patch +++ b/target/linux/qualcommax/patches-6.6/0604-1-qca-add-mcs-support.patch @@ -39,15 +39,15 @@ * added to the bridge private HW address list and all required ports --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h -@@ -906,6 +906,7 @@ void br_manage_promisc(struct net_bridge +@@ -907,6 +907,7 @@ void br_manage_promisc(struct net_bridge int nbp_backup_change(struct net_bridge_port *p, struct net_device *backup_dev); /* br_input.c */ -+int br_pass_frame_up(struct sk_buff *skb); /* QCA qca-mcs support */ ++int br_pass_frame_up(struct sk_buff *skb, bool promisc); /* QCA qca-mcs support */ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb); rx_handler_func_t *br_get_rx_handler(const struct net_device *dev); -@@ -2268,4 +2269,14 @@ struct nd_msg *br_is_nd_neigh_msg(struct +@@ -2269,4 +2270,14 @@ struct nd_msg *br_is_nd_neigh_msg(struct bool br_is_neigh_suppress_enabled(const struct net_bridge_port *p, u16 vid); #define __br_get(__hook, __default, __args ...) \ (__hook ? (__hook(__args)) : (__default)) /* QCA NSS ECM support */ @@ -109,7 +109,7 @@ return netif_receive_skb(skb); } --static int br_pass_frame_up(struct sk_buff *skb) +-static int br_pass_frame_up(struct sk_buff *skb, bool promisc) +/* QCA qca-mcs support - Start */ +/* Hook for external Multicast handler */ +br_multicast_handle_hook_t __rcu *br_multicast_handle_hook __read_mostly; @@ -120,11 +120,11 @@ +EXPORT_SYMBOL_GPL(br_get_dst_hook); +/* QCA qca-mcs support - End */ + -+int br_pass_frame_up(struct sk_buff *skb) ++int br_pass_frame_up(struct sk_buff *skb, bool promisc) { struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev; struct net_bridge *br = netdev_priv(brdev); -@@ -69,6 +79,7 @@ static int br_pass_frame_up(struct sk_bu +@@ -71,6 +81,7 @@ static int br_pass_frame_up(struct sk_bu dev_net(indev), NULL, skb, indev, NULL, br_netif_receive_skb); } @@ -132,7 +132,7 @@ /* note: already called with rcu_read_lock */ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb) -@@ -82,6 +93,11 @@ int br_handle_frame_finish(struct net *n +@@ -84,6 +95,11 @@ int br_handle_frame_finish(struct net *n struct net_bridge_mcast *brmctx; struct net_bridge_vlan *vlan; struct net_bridge *br; @@ -141,10 +141,10 @@ + struct net_bridge_port *pdst = NULL; + br_get_dst_hook_t *get_dst_hook = rcu_dereference(br_get_dst_hook); + /* QCA qca-mcs support - End */ + bool promisc; u16 vid = 0; u8 state; - -@@ -175,6 +191,12 @@ int br_handle_frame_finish(struct net *n +@@ -180,6 +196,12 @@ int br_handle_frame_finish(struct net *n switch (pkt_type) { case BR_PKT_MULTICAST: @@ -157,7 +157,7 @@ mdst = br_mdb_get(brmctx, skb, vid); if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) && br_multicast_querier_exists(brmctx, eth_hdr(skb), mdst)) { -@@ -190,8 +212,15 @@ int br_handle_frame_finish(struct net *n +@@ -195,8 +217,15 @@ int br_handle_frame_finish(struct net *n } break; case BR_PKT_UNICAST: @@ -175,7 +175,7 @@ default: break; } -@@ -206,6 +235,13 @@ int br_handle_frame_finish(struct net *n +@@ -211,6 +240,13 @@ int br_handle_frame_finish(struct net *n dst->used = now; br_forward(dst->dst, skb, local_rcv, false); } else { From 410396a9aa5777964a6d43df881e4bbe8f100498 Mon Sep 17 00:00:00 2001 From: Sean Khan Date: Sun, 5 May 2024 00:59:15 -0400 Subject: [PATCH 223/225] feeds: nss-packages: switch to branch 12.5-6.x --- feeds.conf.default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feeds.conf.default b/feeds.conf.default index 68c55d271c0819..5e40f047d6b5f4 100644 --- a/feeds.conf.default +++ b/feeds.conf.default @@ -2,7 +2,7 @@ src-git packages https://git.openwrt.org/feed/packages.git src-git luci https://git.openwrt.org/project/luci.git src-git routing https://git.openwrt.org/feed/routing.git src-git telephony https://git.openwrt.org/feed/telephony.git -src-git nss_packages https://github.com/qosmio/nss-packages.git;NSS-12.4-K6.x +src-git nss_packages https://github.com/qosmio/nss-packages.git;NSS-12.5-K6.x src-git sqm_scripts_nss https://github.com/qosmio/sqm-scripts-nss.git #src-git video https://github.com/openwrt/video.git #src-git targets https://github.com/openwrt/targets.git From 1a80bc4078f21a2f0c919fccc303364ee3b0d87a Mon Sep 17 00:00:00 2001 From: Sean Khan Date: Sun, 5 May 2024 01:02:03 -0400 Subject: [PATCH 224/225] ath11k_nss: fix invalid access to memory In ath11k_dp_rx_msdu_coalesce(), rxcb is fetched from skb and bool is_continuation is part of rxcb. Currently, after freeing the skb, the rxcb->is_continuation accessed again which is wrong since the memory is already freed. Hence fix the issue by locally defining bool is_continuation from rxcb, so that after freeing skb also we can use is_continuation. Signed-off-by: Sean Khan --- ...-ath11k-fix-invalid-access-to-memory.patch | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 package/kernel/mac80211/patches/nss/ath11k/909-wifi-ath11k-fix-invalid-access-to-memory.patch diff --git a/package/kernel/mac80211/patches/nss/ath11k/909-wifi-ath11k-fix-invalid-access-to-memory.patch b/package/kernel/mac80211/patches/nss/ath11k/909-wifi-ath11k-fix-invalid-access-to-memory.patch new file mode 100644 index 00000000000000..da069c0de63163 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/909-wifi-ath11k-fix-invalid-access-to-memory.patch @@ -0,0 +1,47 @@ +From cea94c73e068ce4e015327bf251f782545d8e365 Mon Sep 17 00:00:00 2001 +From: Sarika Sharma +Date: Mon, 29 Jan 2024 16:01:23 +0530 +Subject: [PATCH] wifi: ath11k: fix invalid access to memory + +In ath11k_dp_rx_msdu_coalesce(), rxcb is fetched from skb and bool +is_continuation is part of rxcb. +Currently, after freeing the skb, the rxcb->is_continuation accessed +again which is wrong since the memory is already freed. + +Hence fix the issue by locally defining bool is_continuation from rxcb, +so that after freeing skb also we can use is_continuation. + +Signed-off-by: Sarika Sharma +--- + drivers/net/wireless/ath/ath11k/dp_rx.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -2202,6 +2202,7 @@ static int ath11k_dp_rx_msdu_coalesce(st + struct hal_rx_desc *ldesc; + int space_extra, rem_len, buf_len; + u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; ++ bool is_continuation; + + /* As the msdu is spread across multiple rx buffers, + * find the offset to the start of msdu for computing +@@ -2250,7 +2251,8 @@ static int ath11k_dp_rx_msdu_coalesce(st + rem_len = msdu_len - buf_first_len; + while ((skb = __skb_dequeue(msdu_list)) != NULL && rem_len > 0) { + rxcb = ATH11K_SKB_RXCB(skb); +- if (rxcb->is_continuation) ++ is_continuation = rxcb->is_continuation; ++ if (is_continuation) + buf_len = DP_RX_BUFFER_SIZE - hal_rx_desc_sz; + else + buf_len = rem_len; +@@ -2268,7 +2270,7 @@ static int ath11k_dp_rx_msdu_coalesce(st + dev_kfree_skb_any(skb); + + rem_len -= buf_len; +- if (!rxcb->is_continuation) ++ if (!is_continuation) + break; + } + From 053618a90c182f6c5a06996f8dae9a210979609b Mon Sep 17 00:00:00 2001 From: Sean Khan Date: Sat, 4 May 2024 17:09:08 -0400 Subject: [PATCH 225/225] kernel: qca-ssdk: update to 12.5 for kernel 6.6 Qualcomm recently committed a new branch (12.5.r2) targeting kernel 6.6. This lets us clean up a few patches particularly the one for "C22/C45" mdio. A quick way to see what changed for IPQ807x/6018 was to list the files produced during build (**/*.o), replace the extension with ".c", and doing a `git log`. Filtering from those commits, ones of particular interest are listed below: ``` 2024-04-16 - 0d8f30aa - fix compile issue on hk with linux style build 2024-01-29 - 636464f7 - update the check for port link notify 2024-01-24 - 30c10e7f - enable and disable loopback for xgmac to fix qm stuck issue 2024-01-15 - b6ea10aa - update the the APIs to access switch 2024-01-08 - a1687502 - Disable Tx bridge mac before power off the PHY 2024-01-07 - 3eafb613 - support led configure for malibu phy 2024-01-07 - 5c1af60d - remove phy type check from mac reset when mode switch 2023-12-17 - 79d0b1e8 - remove the PHY access APIs in ssdk_plat.c 2023-12-16 - b2953740 - Update mii read/write functions 2023-12-11 - 37f2eac3 - add port id check for fdb entry 2023-12-11 - d040ca4d - support mdio clause45 on kernel6.6 2023-12-07 - 11494fbc - use barrier mw() during access fdb entry table 2023-12-03 - 8e40a284 - fix build warnings on kernel6.6 2023-11-10 - 10aa0a02 - change speed value when call ssdk_port_link_notify 2023-11-06 - ee4c4a60 - Update mac bitmap value of L3 table on MAC delete 2023-11-03 - 7cd27d39 - support 10G phy common feature 2023-10-30 - 383cc0d2 - fix mactype and mux select issue 2023-10-24 - decf534a - support autoneg status query on force port 2023-10-11 - 111d574e - move ssdk_led_init to regi_init 2023-10-08 - 6b14c142 - the combo port also need to parse SFP pins 2023-10-03 - fb2e0401 - fix port5 interface mode switch issue in erp case ``` Verified with users on QNAP 301W, NBG7815, and myself on Dynalink DL-WRX36 that everything is functional, including LEDS. Signed-off-by: Sean Khan --- package/kernel/qca-ssdk/Makefile | 8 +- .../0001-config-identify-kernel-6.6.patch | 47 --------- ...upport-for-detection-PSGMII-PHY-mode.patch | 2 +- ...-selecting-PCS-channel-for-PORT3-on-.patch | 20 ++-- ...dapt-to-C22-and-C45-read-write-split.patch | 98 ------------------- .../patches/200-allow-parallel-build.patch | 2 +- .../patches/201-fix-compile-warnings.patch | 31 ++++++ 7 files changed, 47 insertions(+), 161 deletions(-) delete mode 100644 package/kernel/qca-ssdk/patches/0001-config-identify-kernel-6.6.patch delete mode 100644 package/kernel/qca-ssdk/patches/103-mdio-adapt-to-C22-and-C45-read-write-split.patch create mode 100644 package/kernel/qca-ssdk/patches/201-fix-compile-warnings.patch diff --git a/package/kernel/qca-ssdk/Makefile b/package/kernel/qca-ssdk/Makefile index bbe9f120514627..ed18f17504dbef 100644 --- a/package/kernel/qca-ssdk/Makefile +++ b/package/kernel/qca-ssdk/Makefile @@ -1,13 +1,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=qca-ssdk -PKG_RELEASE:=6 +PKG_RELEASE:=1 PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/qca-ssdk.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2023-10-04 -PKG_SOURCE_VERSION:=23a5aa4a4d5834da7a07efb58baebfbee91786b0 -PKG_MIRROR_HASH:=53fb201053b3aca004c4da07b06a0608b0b3322a2062b1f7ab3b3a7871ddabcb +PKG_SOURCE_DATE:=2024-04-17 +PKG_SOURCE_VERSION:=3d060f7ad70d087f6b0452abe79ab6d042e8cd53 +PKG_MIRROR_HASH:=6f5e390b294e699491584094f5d7eb941de6237ad8c5320191e9e306fbcd8eb5 PKG_FLAGS:=nonshared PKG_BUILD_PARALLEL:=1 diff --git a/package/kernel/qca-ssdk/patches/0001-config-identify-kernel-6.6.patch b/package/kernel/qca-ssdk/patches/0001-config-identify-kernel-6.6.patch deleted file mode 100644 index 2dc092326306b3..00000000000000 --- a/package/kernel/qca-ssdk/patches/0001-config-identify-kernel-6.6.patch +++ /dev/null @@ -1,47 +0,0 @@ -From f6c0115daaac586740e873a3b8145c5370a73dce Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Sat, 17 Feb 2024 13:02:31 +0100 -Subject: [PATCH] config: identify kernel 6.6 - -Identify kernel 6.6 so it can be compiled against. - -Signed-off-by: Robert Marko ---- - config | 5 +++++ - make/linux_opt.mk | 4 ++-- - 2 files changed, 7 insertions(+), 2 deletions(-) - ---- a/config -+++ b/config -@@ -27,6 +27,11 @@ endif - ifeq ($(KVER),$(filter 6.1%,$(KVER))) - OS_VER=6_1 - endif -+ -+ifeq ($(KVER),$(filter 6.6%,$(KVER))) -+ OS_VER=6_6 -+endif -+ - ifeq ($(KVER), 3.4.0) - OS_VER=3_4 - endif ---- a/make/linux_opt.mk -+++ b/make/linux_opt.mk -@@ -450,7 +450,7 @@ ifeq (KSLIB, $(MODULE_TYPE)) - KASAN_SHADOW_SCALE_SHIFT := 3 - endif - -- ifeq ($(OS_VER),$(filter 5_4 6_1, $(OS_VER))) -+ ifeq ($(OS_VER),$(filter 5_4 6_1 6_6, $(OS_VER))) - ifeq ($(ARCH), arm64) - KASAN_OPTION += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT) - endif -@@ -481,7 +481,7 @@ ifeq (KSLIB, $(MODULE_TYPE)) - - endif - -- ifeq ($(OS_VER),$(filter 4_4 5_4 6_1, $(OS_VER))) -+ ifeq ($(OS_VER),$(filter 4_4 5_4 6_1 6_6, $(OS_VER))) - MODULE_CFLAG += -DKVER34 - MODULE_CFLAG += -DKVER32 - MODULE_CFLAG += -DLNX26_22 diff --git a/package/kernel/qca-ssdk/patches/101-hsl_phy-add-support-for-detection-PSGMII-PHY-mode.patch b/package/kernel/qca-ssdk/patches/101-hsl_phy-add-support-for-detection-PSGMII-PHY-mode.patch index c27902c4ce1d8c..9d028992a7298b 100644 --- a/package/kernel/qca-ssdk/patches/101-hsl_phy-add-support-for-detection-PSGMII-PHY-mode.patch +++ b/package/kernel/qca-ssdk/patches/101-hsl_phy-add-support-for-detection-PSGMII-PHY-mode.patch @@ -13,7 +13,7 @@ Signed-off-by: Christian Marangi --- a/src/hsl/phy/hsl_phy.c +++ b/src/hsl/phy/hsl_phy.c -@@ -1335,6 +1335,9 @@ hsl_port_phydev_interface_mode_status_ge +@@ -1322,6 +1322,9 @@ hsl_port_phydev_interface_mode_status_ge case PHY_INTERFACE_MODE_10GKR: *interface_mode_status = PORT_10GBASE_R; break; diff --git a/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch b/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch index 5e390d8ee339c0..db84ea1422f1b8 100644 --- a/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch +++ b/package/kernel/qca-ssdk/patches/102-qca-ssdk-support-selecting-PCS-channel-for-PORT3-on-.patch @@ -24,15 +24,15 @@ Signed-off-by: Mantas Pucka --- a/include/init/ssdk_dts.h +++ b/include/init/ssdk_dts.h -@@ -101,6 +101,7 @@ typedef struct +@@ -99,6 +99,7 @@ typedef struct a_uint32_t emu_chip_ver; /*only valid when is_emulation is true*/ a_uint32_t clk_mode; a_uint32_t pcie_hw_base; + a_uint32_t port3_pcs_channel; + led_ctrl_pattern_t source_pattern[SSDK_MAX_PORT_NUM][PORT_LED_SOURCE_MAX]; } ssdk_dt_cfg; - #define SSDK_MAX_NR_ETH 6 -@@ -162,6 +163,7 @@ a_uint32_t ssdk_device_id_get(a_uint32_t +@@ -161,6 +162,7 @@ a_uint32_t ssdk_device_id_get(a_uint32_t struct device_node *ssdk_dts_node_get(a_uint32_t dev_id); struct clk *ssdk_dts_essclk_get(a_uint32_t dev_id); struct clk *ssdk_dts_cmnclk_get(a_uint32_t dev_id); @@ -62,7 +62,7 @@ Signed-off-by: Mantas Pucka cppe_port_mux_ctrl.bf.port4_pcs_sel = --- a/src/adpt/hppe/adpt_hppe_uniphy.c +++ b/src/adpt/hppe/adpt_hppe_uniphy.c -@@ -1122,9 +1122,6 @@ __adpt_hppe_uniphy_psgmii_mode_set(a_uin +@@ -1160,9 +1160,6 @@ __adpt_hppe_uniphy_psgmii_mode_set(a_uin { a_uint32_t i; sw_error_t rv = SW_OK; @@ -72,7 +72,7 @@ Signed-off-by: Mantas Pucka union uniphy_mode_ctrl_u uniphy_mode_ctrl; -@@ -1134,9 +1131,7 @@ __adpt_hppe_uniphy_psgmii_mode_set(a_uin +@@ -1172,9 +1169,7 @@ __adpt_hppe_uniphy_psgmii_mode_set(a_uin SSDK_DEBUG("uniphy %d is psgmii mode\n", uniphy_index); #if defined(CPPE) if (adpt_ppe_type_get(dev_id) == CPPE_TYPE) { @@ -92,14 +92,14 @@ Signed-off-by: Mantas Pucka +a_uint32_t ssdk_dts_port3_pcs_channel_get(a_uint32_t dev_id) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; -+ ++ + return cfg->port3_pcs_channel; +} + - #ifndef BOARD_AR71XX #if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) static void ssdk_dt_parse_mac_mode(a_uint32_t dev_id, -@@ -306,6 +313,25 @@ static void ssdk_dt_parse_mac_mode(a_uin + struct device_node *switch_node, ssdk_init_cfg *cfg) +@@ -305,6 +312,25 @@ static void ssdk_dt_parse_mac_mode(a_uin return; } @@ -109,7 +109,7 @@ Signed-off-by: Mantas Pucka +{ + const __be32 *port3_pcs_channel; + a_uint32_t len = 0; -+ ++ + port3_pcs_channel = of_get_property(switch_node, "port3_pcs_channel", &len); + if (!port3_pcs_channel) { + ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->port3_pcs_channel = 2; @@ -125,7 +125,7 @@ Signed-off-by: Mantas Pucka #ifdef IN_UNIPHY static void ssdk_dt_parse_uniphy(a_uint32_t dev_id) { -@@ -1292,6 +1318,7 @@ sw_error_t ssdk_dt_parse(ssdk_init_cfg * +@@ -1347,6 +1373,7 @@ sw_error_t ssdk_dt_parse(ssdk_init_cfg * rv = ssdk_dt_parse_access_mode(switch_node, ssdk_dt_priv); SW_RTN_ON_ERROR(rv); ssdk_dt_parse_mac_mode(*dev_id, switch_node, cfg); diff --git a/package/kernel/qca-ssdk/patches/103-mdio-adapt-to-C22-and-C45-read-write-split.patch b/package/kernel/qca-ssdk/patches/103-mdio-adapt-to-C22-and-C45-read-write-split.patch deleted file mode 100644 index 7ddca554ecbd50..00000000000000 --- a/package/kernel/qca-ssdk/patches/103-mdio-adapt-to-C22-and-C45-read-write-split.patch +++ /dev/null @@ -1,98 +0,0 @@ -From bdae481e89cbe551068a99028bb57119b59f5ff4 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Tue, 26 Mar 2024 12:19:49 +0100 -Subject: [PATCH] mdio: adapt to C22 and C45 read/write split - -Kernel 6.3 has introduced separate C45 read/write operations, and thus -split them out of the C22 operations completely so the old way of marking -C45 reads and writes via the register value does not work anymore. - -This is causing SSDK to fail and find C45 only PHY-s such as Aquantia ones: -[ 22.187877] ssdk_phy_driver_init[371]:INFO:dev_id = 0, phy_adress = 8, phy_id = 0x0 phytype doesn't match -[ 22.209924] ssdk_phy_driver_init[371]:INFO:dev_id = 0, phy_adress = 0, phy_id = 0x0 phytype doesn't match - -This in turn causes USXGMII MAC autoneg bit to not get set and then UNIPHY -autoneg will time out, causing the 10G ports not to work: -[ 37.292784] uniphy autoneg time out! - -So, lets detect C45 reads and writes by the magic BIT(30) in the register -argument and if so call separate C45 mdiobus read/write functions. - -Signed-off-by: Robert Marko ---- - include/init/ssdk_plat.h | 7 +++++++ - src/init/ssdk_plat.c | 30 ++++++++++++++++++++++++++++++ - 2 files changed, 37 insertions(+) - ---- a/include/init/ssdk_plat.h -+++ b/include/init/ssdk_plat.h -@@ -505,3 +505,10 @@ void ssdk_plat_exit(a_uint32_t dev_id); - - #endif - /*qca808x_end*/ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,3,0)) -+#define MII_ADDR_C45 (1<<30) -+#define MII_DEVADDR_C45_SHIFT 16 -+#define MII_DEVADDR_C45_MASK GENMASK(20, 16) -+#define MII_REGADDR_C45_MASK GENMASK(15, 0) -+#endif ---- a/src/init/ssdk_plat.c -+++ b/src/init/ssdk_plat.c -@@ -356,6 +356,18 @@ phy_addr_validation_check(a_uint32_t phy - return A_TRUE; - } - -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,3,0)) -+static inline u16 mdiobus_c45_regad(u32 regnum) -+{ -+ return FIELD_GET(MII_REGADDR_C45_MASK, regnum); -+} -+ -+static inline u16 mdiobus_c45_devad(u32 regnum) -+{ -+ return FIELD_GET(MII_DEVADDR_C45_MASK, regnum); -+} -+#endif -+ - sw_error_t - qca_ar8327_phy_read(a_uint32_t dev_id, a_uint32_t phy_addr, - a_uint32_t reg, a_uint16_t* data) -@@ -371,9 +383,18 @@ qca_ar8327_phy_read(a_uint32_t dev_id, a - if (!bus) - return SW_NOT_SUPPORTED; - phy_addr = TO_PHY_ADDR(phy_addr); -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,3,0)) -+ mutex_lock(&bus->mdio_lock); -+ if (reg & MII_ADDR_C45) -+ *data = __mdiobus_c45_read(bus, phy_addr, mdiobus_c45_devad(reg), mdiobus_c45_regad(reg)); -+ else -+ *data = __mdiobus_read(bus, phy_addr, reg); -+ mutex_unlock(&bus->mdio_lock); -+#else - mutex_lock(&bus->mdio_lock); - *data = __mdiobus_read(bus, phy_addr, reg); - mutex_unlock(&bus->mdio_lock); -+#endif - - return 0; - } -@@ -393,9 +414,18 @@ qca_ar8327_phy_write(a_uint32_t dev_id, - if (!bus) - return SW_NOT_SUPPORTED; - phy_addr = TO_PHY_ADDR(phy_addr); -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,3,0)) -+ mutex_lock(&bus->mdio_lock); -+ if (reg & MII_ADDR_C45) -+ __mdiobus_c45_write(bus, phy_addr, mdiobus_c45_devad(reg), mdiobus_c45_regad(reg), data); -+ else -+ __mdiobus_write(bus, phy_addr, reg, data); -+ mutex_unlock(&bus->mdio_lock); -+#else - mutex_lock(&bus->mdio_lock); - __mdiobus_write(bus, phy_addr, reg, data); - mutex_unlock(&bus->mdio_lock); -+#endif - - return 0; - } diff --git a/package/kernel/qca-ssdk/patches/200-allow-parallel-build.patch b/package/kernel/qca-ssdk/patches/200-allow-parallel-build.patch index 5635c2fdcfb307..6c28e0ff2ebd68 100644 --- a/package/kernel/qca-ssdk/patches/200-allow-parallel-build.patch +++ b/package/kernel/qca-ssdk/patches/200-allow-parallel-build.patch @@ -40,7 +40,7 @@ kslib_c: --- a/make/linux_opt.mk +++ b/make/linux_opt.mk -@@ -777,6 +777,6 @@ LOCAL_CFLAGS += $(CPU_CFLAG) -D"KBUILD_M +@@ -778,6 +778,6 @@ LOCAL_CFLAGS += $(CPU_CFLAG) -D"KBUILD_M #################################################################### # cflags for LNX Modules-Style Makefile #################################################################### diff --git a/package/kernel/qca-ssdk/patches/201-fix-compile-warnings.patch b/package/kernel/qca-ssdk/patches/201-fix-compile-warnings.patch new file mode 100644 index 00000000000000..5b57f41975bbca --- /dev/null +++ b/package/kernel/qca-ssdk/patches/201-fix-compile-warnings.patch @@ -0,0 +1,31 @@ +--- a/src/fal/fal_port_ctrl.c ++++ b/src/fal/fal_port_ctrl.c +@@ -2089,7 +2089,7 @@ fal_port_hibernate_get (a_uint32_t dev_i + */ + sw_error_t + fal_port_cdt (a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, +- a_uint32_t * cable_status, a_uint32_t * cable_len) ++ fal_cable_status_t * cable_status, a_uint32_t * cable_len) + { + sw_error_t rv; + +--- a/src/fal/fal_portvlan.c ++++ b/src/fal/fal_portvlan.c +@@ -2173,7 +2173,7 @@ fal_netisolate_get(a_uint32_t dev_id, a_ + * @return SW_OK or error code + */ + sw_error_t +-fal_eg_trans_filter_bypass_en_set(a_uint32_t dev_id, a_bool_t enable) ++fal_eg_trans_filter_bypass_en_set(a_uint32_t dev_id, a_uint32_t enable) + { + sw_error_t rv; + +@@ -2190,7 +2190,7 @@ fal_eg_trans_filter_bypass_en_set(a_uint + * @return SW_OK or error code + */ + sw_error_t +-fal_eg_trans_filter_bypass_en_get(a_uint32_t dev_id, a_bool_t* enable) ++fal_eg_trans_filter_bypass_en_get(a_uint32_t dev_id, a_uint32_t* enable) + { + sw_error_t rv; +